Guest User

tuple_cat constepxr style

a guest
Nov 16th, 2014
365
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <tuple>
  2. #include <iostream>
  3. #include <string>
  4. #include <array>
  5.  
  6.  
  7. template <typename T, size_t N, size_t... Idx>
  8. constexpr std::array<T, N> to_array_detail(T* data, std::index_sequence<Idx...>)
  9. {
  10.    return std::array<T, N>{data[Idx]...};
  11. }
  12.  
  13. template <typename T, size_t N>
  14. constexpr std::array<T, N> to_array(T* data)
  15. {
  16.    std::make_index_sequence<N> indices;
  17.    return to_array_detail<T, N>(data, indices);
  18. }
  19.  
  20. template <typename... Tuples>
  21. constexpr size_t total_length()
  22. {
  23.    return (std::tuple_size<std::decay_t<Tuples>>::value + ...); // neat new "fold expressions" (N4295) available from clang trunk + std=c++1z
  24. }
  25.  
  26.  
  27. template <typename... Tuples>
  28. constexpr auto inner_outer()
  29. {
  30.     constexpr size_t nbEl = total_length<Tuples...>();
  31.     constexpr size_t nbTup = sizeof...(Tuples);
  32.     size_t tupSizes[nbTup] = {std::tuple_size<std::decay_t<Tuples>>::value...};
  33.     size_t inner[nbEl] = {0};
  34.     size_t outer[nbEl] = {0};
  35.  
  36.     int index = 0;
  37.     for(int i = 0 ; i < nbTup; i++)
  38.     {
  39.        for(int j = 0; j < tupSizes[i]; j++, index++)
  40.        {
  41.           inner[index] = i;
  42.           outer[index] = j;
  43.        }
  44.     }
  45.  
  46.     // annoying workaround for the lack of constexpr std::array operator[].
  47.     // We are forced to work with plain C array before converting them to std::array
  48.     std::array<size_t, nbEl> in = to_array<size_t, nbEl>(inner);
  49.     std::array<size_t, nbEl> out = to_array<size_t, nbEl>(outer);
  50.  
  51.     return std::make_pair(in, out);
  52. }
  53.  
  54. template <size_t... inner, size_t... outer, typename Tuples>
  55. auto tuple_cat_detail2(std::index_sequence<inner...>, std::index_sequence<outer...>, Tuples ts)
  56. {
  57.    return std::make_tuple(std::get<outer>(std::get<inner>(ts))...);
  58. }
  59.  
  60. template <typename... Tuples, size_t... Idx>
  61. auto tuple_cat_detail(std::index_sequence<Idx...>, Tuples&&... ts)
  62. {
  63.    constexpr auto in_out = inner_outer<Tuples...>(); // pair of inner and outer array of indices
  64.    return tuple_cat_detail2(std::index_sequence<in_out.first[Idx]...>(),
  65.                             std::index_sequence<in_out.second[Idx]...>(),
  66.                             std::forward_as_tuple(std::forward<Tuples>(ts)...));
  67. }
  68.  
  69. template <typename... Tuples>
  70. auto my_tuple_cat(Tuples&&... ts)
  71. {
  72.  
  73.    constexpr size_t totalLength = total_length<Tuples...>();
  74.    return tuple_cat_detail(std::make_index_sequence<totalLength>(), std::forward<Tuples>(ts)...);
  75. }
  76.  
  77. int main()
  78. {
  79.   std::array<int, 5> ta;
  80.   ta[0] = 1;
  81.   using T1 = std::tuple<int, short, long>; T1 t1{0, 1, 2};
  82.   using T2 = std::tuple<>; T2 t2;
  83.   using T3 = std::tuple<float, double, long double>; T3 t3{3.0, 4.0, 5.0};
  84.   using T4 = std::tuple<void*, const char*>; T4 t4{nullptr, "hello world"};
  85.  
  86.   std::tuple<int, short, long, float, double, long double, void*, const char*> t = my_tuple_cat(t1, t2, t3, t4);
  87.   std::cout << std::get<0>(t) << "\n";
  88.   std::cout << std::get<1>(t) << "\n";
  89.   std::cout << std::get<2>(t) << "\n";
  90.   std::cout << std::get<3>(t) << "\n";
  91.   std::cout << std::get<4>(t) << "\n";
  92.   std::cout << std::get<5>(t) << "\n";
  93.   std::cout << std::get<6>(t) << "\n";
  94.   std::cout << std::get<7>(t) << "\n";
  95. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×