vari
Loading...
Searching...
No Matches
typelist.h
1
23
24#pragma once
25
26#include <concepts>
27#include <cstddef>
28
29namespace vari
30{
31
32template < typename T >
33struct _dependent_false : std::false_type
34{
35};
36
37// Most of the templates for typelist specify operation over typelist, which does not have default
38// behavior for non-typelist-types. Any such template is guarded by this template to produce
39// compiler error in case they are given something they are not compatible with. Always consult the
40// documentation of the template to see what is expected.
41template < typename T >
42struct _default_template_guard
43{
44 static_assert(
45 _dependent_false< T >::value,
46 "Default template matched, this implies unexpected usage of the template. Read the documentation of template." );
47};
48
49// ---
50
51// compile time set of types Ts...
52template < typename... Ts >
53struct typelist
54{
55 using types = typelist< Ts... >;
56 static constexpr std::size_t size = sizeof...( Ts );
57};
58
59template < typename T >
60struct typelist_traits
61{
62 static constexpr bool is_compatible = false;
63};
64
65template < typename... Ts >
66struct typelist_traits< typelist< Ts... > >
67{
68 static constexpr bool is_compatible = true;
69
70 using types = typelist< Ts... >;
71};
72
73template < typename T >
74using typelist_traits_types = typename typelist_traits< T >::types;
75
76template < typename T >
77concept typelist_compatible = typelist_traits< T >::is_compatible;
78
79// ---
80
81// Index of type `T` or `T const` in typelist `TL`, exported as ::value. `TL` has to be `typelist`
82// or typelist compatible type.
83template < typename T, typename TL >
84struct index_of_t_or_const_t : _default_template_guard< T >
85{
86};
87
88template < typename T, typelist_compatible TL >
89struct index_of_t_or_const_t< T, TL > : index_of_t_or_const_t< typelist_traits_types< T >, TL >
90{
91};
92
93template < typename T >
94struct index_of_t_or_const_t< T, typelist<> >
95{
96 static_assert( !std::same_as< T, T >, "Type T is not present in the type list" );
97};
98
99template < typename T, typename... Ts >
100struct index_of_t_or_const_t< T, typelist< T, Ts... > >
101{
102 static constexpr std::size_t value = 0;
103};
104
105template < typename T, typename... Ts >
106struct index_of_t_or_const_t< T, typelist< T const, Ts... > >
107{
108 static constexpr std::size_t value = 0;
109};
110
111template < typename T, typename U, typename... Ts >
112struct index_of_t_or_const_t< T, typelist< U, Ts... > >
113{
114 static constexpr std::size_t value =
115 1 + index_of_t_or_const_t< T, typelist< Ts... > >::value;
116};
117
118template < typename T, typename TL >
119static constexpr std::size_t index_of_t_or_const_t_v = index_of_t_or_const_t< T, TL >::value;
120
121// ---
122
123// Exports type at index `j` in typelist `TL` as ::type. `TL` has to be `typelist` or typelist
124// compatible type.
125template < std::size_t j, typename TL >
126struct type_at : _default_template_guard< TL >
127{
128};
129
130template < std::size_t j, typelist_compatible TL >
131struct type_at< j, TL > : type_at< j, typelist_traits_types< TL > >
132{
133};
134
135template < std::size_t j, typename T, typename... Ts >
136struct type_at< j, typelist< T, Ts... > >
137{
138 using type = typename type_at< j - 1, typelist< Ts... > >::type;
139};
140
141template < typename T, typename... Ts >
142struct type_at< 0, typelist< T, Ts... > >
143{
144 using type = T;
145};
146
147template < std::size_t j, typename TL >
148using type_at_t = typename type_at< j, TL >::type;
149
150// ---
151
152// ::value is true if type `T` is present in typelist `TL`, false otherwise. `TL` has to be
153// `typelist` or typelist compatible type.
154template < typename T, typename TL >
155struct contains_type : _default_template_guard< T >
156{
157};
158
159template < typename T, typelist_compatible TL >
160struct contains_type< T, TL > : contains_type< T, typelist_traits_types< TL > >
161{
162};
163
164template < typename T, typename... Ts >
165struct contains_type< T, typelist< Ts... > >
166{
167 static constexpr bool value = ( std::same_as< T, Ts > || ... || false );
168};
169
170template < typename T, typename TL >
171static constexpr bool contains_type_v = contains_type< T, TL >::value;
172
173// ---
174
175// Filters out duplicates from typelist `TL2`, `TL1` is used as output argument collecting the
176// result typelist as it is filtered. ::type will contain the final filtered typelist. `TL1` and
177// `TL2` has to be `typelist` or typelist compatible type.
178template < typename TL1, typename TL2 >
179struct _unique_tl_impl : _default_template_guard< TL1 >
180{
181};
182
183template < typename TL1, typelist_compatible TL2 >
184struct _unique_tl_impl< TL1, TL2 > : _unique_tl_impl< TL1, typelist_traits_types< TL2 > >
185{
186};
187
188template < typename... Ts >
189struct _unique_tl_impl< typelist< Ts... >, typelist<> >
190{
191 using type = typelist< Ts... >;
192};
193
194template < typename TL1, typename T, typename... Ts >
195 requires( contains_type_v< T, typelist< Ts... > > )
196struct _unique_tl_impl< TL1, typelist< T, Ts... > > : _unique_tl_impl< TL1, typelist< Ts... > >
197{
198};
199
200template < typename... Us, typename T, typename... Ts >
201 requires( !contains_type_v< T, typelist< Ts... > > )
202struct _unique_tl_impl< typelist< Us... >, typelist< T, Ts... > >
203 : _unique_tl_impl< typelist< Us..., T >, typelist< Ts... > >
204{
205};
206
207template < typename TL >
208using unique_typelist_t = typename _unique_tl_impl< typelist<>, TL >::type;
209
210// ---
211
212// Flattens any `typelist` or typelist compatible type within the `Ts...` set, producing a single
213// flat set. `TL` is used as output argument collecting the result typelist. ::type will contain the
214// final flattened typelist. `TL` has to be `typelist`.
215template < typename TL, typename... Ts >
216struct _flatten_impl : _default_template_guard< TL >
217{
218};
219
220template < typename TL >
221struct _flatten_impl< TL >
222{
223 using type = TL;
224};
225
226template < typename... Us, typelist_compatible T, typename... Ts >
227struct _flatten_impl< typelist< Us... >, T, Ts... >
228 : _flatten_impl< typelist< Us... >, typelist_traits_types< T >, Ts... >
229{
230};
231
232template < typename... Us, typename T, typename... Ts >
233struct _flatten_impl< typelist< Us... >, T, Ts... > : _flatten_impl< typelist< Us..., T >, Ts... >
234{
235};
236
237template < typename... Us, typename... Ks, typename... Ts >
238struct _flatten_impl< typelist< Us... >, typelist< Ks... >, Ts... >
239 : _flatten_impl< typelist< Us... >, Ks..., Ts... >
240{
241};
242
243template < typename... Us, typename... Ks, typename... Ts >
244struct _flatten_impl< typelist< Us... >, typelist< Ks... > const, Ts... >
245 : _flatten_impl< typelist< Us... >, Ks const..., Ts... >
246{
247};
248
249template < typename... Ts >
250using flatten_t = typename _flatten_impl< typelist<>, Ts... >::type;
251
252// ---
253
254// ::value is true if all types in `LH` are present in `RH`, false otherwise. `LH` and `RH` has
255// to be `typelist` or typelist compatible type.
256template < typename LH, typename RH >
257struct is_subset : _default_template_guard< LH >
258{
259};
260
261template < typename... Us, typename RH >
262struct is_subset< typelist< Us... >, RH >
263{
264 static constexpr bool value = ( contains_type_v< Us, RH > && ... );
265};
266
267template < typename... Us, typename RH >
268struct is_subset< typelist< Us... > const, RH >
269{
270 static constexpr bool value = ( contains_type_v< Us const, RH > && ... );
271};
272
273template < typename LH, typename RH >
274static constexpr bool is_subset_v = is_subset< LH, RH >::value;
275
276// ---
277
278// ::value is true if any type in typelist `TL` is const qualified, false otherwise. `TL` has to be
279// `typelist` or typelist compatible type.
280template < typename TL >
281struct any_is_const : _default_template_guard< TL >
282{
283};
284
285template < typelist_compatible TL >
286struct any_is_const< TL > : any_is_const< typelist_traits_types< TL > >
287{
288};
289
290template < typename... Us >
291struct any_is_const< typelist< Us... > >
292{
293 static constexpr bool value = ( std::is_const_v< Us > || ... );
294};
295
296template < typename TL >
297static constexpr bool any_is_const_v = any_is_const< TL >::value;
298
299// ---
300
301// ::value is true if all types in typelist `TL` are const qualified, false otherwise. `TL` has to
302// be `typelist` or typelist compatible type.
303template < typename TL >
304struct all_is_const : _default_template_guard< TL >
305{
306};
307
308template < typelist_compatible TL >
309struct all_is_const< TL > : all_is_const< typelist_traits_types< TL > >
310{
311};
312
313template < typename... Us >
314struct all_is_const< typelist< Us... > >
315{
316 static constexpr bool value = ( std::is_const_v< Us > && ... );
317};
318
319template < typename TL >
320static constexpr bool all_is_const_v = all_is_const< TL >::value;
321
322// ---
323
324// ::value is true if none of the types in typelist `TL` are const qualified, false otherwise. `TL`
325// has to be `typelist` or typelist compatible type.
326template < typename TL >
327struct none_is_const : _default_template_guard< TL >
328{
329};
330
331template < typelist_compatible TL >
332struct none_is_const< TL > : none_is_const< typelist_traits_types< TL > >
333{
334};
335
336template < typename... Us >
337struct none_is_const< typelist< Us... > >
338{
339 static constexpr bool value = !( std::is_const_v< Us > || ... );
340};
341
342template < typename TL >
343static constexpr bool none_is_const_v = none_is_const< TL >::value;
344
345// ---
346
347// ::value is true if all types in typelist `TL` are nothrow swappable, false otherwise. `TL` has to
348// be `typelist` or typelist compatible type.
349template < typename TL >
350struct all_nothrow_swappable : _default_template_guard< TL >
351{
352};
353
354template < typelist_compatible TL >
355struct all_nothrow_swappable< TL > : all_nothrow_swappable< typelist_traits_types< TL > >
356{
357};
358
359template < typename... Us >
360struct all_nothrow_swappable< typelist< Us... > >
361{
362 static constexpr bool value = ( std::is_nothrow_swappable_v< Us > && ... && true );
363};
364
365template < typename TL >
366static constexpr bool all_nothrow_swappable_v = all_nothrow_swappable< TL >::value;
367
368// ---
369
370// ::value is true if all types in typelist `TL` are nothrow move constructible, false otherwise.
371// `TL` has to be `typelist` or typelist compatible type.
372template < typename TL >
373struct all_nothrow_move_constructible : _default_template_guard< TL >
374{
375};
376
377template < typelist_compatible TL >
378struct all_nothrow_move_constructible< TL >
379 : all_nothrow_move_constructible< typelist_traits_types< TL > >
380{
381};
382
383template < typename... Us >
384struct all_nothrow_move_constructible< typelist< Us... > >
385{
386 static constexpr bool value = ( std::is_nothrow_move_constructible_v< Us > && ... && true );
387};
388
389template < typename TL >
390static constexpr bool all_nothrow_move_constructible_v =
391 all_nothrow_move_constructible< TL >::value;
392
393// ---
394
395// ::value is true if all types in typelist `TL` are nothrow copy constructible, false otherwise.
396// `TL` has to be `typelist` or typelist compatible type.
397template < typename TL >
398struct all_nothrow_copy_constructible : _default_template_guard< TL >
399{
400};
401
402template < typelist_compatible TL >
403struct all_nothrow_copy_constructible< TL >
404 : all_nothrow_copy_constructible< typelist_traits_types< TL > >
405{
406};
407
408template < typename... Us >
409struct all_nothrow_copy_constructible< typelist< Us... > >
410{
411 static constexpr bool value = ( std::is_nothrow_copy_constructible_v< Us > && ... && true );
412};
413
414template < typename TL >
415static constexpr bool all_nothrow_copy_constructible_v =
416 all_nothrow_copy_constructible< TL >::value;
417
418// ---
419
420// ::value is true if all types in typelist `TL` are nothrow destructible, false otherwise.
421// `TL` has to be `typelist` or typelist compatible type.
422template < typename TL >
423struct all_nothrow_destructible : _default_template_guard< TL >
424{
425};
426
427template < typelist_compatible TL >
428struct all_nothrow_destructible< TL > : all_nothrow_destructible< typelist_traits_types< TL > >
429{
430};
431
432template < typename... Us >
433struct all_nothrow_destructible< typelist< Us... > >
434{
435 static constexpr bool value = ( std::is_nothrow_destructible_v< Us > && ... && true );
436};
437
438template < typename TL >
439static constexpr bool all_nothrow_destructible_v = all_nothrow_destructible< TL >::value;
440
441
442// ---
443
444template < typename U, typename T >
445concept nothrow_three_way_comparable = noexcept( std::declval< U >() <=> std::declval< T >() );
446
447// ::value is true if all types in typelist `TL` are nothrow three way comparable, false otherwise.
448// `TL` has to be `typelist` or typelist compatible type.
449template < typename TL >
450struct all_nothrow_three_way_comparable : _default_template_guard< TL >
451{
452};
453
454template < typelist_compatible TL >
455struct all_nothrow_three_way_comparable< TL >
456 : all_nothrow_three_way_comparable< typelist_traits_types< TL > >
457{
458};
459
460template < typename... Us >
461struct all_nothrow_three_way_comparable< typelist< Us... > >
462{
463 static constexpr bool value = ( nothrow_three_way_comparable< Us, Us > && ... && true );
464};
465
466template < typename TL >
467static constexpr bool all_nothrow_three_way_comparable_v =
468 all_nothrow_three_way_comparable< TL >::value;
469
470// ---
471
472template < typename U, typename T >
473concept nothrow_equality_comparable = noexcept( std::declval< U >() == std::declval< T >() );
474
475// ::value is true if all types in typelist `TL` are nothrow equality comparable, false otherwise.
476// `TL` has to be `typelist` or typelist compatible type.
477template < typename TL >
478struct all_nothrow_equality_comparable : _default_template_guard< TL >
479{
480};
481
482template < typelist_compatible TL >
483struct all_nothrow_equality_comparable< TL >
484 : all_nothrow_copy_constructible< typelist_traits_types< TL > >
485{
486};
487
488template < typename... Us >
489struct all_nothrow_equality_comparable< typelist< Us... > >
490{
491 static constexpr bool value = ( nothrow_equality_comparable< Us, Us > && ... && true );
492};
493
494template < typename TL >
495static constexpr bool all_nothrow_equality_comparable_v =
496 all_nothrow_equality_comparable< TL >::value;
497
498// ---
499
500// ::type is a typelist containing all return types of `Fac::operator()< N >()` for `N` going from 0
501// to `N`, exclusive. `TL` has to be `typelist` or typelist compatible type. `Fac` has to be a type
502// with `operator()< N >()` defined for `N` from 0 to `N`, exclusive.
503template < typename TL, std::size_t N, typename Fac >
504struct _factory_result_types_impl : _default_template_guard< TL >
505{
506};
507
508template < typename... Ts, typename Fac >
509struct _factory_result_types_impl< typelist< Ts... >, 0, Fac >
510{
511 using type = typelist< Ts... >;
512};
513
514template < typename... Ts, std::size_t N, typename Fac >
515struct _factory_result_types_impl< typelist< Ts... >, N, Fac >
516{
517 using n_type = decltype( std::declval< Fac >().template operator()< N - 1 >() );
518 using type =
519 typename _factory_result_types_impl< typelist< Ts..., n_type >, N - 1, Fac >::type;
520};
521
522template < std::size_t N, typename Fac >
523using factory_result_types_t = typename _factory_result_types_impl< typelist<>, N, Fac >::type;
524
525} // namespace vari
MIT License.
Definition: dispatch.h:32