fork(1) download
  1. #include <ratio>
  2.  
  3. template <char... Ts>
  4. struct seq;
  5.  
  6. template <class Seq>
  7. struct parse_sign
  8. {
  9. static constexpr auto sign = intmax_t{1};
  10. using tail = Seq;
  11. };
  12.  
  13. template <char... Ts>
  14. struct parse_sign<seq<'+', Ts...>>
  15. {
  16. static constexpr auto sign = intmax_t{1};
  17. using tail = seq<Ts...>;
  18. };
  19.  
  20. template <char... Ts>
  21. struct parse_sign<seq<'-', Ts...>>
  22. {
  23. static constexpr auto sign = intmax_t{-1};
  24. using tail = seq<Ts...>;
  25. };
  26.  
  27. template <bool BeforePoint, intmax_t Num, intmax_t Den, class Seq>
  28. struct parse_frac;
  29.  
  30. template <bool BeforePoint, intmax_t Num, intmax_t Den>
  31. struct parse_frac<BeforePoint, Num, Den, seq<>>
  32. {
  33. static constexpr auto num = Num;
  34. static constexpr auto den = Den;
  35. };
  36.  
  37. template <intmax_t Num, intmax_t Den, char... Ts>
  38. struct parse_frac<true, Num, Den, seq<'.', Ts...>>
  39. {
  40. using next = parse_frac<false, Num, Den, seq<Ts...>>;
  41. static constexpr auto num = next::num;
  42. static constexpr auto den = next::den;
  43. };
  44.  
  45. template <intmax_t Num, intmax_t Den, char T, char... Ts>
  46. struct parse_frac<true, Num, Den, seq<T, Ts...>>
  47. {
  48. static_assert(
  49. T >= '0' && T <= '9',
  50. "Expected digit."
  51. );
  52.  
  53. using next = parse_frac<true, 10 * Num + (T - '0'), Den, seq<Ts...>>;
  54. static constexpr auto num = next::num;
  55. static constexpr auto den = next::den;
  56. };
  57.  
  58. template <intmax_t Num, intmax_t Den, char T, char... Ts>
  59. struct parse_frac<false, Num, Den, seq<T, Ts...>>
  60. {
  61. static_assert(
  62. T >= '0' && T <= '9',
  63. "Expected digit."
  64. );
  65.  
  66. using next = parse_frac<false, 10 * Num + (T - '0'), 10 * Den, seq<Ts...>>;
  67. static constexpr auto num = next::num;
  68. static constexpr auto den = next::den;
  69. };
  70.  
  71. template <class Char, Char... Ts>
  72. constexpr auto operator"" _f()
  73. {
  74. using sign_parser = parse_sign<seq<Ts...>>;
  75. using tail = typename sign_parser::tail;
  76. using frac_parser = parse_frac<true, 0, 1, tail>;
  77.  
  78. return std::ratio<
  79. sign_parser::sign * frac_parser::num,
  80. frac_parser::den
  81. >{};
  82. }
  83.  
  84. #define cc_fixed(x) decltype(#x ## _f)
  85.  
  86. int main()
  87. {
  88. using x = cc_fixed(123.456);
  89. using y = cc_fixed(+123.456);
  90. using z = cc_fixed(-123.456);
  91. }
Success #stdin #stdout 0s 3136KB
stdin
Standard input is empty
stdout
Standard output is empty