fork download
  1. #include <iostream>
  2.  
  3. template <unsigned N>
  4. class element {
  5. public:
  6. const static unsigned value = N;
  7. };
  8.  
  9. template <typename ...Elems>
  10. class set{};
  11.  
  12. template <typename ...Elems>
  13. void print(set<Elems...> t) {
  14. std::cout << "{";
  15. t.print();
  16. std::cout << "}";
  17. }
  18.  
  19. template <typename Elem, typename ...Elems>
  20. class set<Elem, Elems...> {
  21. public:
  22. static void print()
  23. {
  24. ::print(Elem());
  25. std::cout << ", ";
  26. set<Elems...>::print();
  27. }
  28. };
  29.  
  30. template <typename Elem>
  31. class set<Elem> {
  32. public:
  33. static void print()
  34. {
  35. ::print(Elem());
  36. }
  37. };
  38.  
  39. template <unsigned N, typename ...Elems>
  40. class set<element<N>, Elems...> {
  41. public:
  42. static void print()
  43. {
  44. std::cout << N << ", ";
  45. set<Elems...>::print();
  46. }
  47. };
  48.  
  49. template <unsigned N>
  50. class set<element<N>> {
  51. public:
  52. static void print()
  53. {
  54. std::cout << N;
  55. }
  56. };
  57.  
  58. template <>
  59. class set<> {
  60. public:
  61. static void print(){}
  62. };
  63.  
  64. template <typename T, typename U>
  65. class join;
  66.  
  67. template <typename ...Elems>
  68. class join<set<>, set<Elems...>> {
  69. public:
  70. typedef set<Elems...> type;
  71. };
  72.  
  73. template <typename Elem1, typename ...Elems, typename ...Elems2>
  74. class join<set<Elem1, Elems...>, set<Elems2...>> {
  75. public:
  76. typedef typename join<set<Elems...>, set<Elem1, Elems2...>>::type type;
  77. };
  78.  
  79.  
  80. template <typename T, typename U>
  81. class all_subsets_worker;
  82.  
  83. template <typename Rest>
  84. class all_subsets_worker<set<>, Rest>
  85. {
  86. public:
  87. typedef set<Rest> type;
  88. };
  89.  
  90. template <typename Elem, typename Rest, typename ...Elems>
  91. class all_subsets_worker<set<Elem, Elems...>, Rest>
  92. {
  93. public:
  94. typedef typename join<
  95. typename all_subsets_worker<set<Elems...>, Rest>::type,
  96. typename all_subsets_worker<set<Elems...>, typename join< set<Elem>, Rest>::type >::type
  97. >::type type;
  98. };
  99.  
  100. template <typename T>
  101. class all_subsets;
  102.  
  103. template <typename Elem, typename ...Elems>
  104. class all_subsets<set<Elem, Elems...>> {
  105. public:
  106. typedef typename all_subsets_worker<set<Elem, Elems...>, set<>>::type type;
  107. };
  108.  
  109.  
  110.  
  111. int main(int argc, const char * argv[])
  112. {
  113. auto t = all_subsets<set<element<0>, element<1>, element<2>, element<3>>>::type();
  114.  
  115. print(t);
  116.  
  117. std::cout << "\n";
  118. return 0;
  119. }
Success #stdin #stdout 0s 2888KB
stdin
Standard input is empty
stdout
{{3, 2, 1}, {2, 1}, {1}, {3, 1}, {3}, {}, {2}, {3, 2}, {3, 2, 0}, {2, 0}, {0}, {3, 0}, {3, 1, 0}, {1, 0}, {2, 1, 0}, {3, 2, 1, 0}}