fork(1) download
  1. #include <iostream>
  2.  
  3. using value_t = unsigned long long int;
  4.  
  5. namespace peano
  6. {
  7.  
  8. struct zero {
  9. static constexpr value_t value = 0;
  10.  
  11. using type = zero;
  12. };
  13.  
  14. template <typename T>
  15. struct succ {
  16. static constexpr value_t value = 1 + T::value;
  17.  
  18. using pred = typename T::type;
  19.  
  20. using type = succ<typename T::type>;
  21. };
  22.  
  23. template <typename S, typename T>
  24. struct add: succ<typename add<S, typename T::pred>::type>::type {};
  25.  
  26. template <typename S>
  27. struct add<S, zero>: S::type {};
  28.  
  29. template <typename S, typename T>
  30. struct mul: add<typename mul<S, typename T::pred>::type, S>::type {};
  31.  
  32. template <typename S>
  33. struct mul<S, zero>: zero {};
  34.  
  35. template <typename S>
  36. struct factorial: mul<S, typename factorial<typename S::pred>::type>::type {};
  37.  
  38. template <>
  39. struct factorial<zero>: succ<zero>::type {};
  40.  
  41. // constants
  42. using _0 = zero;
  43. using _1 = succ<_0>::type;
  44. using _2 = succ<_1>::type;
  45. using _3 = succ<_2>::type;
  46. using _4 = succ<_3>::type;
  47. using _5 = succ<_4>::type;
  48. using _6 = succ<_5>::type;
  49. using _7 = succ<_6>::type;
  50. using _8 = succ<_7>::type;
  51. using _9 = succ<_8>::type;
  52.  
  53. } // namespace peano
  54.  
  55. int main() {
  56. // 9 + 9 == 18
  57. std::cout
  58. << peano::add<peano::_9, peano::_9>::value
  59. << std::endl;
  60.  
  61. // 5 * 7 == 35
  62. std::cout
  63. << peano::mul<peano::_5, peano::_7>::value
  64. << std::endl;
  65.  
  66. // let's try a more complex expression
  67. // 2 * 7 + 3 * (4 + 5) == 41
  68. std::cout <<
  69. peano::add<
  70. peano::mul<peano::_2, peano::_7>,
  71. peano::mul<
  72. peano::_3,
  73. peano::add<peano::_4, peano::_5>
  74. >
  75. >::value
  76. << std::endl;
  77.  
  78. // and now factorial: 5! == 120
  79. std::cout
  80. << peano::factorial<peano::_5>::value
  81. << std::endl;
  82.  
  83. return 0;
  84. }
  85.  
Success #stdin #stdout 0.01s 5304KB
stdin
Standard input is empty
stdout
18
35
41
120