fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template <bool b, typename T, typename U>
  5. class Select;
  6.  
  7. template <typename T, typename U>
  8. class Select<true, T, U>
  9. {
  10. public:
  11. using type = T;
  12. };
  13.  
  14. template <typename T, typename U>
  15. class Select<false, T, U>
  16. {
  17. public:
  18. using type = U;
  19. };
  20.  
  21.  
  22. template <typename Type>
  23. class EmptyList
  24. {
  25. public:
  26. using type = Type;
  27. };
  28.  
  29. template <typename Type, Type Value>
  30. class ValueWrapper
  31. {
  32. public:
  33. using type = Type;
  34. static constexpr Type value = Value;
  35. };
  36.  
  37. template <typename Left, typename Right>
  38. class Pair
  39. {
  40. public:
  41. using first = Left;
  42. using rest = Right;
  43. };
  44.  
  45. template <typename Type, Type First, Type ... Rest>
  46. class Make_List
  47. {
  48. public:
  49. using result = Pair<ValueWrapper<Type, First>,
  50. typename Make_List<Type, Rest...>::result>;
  51. };
  52.  
  53. template <typename Type, Type Last>
  54. class Make_List<Type, Last>
  55. {
  56. public:
  57. using result = Pair<ValueWrapper<Type, Last>, EmptyList<Type>>;
  58. };
  59.  
  60. template <typename T, T val>
  61. class DivBy5
  62. {
  63. public:
  64. static constexpr bool value = val % 5 == 0;
  65. };
  66.  
  67. template <typename List, template <typename T, T v> class Pred>
  68. class Filter;
  69.  
  70. template <typename Type, template <typename T, T v> class Pred>
  71. class Filter<EmptyList<Type>, Pred>
  72. {
  73. public:
  74. using result = EmptyList<Type>;
  75. };
  76.  
  77. template <typename First, typename Rest, template <typename T, T v> class Pred>
  78. class Filter<Pair<First, Rest>, Pred>
  79. {
  80. public:
  81. using result = typename Select<Pred<typename First::type, First::value>::value,
  82. Pair<First, typename Filter<Rest, Pred>::result>,
  83. typename Filter<Rest, Pred>::result>::type;
  84. };
  85.  
  86. template <typename Type>
  87. void PrintList(EmptyList<Type>)
  88. {
  89. }
  90.  
  91. template <typename First, typename Rest>
  92. void PrintList(Pair<First, Rest>)
  93. {
  94. cout << First::value << endl;
  95. PrintList(Rest());
  96. }
  97.  
  98. int main()
  99. {
  100. using original = Make_List<int, 1, 2, 3, 10, 15, 20, 25, 123, 15>::result;
  101. using filtered = Filter<original, DivBy5>::result;
  102. PrintList(original());
  103. cout << endl;
  104. PrintList(filtered());
  105. }
  106.  
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
1
2
3
10
15
20
25
123
15

10
15
20
25
15