Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Competency test question 1
- /* Define a user defined literal assignable to float that fails compilation when the value provided cannot be expressed as an positive integer power of 0.5 (e.g. 0.5, 0.25, 0.125). */
- // Implements a compile time float data type
- // Aborts compilation by recursion depth overflow
- //
- // Dive<i,F> checks all the powers of 0.5 from i to infinite
- // If any of them matches F, it returns F::value
- //
- #include <iostream>
- #define BASE 10.0
- #include <limits>
- using namespace std;
- using ft = double;
- template<int n>
- struct PowHalf {
- constexpr static ft value = 0.5*PowHalf<n-1>::value;
- };
- template<>
- struct PowHalf<1> {
- constexpr static ft value = 0.5;
- };
- template<class F>
- struct Return {
- constexpr static ft value = F::value;
- };
- template<int n, class F>
- struct Dive {
- constexpr static ft nthPowOfHalf = PowHalf<n>::value;
- constexpr static ft value = conditional_t<F::value == nthPowOfHalf, Return<F>, Dive<n+1,F>>::value;
- };
- template<char c>
- struct Abort {
- constexpr static int value = Abort<c+1>::value;
- };
- template<char c>
- struct DontAbort {
- constexpr static int value = c-'0';
- };
- template<char c>
- struct NumVal {
- constexpr static int value = conditional_t<((c >= '0') && (c <= '9')), DontAbort<c>, Abort<c>>::value;
- };
- template<char F, char... R>
- struct GetVal {
- constexpr static ft value() {
- if constexpr(sizeof...(R) == 0) {
- return NumVal<F>::value;
- } else {
- return (NumVal<F>::value+GetVal<R...>::value()/10.0);
- }
- }
- };
- template<char F, char S, char... R>
- struct Float {
- static_assert(F == '0' && S == '.');
- constexpr static ft value = GetVal<R...>::value()/10.0;
- };
- template<char... C>
- constexpr ft operator"" _pref() {
- return Dive<1,Float<C...>>::value;
- }
- ft operator"" _pref(const char *v, size_t n) {
- if ((n == 3) && (v[0] == 'i') && (v[1] == 'n') && (v[2] =='f')) {
- return numeric_limits<ft>::infinity();
- }
- return numeric_limits<ft>::quiet_NaN();
- }
- int main( int argc, const char *argv[] ) {
- 0.5_pref;
- 0.25_pref;
- 0.125_pref;
- 0.0625_pref;
- 0.03125_pref;
- 0.015625_pref;
- 0.0078125_pref;
- 0.00390625_pref;
- 0.001953125_pref;
- 0.0009765625_pref;
- 0.00048828125_pref;
- 0.000244140625_pref;
- 0.0001220703125_pref;
- // 0.000122070312_pref; // compilation will fail if this is uncommented
- ft inf = "inf"_pref;
- ft nan = "me"_pref;
- cout << inf << endl;
- cout << nan << endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment