Tatooine
variadic_helpers.h
Go to the documentation of this file.
1#ifndef TATOOINE_VARIADIC_HELPERS_H
2#define TATOOINE_VARIADIC_HELPERS_H
3//==============================================================================
4#include <cstdint>
5#include <tatooine/tuple.h>
6#include <tatooine/concepts.h>
8//==============================================================================
10//==============================================================================
11template <std::size_t I, std::size_t... Is>
13 static auto constexpr value = I;
14};
15//------------------------------------------------------------------------------
16template <std::size_t... Is>
17static auto constexpr front_number = front_number_impl<Is...>::value;
18//==============================================================================
19template <std::size_t... I>
21//------------------------------------------------------------------------------
22template <std::size_t I>
24 static auto constexpr value = I;
25};
26//------------------------------------------------------------------------------
27template <std::size_t I, std::size_t... Is>
28struct back_number_impl<I, Is...> {
29 static auto constexpr value = back_number_impl<Is...>::value;
30};
31//------------------------------------------------------------------------------
32template <std::size_t... Is>
33static auto constexpr back_number = back_number_impl<Is...>::value;
34//==============================================================================
35template <typename T, typename... Ts>
37 using type = T;
38};
39//------------------------------------------------------------------------------
40template <typename... Ts>
41using front_type = typename front_type_impl<Ts...>::type;
42//==============================================================================
43template <typename... T>
45//------------------------------------------------------------------------------
46template <typename T>
47struct back_type_impl<T> {
48 using type = T;
49};
50//------------------------------------------------------------------------------
51template <typename T, typename... Ts>
52struct back_type_impl<T, Ts...> {
53 using type = typename back_type_impl<Ts...>::type;
54};
55//------------------------------------------------------------------------------
56template <typename... Ts>
57using back_type = typename back_type_impl<Ts...>::type;
58//==============================================================================
59template <std::size_t I, std::size_t CurNum, std::size_t... RestNums>
61 static auto constexpr value = ith_number_impl<I - 1, RestNums...>::value;
62};
63template <std::size_t CurNum, std::size_t... RestNums>
64struct ith_number_impl<0, CurNum, RestNums...> {
65 static auto constexpr value = CurNum;
66};
67template <std::size_t I, std::size_t... Nums>
68[[maybe_unused]] static auto constexpr ith_number =
69 ith_number_impl<I, Nums...>::value;
70//==============================================================================
71template <std::size_t X, std::size_t... Rest>
73template <std::size_t X, std::size_t I, std::size_t... Rest>
74struct contains_impl<X, I, Rest...>
75 : std::integral_constant<bool, contains_impl<X, Rest...>::value> {};
76template <std::size_t X, std::size_t... Rest>
77struct contains_impl<X, X, Rest...> : std::true_type {};
78template <std::size_t X>
79struct contains_impl<X> : std::false_type {};
80template <std::size_t X, std::size_t... Is>
81static constexpr auto contains = contains_impl<X, Is...>::value;
82//==============================================================================
84template <std::size_t I, std::size_t Begin, std::size_t End>
85constexpr auto extract_to_array(auto& extracted_data) -> auto& {
86 return extracted_data;
87}
88//==============================================================================
90template <std::size_t I, std::size_t Begin, std::size_t End,
91 typename T, typename... Ts>
92requires(Begin < End) && (I <= End)
93constexpr auto extract_to_array(auto& extracted_data,
94 T&& t, [[maybe_unused]] Ts&&... ts) -> auto& {
95 if constexpr (I == End) {
96 return extracted_data;
97 } else {
98 if constexpr (I >= Begin) {
99 extracted_data[I - Begin] = std::forward<T>(t);
100 }
101 return extract_to_array<I + 1, Begin, End>(extracted_data, std::forward<Ts>(ts)...);
102 }
103}
104//==============================================================================
106template <std::size_t I, std::size_t Begin, std::size_t End>
107constexpr auto extract_to_tuple(auto& extracted_data) -> auto& {
108 return extracted_data;
109}
110//------------------------------------------------------------------------------
112template <std::size_t I, std::size_t Begin, std::size_t End,
113 typename T, typename... Ts>
114requires(Begin < End) && (I == End)
115constexpr auto extract_to_tuple(auto& extracted_data) -> auto& {
116 return extracted_data;
117}
118//------------------------------------------------------------------------------
120template <std::size_t I, std::size_t Begin, std::size_t End,
121 typename T, typename... Ts>
122requires(Begin < End) && (I <= End)
123constexpr auto extract_to_tuple(auto& extracted_data,
124 T&& t, [[maybe_unused]] Ts&&... ts) -> auto& {
125 if constexpr (I == End) {
126 return extracted_data;
127 } else {
128 if constexpr (I >= Begin) {
129 extracted_data.template at<I - Begin>() = std::forward<T>(t);
130 }
131 return extract_to_tuple<I + 1, Begin, End>(extracted_data, std::forward<Ts>(ts)...);
132 }
133}
134//------------------------------------------------------------------------------
135template <std::size_t I, std::size_t Begin, std::size_t End, typename... Ts>
137//------------------------------------------------------------------------------
139template <std::size_t I, std::size_t Begin, std::size_t End, typename T,
140 typename... Ts>
141requires(I < Begin)
143 using type =
144 typename extract_helper_tuple_impl<I + 1, Begin, End, Ts...>::type;
145};
146//------------------------------------------------------------------------------
148template <std::size_t I, std::size_t Begin, std::size_t End, typename T0, typename T1,
149 typename... Ts>
150requires(I >= Begin && I < End-1)
153 tuple<T0>,
154 typename extract_helper_tuple_impl<I + 1, Begin, End, T1, Ts...>::type>;
155};
156//------------------------------------------------------------------------------
158template <std::size_t I, std::size_t Begin, std::size_t End, typename T,
159 typename... Ts>
160requires(I == End - 1)
162 using type = tuple<T>;
163};
164//------------------------------------------------------------------------------
165template <std::size_t Begin, std::size_t End, typename... Ts>
167 typename extract_helper_tuple_impl<0, Begin, End, Ts...>::type;
168//------------------------------------------------------------------------------
170template <std::size_t Begin, std::size_t End, typename T, typename... Ts>
171requires (Begin < End)
172constexpr auto extract(T&&t, Ts&&... ts) {
173 if constexpr ((std::is_same_v<std::decay_t<T>, std::decay_t<Ts>>&&...)) {
174 auto extracted_data =
175 std::array<std::decay_t<T>, End - Begin>{};
176 return extract_to_array<0, Begin, End>(extracted_data,
177 std::forward<T>(t),
178 std::forward<Ts>(ts)...);
179 } else {
180 auto extracted_data = extract_helper_tuple<Begin, End, std::decay_t<T>, std::decay_t<Ts>...>{};
181 return extract_to_tuple<0, Begin, End>(extracted_data,
182 std::forward<T>(t),
183 std::forward<Ts>(ts)...);
184 }
185}
186//==============================================================================
187} // namespace tatooine::variadic
188//==============================================================================
189#endif
Definition: variadic_helpers.h:9
static auto constexpr front_number
Definition: variadic_helpers.h:17
typename front_type_impl< Ts... >::type front_type
Definition: variadic_helpers.h:41
constexpr auto extract(T &&t, Ts &&... ts)
Extracts variadic data into an array in the Range of Begin and End.
Definition: variadic_helpers.h:172
constexpr auto extract_to_tuple(auto &extracted_data) -> auto &
Extracts variadic data into an array in the Range of Begin and End.
Definition: variadic_helpers.h:107
typename extract_helper_tuple_impl< 0, Begin, End, Ts... >::type extract_helper_tuple
Definition: variadic_helpers.h:167
static auto constexpr back_number
Definition: variadic_helpers.h:33
constexpr auto extract_to_array(auto &extracted_data) -> auto &
Extracts variadic data into an array in the Range of Begin and End.
Definition: variadic_helpers.h:85
static constexpr auto contains
Definition: variadic_helpers.h:81
static auto constexpr ith_number
Definition: variadic_helpers.h:68
typename back_type_impl< Ts... >::type back_type
Definition: variadic_helpers.h:57
typename tuple_concat_types_impl< Tuple1, Tuple2 >::type tuple_concat_types
Definition: tuple.h:139
Definition: tuple.h:11
Definition: variadic_helpers.h:20
typename back_type_impl< Ts... >::type type
Definition: variadic_helpers.h:53
T type
Definition: variadic_helpers.h:48
Definition: variadic_helpers.h:44
Definition: variadic_helpers.h:72
tuple_concat_types< tuple< T0 >, typename extract_helper_tuple_impl< I+1, Begin, End, T1, Ts... >::type > type
Definition: variadic_helpers.h:154
typename extract_helper_tuple_impl< I+1, Begin, End, Ts... >::type type
Definition: variadic_helpers.h:144
Definition: variadic_helpers.h:136
Definition: variadic_helpers.h:12
static auto constexpr value
Definition: variadic_helpers.h:13
Definition: variadic_helpers.h:36
T type
Definition: variadic_helpers.h:37
Definition: variadic_helpers.h:60
static auto constexpr value
Definition: variadic_helpers.h:61