fork(1) download
  1. // http://w...content-available-to-author-only...t.org/doc/libs/1_66_0_beta1/libs/mp11/doc/html/simple_cxx11_metaprogramming.html
  2. #include <tuple>
  3. #include <type_traits>
  4.  
  5. // Tuple concatenation:
  6. // tuple<a...>, tuple<b...>, ... -> tuple<a..., b..., ...>
  7.  
  8. template <class A, class B>
  9. struct Tcat;
  10.  
  11. template <class... T, class... S>
  12. struct Tcat<std::tuple<T...>, std::tuple<S...>>
  13. {
  14. using type = std::tuple<T..., S...>;
  15. };
  16.  
  17. template <class A, class B>
  18. using tcat = typename Tcat<A, B>::type;
  19.  
  20.  
  21. template <class... A> struct Tcats;
  22.  
  23. template <class... T>
  24. struct Tcats<std::tuple<T...>>
  25. {
  26. using type = std::tuple<T...>;
  27. };
  28.  
  29. template <class A, class B, class... Other>
  30. struct Tcats<A, B, Other...>
  31. {
  32. using type = typename Tcats<tcat<A, B>, Other...>::type;
  33. };
  34.  
  35. template <class... T>
  36. using tcats = typename Tcats<T...>::type;
  37.  
  38.  
  39. // Transpose (generic "zip"):
  40. // F, tuple<tuple<a,b,c>, tuple<d,e,f>> ->
  41. // tuple<F<a,d>, F<b,e>, F<c,f>>
  42. // -- any number of tuples -- arguments of F.
  43. // where F is any template<class...> class.
  44.  
  45. // Select the column I from the T... matrix.
  46. template <class I,
  47. template <class...> class F, class... T>
  48. struct Tcol
  49. {
  50. using type = F<std::tuple_element_t<I::value, T>...>;
  51. };
  52.  
  53. template <class I,
  54. template <class...> class F, class... T>
  55. using tcol = typename Tcol<I, F, T...>::type;
  56.  
  57. // Make range S, S+1, S+2, ..., T-1
  58. // as a tuple of integer_constant.
  59. template <class S, class T,
  60. template <class...> class F, class... Other>
  61. struct Tfor;
  62.  
  63. template <class Int, Int s,
  64. template <class...> class F, class... Other>
  65. struct Tfor<
  66. std::integral_constant<Int, s>,
  67. std::integral_constant<Int, s>,
  68. F, Other...>
  69. {
  70. using type = std::tuple<>;
  71. };
  72.  
  73. template <class Int, Int s, Int t,
  74. template <class...> class F, class... Other>
  75. struct Tfor<
  76. std::integral_constant<Int, s>,
  77. std::integral_constant<Int, t>,
  78. F, Other...>
  79. {
  80. static_assert(s < t, "");
  81. using S = std::integral_constant<Int, s>;
  82. using S1 = std::integral_constant<Int, s+1>;
  83. using T = std::integral_constant<Int, t>;
  84.  
  85. using type = tcat<std::tuple<F<S, Other...>>,
  86. typename Tfor<S1, T, F, Other...>::type>;
  87. };
  88.  
  89. template <class S, class T,
  90. template <class...> class F, class... Other>
  91. using tfor = typename Tfor<S, T, F, Other...>::type;
  92.  
  93. template <
  94. template <class...> class F,
  95. class... T>
  96. struct Tzip;
  97.  
  98. template <
  99. template <class...> class F>
  100. struct Tzip<F> { using type = std::tuple<>; };
  101.  
  102. template <
  103. template <class...> class F,
  104. class T0, class... T>
  105. struct Tzip<F, T0, T...>
  106. {
  107. template <class I, class... Y>
  108. using tcolF = tcol<I, F, Y...>;
  109. using type = tfor<
  110. std::integral_constant<std::size_t, 0>,
  111. std::integral_constant<std::size_t, std::tuple_size<T0>::value>,
  112. tcolF, T0, T...>;
  113. };
  114.  
  115. template <
  116. template <class...> class F,
  117. class... T>
  118. using tzip = typename Tzip<F, T...>::type;
  119.  
  120.  
  121. //////////////////////////////////////////////////
  122. // Testing
  123.  
  124. template <class... T>
  125. struct Tmax;
  126.  
  127. template <class T>
  128. struct Tmax<T> { using type = T; };
  129.  
  130. template <class T0, class... T>
  131. struct Tmax<T0, T...>
  132. {
  133. using tail_max = typename Tmax<T...>::type;
  134. using type = std::conditional_t<
  135. (T0::value < tail_max::value), tail_max, T0>;
  136. };
  137.  
  138. template <class... T>
  139. using tmax = typename Tmax<T...>::type;
  140.  
  141. template <class T>
  142. using Sizeof = std::integral_constant<std::size_t, sizeof(T)>;
  143.  
  144. template <class... T>
  145. using tmax_sizeof = tmax<Sizeof<T>...>;
  146.  
  147. int main()
  148. {
  149. using namespace std;
  150. // Concat.
  151. {
  152. using t0 = tuple<int, int*>;
  153. using t1 = tuple<float>;
  154. using t2 = tuple<char*, char**, void*, void**>;
  155. using t3 = tuple<>;
  156. using ex = tuple<int, int*, float, char*, char**, void*, void**>;
  157. static_assert(is_same<tcats<t0, t1, t2, t3>, ex>::value, "");
  158. }
  159.  
  160. // Generic zip.
  161. {
  162. using r0 = tuple<char, short, int, long>;
  163. using r1 = tuple<unsigned, void*, void**, void***>;
  164. using exr = tuple<
  165. tuple<char, unsigned>,
  166. tuple<short, void*>,
  167. tuple<int, void**>,
  168. tuple<long, void***>>;
  169. //print_t(tzip<tuple, r0, r1>{});
  170. static_assert(is_same<exr, tzip<tuple, r0, r1>>::value, "");
  171.  
  172. using t0 = tuple<int[11], int[12], int[13]>;
  173. using t1 = tuple<int[21], int[22], int[23]>;
  174. using t2 = tuple<int[31], int[32], int[33]>;
  175. using t3 = tuple<int[41], int[42], int[43]>;
  176. using ext = tuple<
  177. tuple<int[11], int[21], int[31], int[41]>,
  178. tuple<int[12], int[22], int[32], int[42]>,
  179. tuple<int[13], int[23], int[33], int[43]>>;
  180. static_assert(is_same<ext, tzip<tuple, t0, t1, t2, t3>>::value, "");
  181.  
  182. using exsz = tuple<
  183. Sizeof<int[41]>, Sizeof<int[42]>, Sizeof<int[43]>>;
  184. static_assert(is_same<exsz, tzip<tmax_sizeof, t0, t1, t2, t3>>::value, "");
  185. }
  186.  
  187. return 0;
  188. }
  189.  
Success #stdin #stdout 0s 16048KB
stdin
Standard input is empty
stdout
Standard output is empty