Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <tuple>
- #include <iostream>
- #include <string>
- #include <array>
- template <typename T, size_t N, size_t... Idx>
- constexpr std::array<T, N> to_array_detail(T* data, std::index_sequence<Idx...>)
- {
- return std::array<T, N>{data[Idx]...};
- }
- template <typename T, size_t N>
- constexpr std::array<T, N> to_array(T* data)
- {
- std::make_index_sequence<N> indices;
- return to_array_detail<T, N>(data, indices);
- }
- template <typename... Tuples>
- constexpr size_t total_length()
- {
- return (std::tuple_size<std::decay_t<Tuples>>::value + ...); // neat new "fold expressions" (N4295) available from clang trunk + std=c++1z
- }
- template <typename... Tuples>
- constexpr auto inner_outer()
- {
- constexpr size_t nbEl = total_length<Tuples...>();
- constexpr size_t nbTup = sizeof...(Tuples);
- size_t tupSizes[nbTup] = {std::tuple_size<std::decay_t<Tuples>>::value...};
- size_t inner[nbEl] = {0};
- size_t outer[nbEl] = {0};
- int index = 0;
- for(int i = 0 ; i < nbTup; i++)
- {
- for(int j = 0; j < tupSizes[i]; j++, index++)
- {
- inner[index] = i;
- outer[index] = j;
- }
- }
- // annoying workaround for the lack of constexpr std::array operator[].
- // We are forced to work with plain C array before converting them to std::array
- std::array<size_t, nbEl> in = to_array<size_t, nbEl>(inner);
- std::array<size_t, nbEl> out = to_array<size_t, nbEl>(outer);
- return std::make_pair(in, out);
- }
- template <size_t... inner, size_t... outer, typename Tuples>
- auto tuple_cat_detail2(std::index_sequence<inner...>, std::index_sequence<outer...>, Tuples ts)
- {
- return std::make_tuple(std::get<outer>(std::get<inner>(ts))...);
- }
- template <typename... Tuples, size_t... Idx>
- auto tuple_cat_detail(std::index_sequence<Idx...>, Tuples&&... ts)
- {
- constexpr auto in_out = inner_outer<Tuples...>(); // pair of inner and outer array of indices
- return tuple_cat_detail2(std::index_sequence<in_out.first[Idx]...>(),
- std::index_sequence<in_out.second[Idx]...>(),
- std::forward_as_tuple(std::forward<Tuples>(ts)...));
- }
- template <typename... Tuples>
- auto my_tuple_cat(Tuples&&... ts)
- {
- constexpr size_t totalLength = total_length<Tuples...>();
- return tuple_cat_detail(std::make_index_sequence<totalLength>(), std::forward<Tuples>(ts)...);
- }
- int main()
- {
- std::array<int, 5> ta;
- ta[0] = 1;
- using T1 = std::tuple<int, short, long>; T1 t1{0, 1, 2};
- using T2 = std::tuple<>; T2 t2;
- using T3 = std::tuple<float, double, long double>; T3 t3{3.0, 4.0, 5.0};
- using T4 = std::tuple<void*, const char*>; T4 t4{nullptr, "hello world"};
- std::tuple<int, short, long, float, double, long double, void*, const char*> t = my_tuple_cat(t1, t2, t3, t4);
- std::cout << std::get<0>(t) << "\n";
- std::cout << std::get<1>(t) << "\n";
- std::cout << std::get<2>(t) << "\n";
- std::cout << std::get<3>(t) << "\n";
- std::cout << std::get<4>(t) << "\n";
- std::cout << std::get<5>(t) << "\n";
- std::cout << std::get<6>(t) << "\n";
- std::cout << std::get<7>(t) << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement