Sagar2018

q1.cpp

Mar 20th, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.55 KB | None | 0 0
  1. // Competency test question 1
  2. /* 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). */
  3. // Implements a compile time float data type
  4. // Aborts compilation by recursion depth overflow
  5. //
  6. // Dive<i,F> checks all the powers of 0.5 from i to infinite
  7. // If any of them matches F, it returns F::value
  8. //
  9. #include <iostream>
  10. #define BASE 10.0
  11. #include <limits>
  12.  
  13. using namespace std;
  14. using ft = double;
  15.  
  16. template<int n>
  17. struct PowHalf {
  18.     constexpr static ft value = 0.5*PowHalf<n-1>::value;
  19. };
  20.  
  21. template<>
  22. struct PowHalf<1> {
  23.     constexpr static ft value = 0.5;
  24. };
  25.  
  26. template<class F>
  27. struct Return {
  28.     constexpr static ft value = F::value;
  29. };
  30.  
  31. template<int n, class F>
  32. struct Dive {
  33.     constexpr static ft nthPowOfHalf = PowHalf<n>::value;
  34.     constexpr static ft value = conditional_t<F::value == nthPowOfHalf, Return<F>, Dive<n+1,F>>::value;
  35. };
  36.  
  37. template<char c>
  38. struct Abort {
  39.     constexpr static int value = Abort<c+1>::value;
  40. };
  41.  
  42. template<char c>
  43. struct DontAbort {
  44.     constexpr static int value = c-'0';
  45. };
  46.  
  47. template<char c>
  48. struct NumVal {
  49.     constexpr static int value = conditional_t<((c >= '0') && (c <= '9')), DontAbort<c>, Abort<c>>::value;
  50. };
  51.  
  52. template<char F, char... R>
  53. struct GetVal {
  54.     constexpr static ft value() {
  55.         if constexpr(sizeof...(R) == 0) {
  56.             return NumVal<F>::value;
  57.         } else {
  58.             return (NumVal<F>::value+GetVal<R...>::value()/10.0);
  59.         }
  60.     }
  61. };
  62.  
  63. template<char F, char S, char... R>
  64. struct Float {
  65.     static_assert(F == '0' && S == '.');
  66.     constexpr static ft value = GetVal<R...>::value()/10.0;
  67. };
  68.  
  69. template<char... C>
  70. constexpr ft operator"" _pref() {
  71.     return Dive<1,Float<C...>>::value;
  72. }
  73.  
  74. ft operator"" _pref(const char *v, size_t n) {
  75.     if ((n == 3) && (v[0] == 'i') && (v[1] == 'n') && (v[2] =='f')) {
  76.         return numeric_limits<ft>::infinity();
  77.     }
  78.     return numeric_limits<ft>::quiet_NaN();
  79. }
  80.  
  81. int main( int argc, const char *argv[] ) {
  82.     0.5_pref;
  83.     0.25_pref;
  84.     0.125_pref;
  85.     0.0625_pref;
  86.     0.03125_pref;
  87.     0.015625_pref;
  88.     0.0078125_pref;
  89.     0.00390625_pref;
  90.     0.001953125_pref;
  91.     0.0009765625_pref;
  92.     0.00048828125_pref;
  93.     0.000244140625_pref;
  94.     0.0001220703125_pref;
  95. //  0.000122070312_pref; // compilation will fail if this is uncommented
  96.     ft inf = "inf"_pref;
  97.     ft nan = "me"_pref;
  98.     cout << inf << endl;
  99.     cout << nan << endl;
  100.     return 0;
  101. }
Add Comment
Please, Sign In to add comment