fork download
  1. #include <iostream>
  2. #include <utility>
  3. #include <type_traits>
  4.  
  5. enum class values {
  6. zero = 7,
  7. one = 3,
  8. two = 1,
  9. three = -7,
  10. four = 2,
  11. five = 4,
  12. };
  13.  
  14. template<class T, T... ts> struct list {typedef list type;};
  15. template<unsigned max, unsigned... ts> struct make_indexes:make_indexes<max-1, max-1, ts...>{};
  16. template<unsigned... ts> struct make_indexes<0, ts...>:list<unsigned, ts...> {};
  17. template<unsigned max> using make_indexes_t=typename make_indexes<max>::type;
  18.  
  19. template<class list> struct length_of;
  20. template<class T, T... ts> struct length_of<list<T, ts...>>:std::integral_constant<unsigned, sizeof...(ts)> {};
  21.  
  22. template<class T, T t, class list> struct index_of;
  23. template<class T, T t, T t0, T...ts> struct index_of<T, t, list<T, t0, ts...>>:
  24. std::integral_constant< unsigned, index_of<T, t, list<T, ts...>>::value+1 >
  25. {};
  26. template<class T, T t, T...ts> struct index_of<T, t, list<T, t, ts...>>:
  27. std::integral_constant< unsigned, 1 >
  28. {};
  29. template<class T, unsigned N, class list> struct value_at;
  30. template<class T, unsigned N, T t0, T... ts> struct value_at<T, N, list<T, t0, ts...>>:value_at<T, N-1, list<T, ts...>> {};
  31. template<class T, T t0, T... ts> struct value_at<T, 0, list<T, t0, ts...>>:std::integral_constant<T, t0> {};
  32.  
  33. template<class T> struct summable {};
  34. template<> struct summable<values> {
  35. typedef values T;
  36. typedef list<T, T::zero, T::one, T::two, T::three, T::four, T::five> list_type;
  37. template<T t>
  38. using index = index_of< T, t, list_type >;
  39. template<unsigned N>
  40. using value = value_at< T, N, list_type >;
  41. };
  42.  
  43. template<class T, template<T>class indexer>
  44. unsigned index( T t, list<T> ) {
  45. return -1;
  46. }
  47.  
  48. template<class T, template<T>class indexer, T t0, T... ts>
  49. unsigned index( T t, list<T, t0, ts...> ) {
  50. if (t==t0)
  51. return indexer<t0>::value;
  52. else
  53. return index<T, indexer>( t, list<T, ts...>{} );
  54. }
  55.  
  56. template<class T, template<unsigned>class valuer>
  57. T value( unsigned N, list<unsigned> ) {
  58. return static_cast<T>(-1);
  59. }
  60. template<class T, template<unsigned>class valuer, unsigned M0, unsigned... Ms>
  61. T value( unsigned N, list<unsigned, M0, Ms...> ) {
  62. if (N-1==M0)
  63. return valuer<M0>::value;
  64. else
  65. return value<T, valuer>( N, list<unsigned, Ms...>{} );
  66. }
  67.  
  68.  
  69. template<typename T>
  70. T sum( T lhs, T rhs ) {
  71. typedef typename summable<T>::list_type list_type;
  72. return value<T, summable<T>::template value>( index<T, summable<T>::template index>(lhs, list_type{})+index<values, summable<T>::template index>(rhs, list_type{}), make_indexes_t<length_of<list_type>::value>{} );
  73. }
  74.  
  75. template<typename T, typename=typename summable<T>::list_type >
  76. T operator+( T lhs, T rhs ) {
  77. return sum( lhs, rhs );
  78. }
  79.  
  80. int main() {
  81. auto two = values::two;
  82. auto five = values::five;
  83. std::cout << (two+two==five) << "\n";
  84. return 0;
  85. }
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
1