| 1 | /*
|
|---|
| 2 | * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
|
|---|
| 3 | *
|
|---|
| 4 | * SPDX-License-Identifier: BSD-3-Clause
|
|---|
| 5 | */
|
|---|
| 6 |
|
|---|
| 7 | #ifndef LIBCPP_BITS_TUPLE_TUPLE_CAT
|
|---|
| 8 | #define LIBCPP_BITS_TUPLE_TUPLE_CAT
|
|---|
| 9 |
|
|---|
| 10 | #include <utility>
|
|---|
| 11 |
|
|---|
| 12 | namespace std
|
|---|
| 13 | { // forward declarations
|
|---|
| 14 | template<class... Ts>
|
|---|
| 15 | struct tuple;
|
|---|
| 16 |
|
|---|
| 17 | template<size_t I, class T>
|
|---|
| 18 | struct tuple_element;
|
|---|
| 19 |
|
|---|
| 20 | template<size_t I, class... Ts>
|
|---|
| 21 | constexpr typename tuple_element<I, tuple<Ts...>>::type& get(tuple<Ts...>& tpl) noexcept;
|
|---|
| 22 |
|
|---|
| 23 | template<class T, T...>
|
|---|
| 24 | struct integer_sequence;
|
|---|
| 25 |
|
|---|
| 26 | template<size_t... Is>
|
|---|
| 27 | using index_sequence = integer_sequence<size_t, Is...>;
|
|---|
| 28 | }
|
|---|
| 29 |
|
|---|
| 30 | namespace std::aux
|
|---|
| 31 | {
|
|---|
| 32 | template<class...>
|
|---|
| 33 | struct tuple_append;
|
|---|
| 34 |
|
|---|
| 35 | template<class... Ts, class... Us, class... Vs>
|
|---|
| 36 | struct tuple_append<tuple<Ts...>, tuple<Us...>, Vs...>
|
|---|
| 37 | : type_is<tuple<Ts..., Us...>>
|
|---|
| 38 | { /* DUMMY BODY */ };
|
|---|
| 39 |
|
|---|
| 40 | template<class... Ts>
|
|---|
| 41 | using tuple_append_t = typename tuple_append<Ts...>::type;
|
|---|
| 42 |
|
|---|
| 43 | template<class...>
|
|---|
| 44 | struct remove_first_tuple;
|
|---|
| 45 |
|
|---|
| 46 | template<class... Ts, class... Tuples>
|
|---|
| 47 | struct remove_first_tuple<tuple<Ts...>, Tuples...>
|
|---|
| 48 | : type_is<Tuples...>
|
|---|
| 49 | { /* DUMMY BODY */ };
|
|---|
| 50 |
|
|---|
| 51 | template<class... Ts>
|
|---|
| 52 | using remove_first_tuple_t = typename remove_first_tuple<Ts...>::type;
|
|---|
| 53 |
|
|---|
| 54 | template<class...>
|
|---|
| 55 | struct get_first_tuple;
|
|---|
| 56 |
|
|---|
| 57 | template<class... Ts, class... Tuples>
|
|---|
| 58 | struct get_first_tuple<tuple<Ts...>, Tuples...>
|
|---|
| 59 | : type_is<tuple<Ts...>>
|
|---|
| 60 | { /* DUMMY BODY */ };
|
|---|
| 61 |
|
|---|
| 62 | template<class... Ts>
|
|---|
| 63 | using get_first_tuple_t = typename get_first_tuple<Ts...>::type;
|
|---|
| 64 |
|
|---|
| 65 | template<class...>
|
|---|
| 66 | struct tuple_cat_type_impl;
|
|---|
| 67 |
|
|---|
| 68 | template<class... Ts, class... Tuples>
|
|---|
| 69 | struct tuple_cat_type_impl<tuple<Ts...>, Tuples...>
|
|---|
| 70 | : type_is<
|
|---|
| 71 | typename tuple_cat_type_impl<
|
|---|
| 72 | tuple_append_t<tuple<Ts...>, get_first_tuple_t<Tuples...>>,
|
|---|
| 73 | remove_first_tuple_t<Tuples...>
|
|---|
| 74 | >::type
|
|---|
| 75 | >
|
|---|
| 76 | { /* DUMMY BODY */ };
|
|---|
| 77 |
|
|---|
| 78 | template<class... Ts>
|
|---|
| 79 | using tuple_cat_type_impl_t = typename tuple_cat_type_impl<Ts...>::type;
|
|---|
| 80 |
|
|---|
| 81 | template<class...>
|
|---|
| 82 | struct tuple_cat_type;
|
|---|
| 83 |
|
|---|
| 84 | template<class... Ts, class... Tuples>
|
|---|
| 85 | struct tuple_cat_type<tuple<Ts...>, Tuples...>
|
|---|
| 86 | : type_is<tuple_cat_type_impl_t<tuple<Ts...>, Tuples...>>
|
|---|
| 87 | { /* DUMMY BODY */ };
|
|---|
| 88 |
|
|---|
| 89 | template<class... Ts>
|
|---|
| 90 | using tuple_cat_type_t = typename tuple_cat_type<Ts...>::type;
|
|---|
| 91 |
|
|---|
| 92 | template<class...>
|
|---|
| 93 | struct concatenate_sequences;
|
|---|
| 94 |
|
|---|
| 95 | template<size_t... Is1, size_t... Is2>
|
|---|
| 96 | struct concatenate_sequences<index_sequence<Is1...>, index_sequence<Is2...>>
|
|---|
| 97 | : type_is<index_sequence<Is1..., Is2...>>
|
|---|
| 98 | { /* DUMMY BODY */ };
|
|---|
| 99 |
|
|---|
| 100 | template<class... Ts>
|
|---|
| 101 | using concatenate_sequences_t = typename concatenate_sequences<Ts...>::type;
|
|---|
| 102 |
|
|---|
| 103 | template<class...>
|
|---|
| 104 | struct append_indices;
|
|---|
| 105 |
|
|---|
| 106 | template<size_t... Is, class... Ts, class... Tuples>
|
|---|
| 107 | struct append_indices<index_sequence<Is...>, tuple<Ts...>, Tuples...>
|
|---|
| 108 | : append_indices<
|
|---|
| 109 | concatenate_sequences_t<
|
|---|
| 110 | index_sequence<Is...>, make_index_sequence<sizeof...(Ts)>
|
|---|
| 111 | >,
|
|---|
| 112 | Tuples...
|
|---|
| 113 | >
|
|---|
| 114 | { /* DUMMY BODY */ };
|
|---|
| 115 |
|
|---|
| 116 | template<class... Ts>
|
|---|
| 117 | using append_indices_t = typename append_indices<Ts...>::types;
|
|---|
| 118 |
|
|---|
| 119 | template<class...>
|
|---|
| 120 | struct generate_indices;
|
|---|
| 121 |
|
|---|
| 122 | template<class... Ts, class... Tuples>
|
|---|
| 123 | struct generate_indices<tuple<Ts...>, Tuples...>
|
|---|
| 124 | : type_is<
|
|---|
| 125 | append_indices_t<
|
|---|
| 126 | make_index_sequence<sizeof...(Ts)>,
|
|---|
| 127 | Tuples...
|
|---|
| 128 | >
|
|---|
| 129 | >
|
|---|
| 130 | { /* DUMMY BODY */ };
|
|---|
| 131 |
|
|---|
| 132 | template<class... Ts>
|
|---|
| 133 | using generate_indices_t = typename generate_indices<Ts...>::type;
|
|---|
| 134 |
|
|---|
| 135 | template<class... Tuples, size_t... Is1, size_t... Is2>
|
|---|
| 136 | tuple_cat_type_t<Tuples...> tuple_cat(Tuples&&... tpls,
|
|---|
| 137 | index_sequence<Is1...>,
|
|---|
| 138 | index_sequence<Is2...>)
|
|---|
| 139 | {
|
|---|
| 140 | return tuple_cat_type_t<Tuples...>{
|
|---|
| 141 | get<Is1...>(
|
|---|
| 142 | get<Is2...>(
|
|---|
| 143 | forward<Tuples>(tpls)
|
|---|
| 144 | )
|
|---|
| 145 | )...
|
|---|
| 146 | };
|
|---|
| 147 | }
|
|---|
| 148 | }
|
|---|
| 149 |
|
|---|
| 150 | #endif
|
|---|