Templa 0.0.1-alpha
C++ Metaprogramming Utilities
Loading...
Searching...
No Matches
type_list.hpp
Go to the documentation of this file.
1#pragma once
2#include <iostream>
6
11namespace templa
12{
19 template <typename Initial, typename... Ts>
20 struct type_list_append : internal::type_list<Initial, Ts...>
21 {
22 };
23
32 template <template <typename...> class Initial, template <typename...> class Appender, typename... Inits, typename... Apps>
33 struct type_list_append<Initial<Inits...>, Appender<Apps...>> : internal::type_list<Inits..., Apps...>
34 {
35 };
36
44 template <template <typename...> class Initial, typename Elem, typename... Inits>
45 struct type_list_append<Initial<Inits...>, Elem> : internal::type_list<Inits..., Elem>
46 {
47 };
48
55 template <typename Initial, typename... Preps>
56 struct type_list_prepend : internal::type_list<Preps..., Initial>
57 {
58 };
59
68 template <template <typename...> class Initial, template <typename...> class Prepender, typename... Inits, typename... Preps>
69 struct type_list_prepend<Initial<Inits...>, Prepender<Preps...>> : internal::type_list<Preps..., Inits...>
70 {
71 };
72
80 template <template <typename...> class Initial, typename Elem, typename... Inits>
81 struct type_list_prepend<Initial<Inits...>, Elem> : internal::type_list<Elem, Inits...>
82 {
83 };
84
90 template <typename... T>
92
100 template <typename T, typename U, typename... Ts>
101 struct type_list_reverse<T, U, Ts...> : internal::type_list<Ts..., U, T>
102 {
103 };
104
113 template <template <typename...> class Tlist, typename T, typename U, typename... Ts>
114 struct type_list_reverse<Tlist<T, U, Ts...>> : internal::type_list<Ts..., U, T>
115 {
116 };
117
124 template <typename... T>
126
133 template <typename T, typename... Ts>
134 struct type_list_pop_front<T, Ts...> : internal::type_list<Ts...>
135 {
137 using popped = T;
138 };
139
147 template <template <typename...> class Tlist, typename U, typename... Ts>
148 struct type_list_pop_front<Tlist<U, Ts...>> : internal::type_list<Ts...>
149 {
151 using popped = U;
152 };
153
159 template <typename... Ts>
161
168 template <typename Head, typename Tail>
169 struct type_list_pop_back<Head, Tail> : internal::type_list<Head>
170 {
172 using popped = Tail;
173 };
174
182 template <typename Head, typename Mid, typename... Tail>
183 struct type_list_pop_back<Head, Mid, Tail...>
184 {
185 private:
186 using type_list = type_list_prepend<typename type_list_pop_back<Mid, Tail...>::type, Head>;
187
188 public:
192 constexpr static size_t size = type::size;
194 using popped = typename type_list_pop_back<Mid, Tail...>::popped;
195 };
196
203 template <template <typename...> class Tlist, typename... Ts>
204 struct type_list_pop_back<Tlist<Ts...>>
205 {
206 private:
207 using type_list = type_list_pop_back<Ts...>;
208
209 public:
211 using type = type_list::type;
213 constexpr static size_t size = type::size;
215 using popped = type_list::popped;
216 };
217
218 namespace internal
219 {
227 template <typename... Fns>
228 struct visitor : Fns...
229 {
230 using Fns::operator()...;
231 };
232 };
233
241 template <std::size_t x>
242 using value = std::integral_constant<std::size_t, x>;
243
250 template <std::size_t idx, typename... Ts>
252 {
253 static_assert(idx <= sizeof...(Ts) && idx >= 0, "Index out of bounds");
254
256 using type = decltype([]<std::size_t... i>(std::index_sequence<i...>)
257 { return internal::visitor{
258 [](value<i>)
259 {
260 return std::type_identity<Ts>();
261 }...}(value<idx>{}); }(std::index_sequence_for<Ts...>()))::type;
262 };
263
270 template <std::size_t idx, template <typename...> class T, typename... Ts>
271 struct type_at_index<idx, T<Ts...>>
272 {
273 using type = type_at_index<idx, Ts...>::type;
274 };
275
282 template <std::size_t idx, typename... Ts>
284
291 template <typename T, typename... Ts>
293 {
295 constexpr static bool value = (std::is_same_v<T, Ts> || ...);
296 };
297
305 template <typename T, template <typename...> class U, typename... Ts>
306 struct type_list_contains<T, U<Ts...>>
307 {
308 constexpr static bool value = type_list_contains<T, Ts...>::value;
309 };
310
320 template <typename T, typename... List>
322 {
324 constexpr static auto index = []()
325 {
327 {signed i = 0;
328 (... && (!std::is_same_v<T, List> && ++i));
329 return i; }() : -1);
330 }();
331 };
332
343 template <typename T, template <typename...> class U, typename... List>
344 struct index_at_type<T, U<List...>>
345 {
347 constexpr static auto index = index_at_type<T, List...>::index;
348 };
349
357 template <typename T, typename... List>
358 constexpr static auto index_at_type_v = index_at_type<T, List...>::index;
359
374 template <typename... Ts>
376
380 template <>
382 {
383 };
384
388 template <typename T>
390 {
391 };
392
399 template <typename... Ts>
400 struct type_list_flatten<internal::type_list<Ts...>> : type_list_flatten<Ts...>
401 {
402 };
403
410 template <typename T, typename... Rest>
411 struct type_list_flatten<T, Rest...>
412 {
413 private:
414 using head = typename type_list_flatten<T>::type;
415 using tail = typename type_list_flatten<Rest...>::type;
416
417 public:
418 using type = typename type_list_append<head, tail>::type;
419 };
420
434 template <typename... Ts>
436
437 template <>
439 {
440 };
441
442 template <typename T, typename... Ts>
443 struct type_list_unique<T, Ts...>
444 {
445 private:
446 using tail = typename type_list_unique<Ts...>::type;
447
448 public:
449 using type = std::conditional_t<
451 tail,
452 typename type_list_append<internal::type_list<T>, tail>::type>;
453 };
454
455 template <typename... Ts>
456 using type_list_unique_t = typename type_list_unique<Ts...>::type;
457
467 template <std::size_t Offset, typename Seq>
469
476 template <std::size_t Offset, std::size_t... Is>
477 struct offset_index_sequence<Offset, std::index_sequence<Is...>>
478 {
480 using type = std::index_sequence<(Is + Offset)...>;
481 };
482
493 template <typename T, typename F, typename S>
495
504 template <template <typename...> class T, typename... Args, std::size_t... Is, std::size_t... Js>
505 struct type_list_split<T<Args...>, std::index_sequence<Is...>, std::index_sequence<Js...>>
506 {
508 using first = T<std::tuple_element_t<Is, std::tuple<Args...>>...>;
509
511 using second = T<std::tuple_element_t<Js, std::tuple<Args...>>...>;
512 };
513
523 template <typename Ts>
525
532 template <template <typename...> class T, typename... Args>
533 struct type_list_split_half<T<Args...>>
534 {
535 private:
537 static constexpr std::size_t mid = sizeof...(Args) / 2;
538
540 using first_indices = std::make_index_sequence<mid>;
541
543 using second_indices = typename offset_index_sequence<
544 mid,
545 std::make_index_sequence<sizeof...(Args) - mid>>::type;
546
548 using full_type = type_list_split<T<Args...>, first_indices, second_indices>;
549
550 public:
552 using first = typename full_type::first;
553
555 using second = typename full_type::second;
556 };
557}
static constexpr auto index
Index of type T in List.
Definition type_list.hpp:347
Get the index of a type in a type list.
Definition type_list.hpp:322
static constexpr auto index
Index of type T in List.
Definition type_list.hpp:324
A compile-time list of types.
Definition pack.hpp:46
hidden::pack< Ts... > type
Definition pack.hpp:48
Helper visitor struct inheriting from multiple function objects.
Definition type_list.hpp:229
std::index_sequence<(Is+Offset)... > type
Resulting index sequence with offset applied.
Definition type_list.hpp:480
Utility to create an offset std::index_sequence.
Definition type_list.hpp:468
Get the type at a given index in a parameter pack.
Definition type_list.hpp:252
decltype([]< std::size_t... i >(std::index_sequence< i... >) { return internal::visitor{[](value< i >) { return std::type_identity< Ts >(); }...}(value< idx >{});}(std::index_sequence_for< Ts... >()))::type type
Type at index idx.
Definition type_list.hpp:256
Appends types or type lists to an existing type list.
Definition type_list.hpp:21
Check if a type list contains a given type.
Definition type_list.hpp:293
static constexpr bool value
True if T is in Ts...
Definition type_list.hpp:295
Recursively flattens nested type_lists into a single flat type_list.
Definition type_list.hpp:375
type_list::type type
Type list without the last type.
Definition type_list.hpp:190
static constexpr size_t size
Number of types after popping.
Definition type_list.hpp:192
typename type_list_pop_back< Mid, Tail... >::popped popped
The popped (removed) last type.
Definition type_list.hpp:194
Tail popped
The popped (removed) last type.
Definition type_list.hpp:172
type_list::popped popped
The popped (removed) last type.
Definition type_list.hpp:215
static constexpr size_t size
Number of types after popping.
Definition type_list.hpp:213
type_list::type type
Type list without the last type.
Definition type_list.hpp:211
Remove the last type from a type list.
Definition type_list.hpp:160
T popped
The popped (removed) first type.
Definition type_list.hpp:137
U popped
The popped (removed) first type.
Definition type_list.hpp:151
Remove the first type from a type list.
Definition type_list.hpp:125
Prepends types or type lists to an existing type list.
Definition type_list.hpp:57
Reverse the order of types in a type list.
Definition type_list.hpp:91
T< std::tuple_element_t< Js, std::tuple< Args... > >... > second
Second half of the split type list.
Definition type_list.hpp:511
T< std::tuple_element_t< Is, std::tuple< Args... > >... > first
First half of the split type list.
Definition type_list.hpp:508
typename full_type::second second
Second half of the split type list.
Definition type_list.hpp:555
typename full_type::first first
First half of the split type list.
Definition type_list.hpp:552
Splits a type list into two halves.
Definition type_list.hpp:524
Splits a type list into two sublists using index sequences.
Definition type_list.hpp:494
Removes duplicate types from a parameter pack.
Definition type_list.hpp:435
std::integral_constant< std::size_t, x > value
Integral constant wrapper for a size_t value.
Definition type_list.hpp:242
type_at_index< idx, Ts... >::type type_at_index_t
Convenience alias for type_at_index::type.
Definition type_list.hpp:283