fsm
type_traits.h
1 
12 #pragma once
13 
14 #include <charconv>
15 #include <cstddef>
16 #include <iterator>
17 #include <type_traits>
18 #include <utility>
19 
20 namespace mpl {
25 template <std::size_t N>
26 struct choice_t
27  // Unfortunately, doxygen cannot parse such a construct.
28  : choice_t<N - 1>
29 {};
30 
32 template <> struct choice_t<0> {};
33 
38 template <std::size_t N> inline constexpr choice_t<N> choice{};
39 
48 template <typename Type> struct type_identity {
50  using type = Type;
51 };
52 
57 template <typename Type>
58 using type_identity_t = typename type_identity<Type>::type;
59 
60 
65 template <class T>
67 {
68  using type = const std::remove_reference_t<T>&;
69 };
70 
75 template <class T>
76 using const_reference_t = typename const_reference<T>::type;
77 
78 template <class T>
80 {
81  using type = std::conditional_t<std::is_lvalue_reference_v<T>, const_reference_t<T>, const T>;
82 };
83 
84 template <class T>
85 using add_const_to_value_t = typename add_const_to_value<T>::type;
86 
87 
93 template <typename Type, typename = void>
94 struct size_of : std::integral_constant<std::size_t, 0u> {};
95 
97 template <typename Type>
98 struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
99  : std::integral_constant<std::size_t, sizeof(Type)> {};
100 
105 template <typename Type>
106 inline constexpr std::size_t size_of_v = size_of<Type>::value;
107 
113 template <typename Type, typename> using unpack_as_type = Type;
114 
120 template <auto Value, typename> inline constexpr auto unpack_as_value = Value;
121 
126 template <auto Value>
127 using integral_constant = std::integral_constant<decltype(Value), Value>;
128 
135 // template<id_type Value>
136 // using tag = integral_constant<Value>;
137 
142 template <typename... Type> struct type_list {
144  using type = type_list;
146  static constexpr auto size = sizeof...(Type);
147 };
148 
150 template <std::size_t, typename> struct type_list_element;
151 
158 template <std::size_t Index, typename First, typename... Other>
159 struct type_list_element<Index, type_list<First, Other...>>
160  : type_list_element<Index - 1u, type_list<Other...>> {};
161 
167 template <typename First, typename... Other>
168 struct type_list_element<0u, type_list<First, Other...>> {
170  using type = First;
171 };
172 
178 template <std::size_t Index, typename List>
179 using type_list_element_t = typename type_list_element<Index, List>::type;
180 
182 template <typename, typename> struct type_list_index;
183 
190 template <typename Type, typename First, typename... Other>
191 struct type_list_index<Type, type_list<First, Other...>> {
193  using value_type = std::size_t;
195  static constexpr value_type value =
196  1u + type_list_index<Type, type_list<Other...>>::value;
197 };
198 
204 template <typename Type, typename... Other>
205 struct type_list_index<Type, type_list<Type, Other...>> {
206  static_assert(type_list_index<Type, type_list<Other...>>::value ==
207  sizeof...(Other),
208  "Non-unique type");
210  using value_type = std::size_t;
212  static constexpr value_type value = 0u;
213 };
214 
219 template <typename Type> struct type_list_index<Type, type_list<>> {
221  using value_type = std::size_t;
223  static constexpr value_type value = 0u;
224 };
225 
231 template <typename Type, typename List>
232 inline constexpr std::size_t type_list_index_v =
234 
241 template <typename... Type, typename... Other>
242 constexpr type_list<Type..., Other...> operator+(type_list<Type...>,
244  return {};
245 }
246 
248 template <typename...> struct type_list_cat;
249 
251 template <> struct type_list_cat<> {
253  using type = type_list<>;
254 };
255 
262 template <typename... Type, typename... Other, typename... List>
263 struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
265  using type =
266  typename type_list_cat<type_list<Type..., Other...>, List...>::type;
267 };
268 
273 template <typename... Type> struct type_list_cat<type_list<Type...>> {
275  using type = type_list<Type...>;
276 };
277 
282 template <typename... List>
283 using type_list_cat_t = typename type_list_cat<List...>::type;
284 
286 template <typename> struct type_list_unique;
287 
293 template <typename Type, typename... Other>
294 struct type_list_unique<type_list<Type, Other...>> {
296  using type = std::conditional_t<
297  (std::is_same_v<Type, Other> || ...),
298  typename type_list_unique<type_list<Other...>>::type,
299  type_list_cat_t<type_list<Type>,
300  typename type_list_unique<type_list<Other...>>::type>>;
301 };
302 
304 template <> struct type_list_unique<type_list<>> {
306  using type = type_list<>;
307 };
308 
313 template <typename Type>
314 using type_list_unique_t = typename type_list_unique<Type>::type;
315 
322 template <typename List, typename Type> struct type_list_contains;
323 
329 template <typename... Type, typename Other>
330 struct type_list_contains<type_list<Type...>, Other>
331  : std::disjunction<std::is_same<Type, Other>...> {};
332 
338 template <typename List, typename Type>
339 inline constexpr bool type_list_contains_v =
341 
343 template <typename...> struct type_list_diff;
344 
350 template <typename... Type, typename... Other>
351 struct type_list_diff<type_list<Type...>, type_list<Other...>> {
353  using type = type_list_cat_t<
354  std::conditional_t<type_list_contains_v<type_list<Other...>, Type>,
356 };
357 
362 template <typename... List>
363 using type_list_diff_t = typename type_list_diff<List...>::type;
364 
366 template <typename, template <typename...> class> struct type_list_transform;
367 
373 template <typename... Type, template <typename...> class Op>
374 struct type_list_transform<type_list<Type...>, Op> {
377 };
378 
384 template <typename List, template <typename...> class Op>
385 using type_list_transform_t = typename type_list_transform<List, Op>::type;
386 
393 template <typename, template <typename...> typename> struct type_list_rename;
394 template <typename... T, template <typename...> typename F>
395 struct type_list_rename<type_list<T...>, F> {
396  using result = F<T...>;
397 };
398 
405 template <typename, typename> struct type_list_push_front;
406 template <typename... E, typename T>
407 struct type_list_push_front<type_list<E...>, T> {
408  using result = type_list<T, E...>;
409 };
410 
414 template <class List> struct type_list_first {};
415 template <class First, class... Tail>
416 struct type_list_first<type_list<First, Tail...>> {
417  using type = First;
418 };
419 
424 template <auto... Value> struct value_list {
426  using type = value_list;
428  static constexpr auto size = sizeof...(Value);
429 };
430 
432 template <std::size_t, typename> struct value_list_element;
433 
440 template <std::size_t Index, auto Value, auto... Other>
441 struct value_list_element<Index, value_list<Value, Other...>>
442  : value_list_element<Index - 1u, value_list<Other...>> {};
443 
449 template <auto Value, auto... Other>
450 struct value_list_element<0u, value_list<Value, Other...>> {
452  static constexpr auto value = Value;
453 };
454 
460 template <std::size_t Index, typename List>
461 inline constexpr auto value_list_element_v =
463 
470 template <auto... Value, auto... Other>
471 constexpr value_list<Value..., Other...> operator+(value_list<Value...>,
473  return {};
474 }
475 
477 template <typename...> struct value_list_cat;
478 
480 template <> struct value_list_cat<> {
483 };
484 
491 template <auto... Value, auto... Other, typename... List>
492 struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
494  using type =
495  typename value_list_cat<value_list<Value..., Other...>, List...>::type;
496 };
497 
502 template <auto... Value> struct value_list_cat<value_list<Value...>> {
504  using type = value_list<Value...>;
505 };
506 
511 template <typename... List>
512 using value_list_cat_t = typename value_list_cat<List...>::type;
513 
514 
515 template <typename List, size_t ... indexes>
517 {
518  using type = std::tuple<typename value_list_element<indexes, List>::type...>;
519 };
520 
521 template <typename List, size_t ... indexes>
522 using value_list_expand_t = typename value_list_expand<List, indexes...>::type;
523 
524 
525 
526 
527 
528 
530 template <typename, typename> struct is_applicable : std::false_type {};
531 
538 template <typename Func, template <typename...> class Tuple, typename... Args>
539 struct is_applicable<Func, Tuple<Args...>> : std::is_invocable<Func, Args...> {
540 };
541 
548 template <typename Func, template <typename...> class Tuple, typename... Args>
549 struct is_applicable<Func, const Tuple<Args...>>
550  : std::is_invocable<Func, Args...> {};
551 
557 template <typename Func, typename Args>
558 inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
559 
561 template <typename, typename, typename>
562 struct is_applicable_r : std::false_type {};
563 
571 template <typename Ret, typename Func, typename... Args>
572 struct is_applicable_r<Ret, Func, std::tuple<Args...>>
573  : std::is_invocable_r<Ret, Func, Args...> {};
574 
582 template <typename Ret, typename Func, typename Args>
583 inline constexpr bool is_applicable_r_v =
585 
591 template <typename Type, typename = void>
592 struct is_complete : std::false_type {};
593 
595 template <typename Type>
596 struct is_complete<Type, std::void_t<decltype(sizeof(Type))>> : std::true_type {
597 };
598 
603 template <typename Type>
604 inline constexpr bool is_complete_v = is_complete<Type>::value;
605 
611 template <typename Type, typename = void>
612 struct is_iterator : std::false_type {};
613 
614 namespace details {
615 
616 template <typename, typename = void>
617 struct has_iterator_category : std::false_type {};
618 
619 template <typename Type>
621  Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>
622  : std::true_type {};
623 
624 } // namespace details
625 
627 template <typename Type>
628 struct is_iterator<Type,
629  std::enable_if_t<!std::is_same_v<
630  std::remove_const_t<std::remove_pointer_t<Type>>, void>>>
632 
637 template <typename Type>
638 inline constexpr bool is_iterator_v = is_iterator<Type>::value;
639 
645 template <typename Type>
646 struct is_ebco_eligible : std::conjunction<std::is_empty<Type>,
647  std::negation<std::is_final<Type>>> {
648 };
649 
654 template <typename Type>
655 inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
656 
662 template <typename Type, typename = void>
663 struct is_transparent : std::false_type {};
664 
666 template <typename Type>
667 struct is_transparent<Type, std::void_t<typename Type::is_transparent>>
668  : std::true_type {};
669 
674 template <typename Type>
675 inline constexpr bool is_transparent_v = is_transparent<Type>::value;
676 
682 template <typename Type, typename = void>
683 struct is_equality_comparable : std::false_type {};
684 
685 namespace details {
686 
687 template <typename, typename = void>
688 struct has_tuple_size_value : std::false_type {};
689 
690 template <typename Type>
692  Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>
693  : std::true_type {};
694 
695 template <typename Type, std::size_t... Index>
696 [[nodiscard]] constexpr bool
697 unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
698  return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value &&
699  ...);
700 }
701 
702 template <typename>
703 [[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
704  return true;
705 }
706 
707 template <typename Type>
708 [[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>)
709  -> decltype(std::declval<typename Type::value_type>(), bool{}) {
710  if constexpr (is_iterator_v<Type>) {
711  return true;
712  } else if constexpr (std::is_same_v<typename Type::value_type, Type>) {
713  return maybe_equality_comparable<Type>(choice<0>);
714  } else {
716  }
717 }
718 
719 template <typename Type>
720 [[nodiscard]] constexpr std::enable_if_t<
721  is_complete_v<std::tuple_size<std::remove_const_t<Type>>>, bool>
722 maybe_equality_comparable(choice_t<2>) {
723  if constexpr (has_tuple_size_value<Type>::value) {
724  return unpack_maybe_equality_comparable<Type>(
725  std::make_index_sequence<std::tuple_size<Type>::value>{});
726  } else {
727  return maybe_equality_comparable<Type>(choice<1>);
728  }
729 }
730 
731 } // namespace details
732 
734 template <typename Type>
736  Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
737  : std::bool_constant<details::maybe_equality_comparable<Type>(choice<2>)> {
738 };
739 
744 template <typename Type>
745 inline constexpr bool is_equality_comparable_v =
747 
753 template <typename To, typename From> struct constness_as {
755  using type = std::remove_const_t<To>;
756 };
757 
759 template <typename To, typename From> struct constness_as<To, const From> {
761  using type = const To;
762 };
763 
769 template <typename To, typename From>
770 using constness_as_t = typename constness_as<To, From>::type;
771 
776 template <typename Member> class member_class {
777  static_assert(std::is_member_pointer_v<Member>,
778  "Invalid pointer type to non-static member object or function");
779 
780  template <typename Class, typename Ret, typename... Args>
781  static Class *clazz(Ret (Class::*)(Args...));
782 
783  template <typename Class, typename Ret, typename... Args>
784  static Class *clazz(Ret (Class::*)(Args...) const);
785 
786  template <typename Class, typename Type> static Class *clazz(Type Class::*);
787 
788 public:
790  using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
791 };
792 
797 template <typename Member>
798 using member_class_t = typename member_class<Member>::type;
799 
805 template <std::size_t Index, auto Candidate> class nth_argument {
806  template <typename Ret, typename... Args>
807  static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
808 
809  template <typename Ret, typename Class, typename... Args>
810  static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
811 
812  template <typename Ret, typename Class, typename... Args>
813  static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
814 
815  template <typename Type, typename Class>
816  static constexpr type_list<Type> pick_up(Type Class ::*);
817 
818 public:
820  using type = type_list_element_t<Index, decltype(pick_up(Candidate))>;
821 };
822 
828 template <std::size_t Index, auto Candidate>
829 using nth_argument_t = typename nth_argument<Index, Candidate>::type;
830 
831 
832 
833 template<std::size_t N, typename Seq> struct offset_sequence;
834 
835 template<std::size_t N, std::size_t... Ints>
836 struct offset_sequence<N, std::index_sequence<Ints...>>
837 {
838  using type = std::index_sequence<Ints + N...>;
839 };
845 template<std::size_t N, typename Seq>
846 using offset_sequence_t = typename offset_sequence<N, Seq>::type;
847 
856 template <typename T, T... S, typename F>
857 constexpr void for_sequence(std::integer_sequence<T, S...>, F &&f) {
858  using unpack_t = int[];
859  (void)unpack_t{(static_cast<void>(f(std::integral_constant<T, S>{})), 0)...,
860  0};
861 }
862 
863 
870 template <typename T, typename = void>
871 struct is_from_chars_convertible : std::false_type {};
872 
878 template <typename T>
880  T, std::void_t<decltype(std::from_chars(std::declval<const char *>(),
881  std::declval<const char *>(),
882  std::declval<T &>()))>>
883  : std::true_type {};
884 
885 } // namespace mpl
Get first type in provided type_list<>
Definition: type_traits.h:414
Definition: type_traits.h:20
Same as std::is_invocable_r, but with tuples for arguments.
Definition: type_traits.h:562
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:286
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:432
std::remove_const_t< To > type
The type resulting from the transcription of the constness.
Definition: type_traits.h:755
Definition: testIterator.cpp:9
type_list_cat_t< std::conditional_t< type_list_contains_v< type_list< Other... >, Type >, type_list<>, type_list< Type > >... > type
A type list that is the difference between the two type lists.
Definition: type_traits.h:355
Extracts the n-th argument of a given function or member function.
Definition: type_traits.h:805
std::conditional_t<(std::is_same_v< Type, Other >||...), typename type_list_unique< type_list< Other... > >::type, type_list_cat_t< type_list< Type >, typename type_list_unique< type_list< Other... > >::type > > type
A type list without duplicate types.
Definition: type_traits.h:300
Definition: compressed_pair.h:255
A type-only sizeof wrapper that returns 0 where sizeof complains.
Definition: type_traits.h:94
First type
Searched type.
Definition: type_traits.h:170
Provides the member constant value to true if a given type is complete, false otherwise.
Definition: type_traits.h:592
Definition: type_traits.h:833
Identity type trait.
Definition: type_traits.h:48
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:248
Definition: type_traits.h:79
Append a type at the begining of the type_list.
Definition: type_traits.h:405
const To type
The type resulting from the transcription of the constness.
Definition: type_traits.h:761
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:477
Provides the member constant value to true if a given type is both an empty and non-final class...
Definition: type_traits.h:646
Extracts the class of a non-static member object or function.
Definition: type_traits.h:776
Default detection pattern template for std::from_chars.
Definition: type_traits.h:871
Definition: type_traits.h:688
Definition: type_traits.h:516
Provides the member constant value to true if Type::is_transparent is valid and denotes a type...
Definition: type_traits.h:663
A type trait that provides a const reference type for a given type.
Definition: type_traits.h:66
Transcribes the constness of a type to another type.
Definition: type_traits.h:753
type_list_element_t< Index, decltype(pick_up(Candidate))> type
N-th argument of the given function or member function.
Definition: type_traits.h:820
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:366
std::size_t value_type
Unsigned integer type.
Definition: type_traits.h:193
A class to use to push around lists of constant values, nothing more.
Definition: type_traits.h:424
Concatenates multiple type lists.
Definition: type_traits.h:251
Definition: type_traits.h:617
typename type_list_cat< type_list< Type..., Other... >, List... >::type type
A type list composed by the types of all the type lists.
Definition: type_traits.h:266
std::size_t value_type
Unsigned integer type.
Definition: type_traits.h:221
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:150
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:343
Utility class to disambiguate overloaded functions.
Definition: type_traits.h:26
Concatenates multiple value lists.
Definition: type_traits.h:480
typename value_list_cat< value_list< Value..., Other... >, List... >::type type
A value list composed by the values of all the value lists.
Definition: type_traits.h:495
std::size_t value_type
Unsigned integer type.
Definition: type_traits.h:210
reanme typelist
Definition: type_traits.h:393
Provides the member constant value to true if a given type is equality comparable, false otherwise.
Definition: type_traits.h:683
Provides the member constant value to true if a type list contains a given type, false otherwise...
Definition: type_traits.h:322
Alias template to facilitate the creation of named values.
Definition: type_traits.h:142
Same as std::is_invocable, but with tuples.
Definition: type_traits.h:530
Primary template isn&#39;t defined on purpose.
Definition: type_traits.h:182
Type type
Identity type.
Definition: type_traits.h:50
Utility class to disambiguate overloaded functions.
Definition: type_traits.h:32
std::remove_pointer_t< decltype(clazz(std::declval< Member >()))> type
The class of the given non-static member object or function.
Definition: type_traits.h:790
Provides the member constant value to true if a given type is an iterator, false otherwise.
Definition: type_traits.h:612