EnTT 3.14.0
Loading...
Searching...
No Matches
type_traits.hpp
1#ifndef ENTT_CORE_TYPE_TRAITS_HPP
2#define ENTT_CORE_TYPE_TRAITS_HPP
3
4#include <cstddef>
5#include <iterator>
6#include <tuple>
7#include <type_traits>
8#include <utility>
9#include "../config/config.h"
10#include "fwd.hpp"
11
12namespace entt {
13
18template<std::size_t N>
20 // unfortunately, doxygen cannot parse such a construct
21 : choice_t<N - 1>
22{};
23
25template<>
26struct choice_t<0> {};
27
32template<std::size_t N>
33inline constexpr choice_t<N> choice{};
34
43template<typename Type>
46 using type = Type;
47};
48
53template<typename Type>
55
60template<typename Type, typename = void>
61struct size_of: std::integral_constant<std::size_t, 0u> {};
62
64template<typename Type>
65struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
66 : std::integral_constant<std::size_t, sizeof(Type)> {};
67
72template<typename Type>
73inline constexpr std::size_t size_of_v = size_of<Type>::value;
74
80template<typename Type, typename>
81using unpack_as_type = Type;
82
88template<auto Value, typename>
89inline constexpr auto unpack_as_value = Value;
90
95template<auto Value>
96using integral_constant = std::integral_constant<decltype(Value), Value>;
97
102template<id_type Value>
104
109template<typename... Type>
110struct type_list {
114 static constexpr auto size = sizeof...(Type);
115};
116
118template<std::size_t, typename>
120
127template<std::size_t Index, typename First, typename... Other>
128struct type_list_element<Index, type_list<First, Other...>>
129 : type_list_element<Index - 1u, type_list<Other...>> {};
130
136template<typename First, typename... Other>
137struct type_list_element<0u, type_list<First, Other...>> {
139 using type = First;
140};
141
147template<std::size_t Index, typename List>
149
151template<typename, typename>
153
160template<typename Type, typename First, typename... Other>
161struct type_list_index<Type, type_list<First, Other...>> {
163 using value_type = std::size_t;
165 static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
166};
167
173template<typename Type, typename... Other>
174struct type_list_index<Type, type_list<Type, Other...>> {
175 static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
177 using value_type = std::size_t;
179 static constexpr value_type value = 0u;
180};
181
186template<typename Type>
187struct type_list_index<Type, type_list<>> {
189 using value_type = std::size_t;
191 static constexpr value_type value = 0u;
192};
193
199template<typename Type, typename List>
201
208template<typename... Type, typename... Other>
210 return {};
211}
212
214template<typename...>
216
218template<>
222};
223
230template<typename... Type, typename... Other, typename... List>
231struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
233 using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
234};
235
240template<typename... Type>
241struct type_list_cat<type_list<Type...>> {
243 using type = type_list<Type...>;
244};
245
250template<typename... List>
251using type_list_cat_t = typename type_list_cat<List...>::type;
252
254namespace internal {
255
256template<typename...>
257struct type_list_unique;
258
259template<typename First, typename... Other, typename... Type>
260struct type_list_unique<type_list<First, Other...>, Type...>
261 : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
262
263template<typename... Type>
264struct type_list_unique<type_list<>, Type...> {
265 using type = type_list<Type...>;
266};
267
268} // namespace internal
275template<typename List>
278 using type = typename internal::type_list_unique<List>::type;
279};
280
285template<typename List>
287
294template<typename List, typename Type>
296
302template<typename... Type, typename Other>
303struct type_list_contains<type_list<Type...>, Other>
304 : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
305
311template<typename List, typename Type>
313
315template<typename...>
317
323template<typename... Type, typename... Other>
324struct type_list_diff<type_list<Type...>, type_list<Other...>> {
326 using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
327};
328
333template<typename... List>
334using type_list_diff_t = typename type_list_diff<List...>::type;
335
337template<typename, template<typename...> class>
339
345template<typename... Type, template<typename...> class Op>
350
356template<typename List, template<typename...> class Op>
358
363template<auto... Value>
368 static constexpr auto size = sizeof...(Value);
369};
370
372template<std::size_t, typename>
374
381template<std::size_t Index, auto Value, auto... Other>
382struct value_list_element<Index, value_list<Value, Other...>>
383 : value_list_element<Index - 1u, value_list<Other...>> {};
384
390template<auto Value, auto... Other>
391struct value_list_element<0u, value_list<Value, Other...>> {
393 using type = decltype(Value);
395 static constexpr auto value = Value;
396};
397
403template<std::size_t Index, typename List>
405
411template<std::size_t Index, typename List>
413
415template<auto, typename>
417
424template<auto Value, auto First, auto... Other>
425struct value_list_index<Value, value_list<First, Other...>> {
427 using value_type = std::size_t;
429 static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
430};
431
437template<auto Value, auto... Other>
438struct value_list_index<Value, value_list<Value, Other...>> {
439 static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
441 using value_type = std::size_t;
443 static constexpr value_type value = 0u;
444};
445
450template<auto Value>
451struct value_list_index<Value, value_list<>> {
453 using value_type = std::size_t;
455 static constexpr value_type value = 0u;
456};
457
463template<auto Value, typename List>
465
472template<auto... Value, auto... Other>
474 return {};
475}
476
478template<typename...>
480
482template<>
486};
487
494template<auto... Value, auto... Other, typename... List>
495struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
497 using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
498};
499
504template<auto... Value>
505struct value_list_cat<value_list<Value...>> {
507 using type = value_list<Value...>;
508};
509
514template<typename... List>
515using value_list_cat_t = typename value_list_cat<List...>::type;
516
518template<typename>
520
526template<auto Value, auto... Other>
527struct value_list_unique<value_list<Value, Other...>> {
529 using type = std::conditional_t<
530 ((Value == Other) || ...),
531 typename value_list_unique<value_list<Other...>>::type,
533};
534
536template<>
541
546template<typename Type>
548
555template<typename List, auto Value>
557
563template<auto... Value, auto Other>
564struct value_list_contains<value_list<Value...>, Other>
565 : std::bool_constant<((Value == Other) || ...)> {};
566
572template<typename List, auto Value>
574
576template<typename...>
578
584template<auto... Value, auto... Other>
585struct value_list_diff<value_list<Value...>, value_list<Other...>> {
587 using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
588};
589
594template<typename... List>
595using value_list_diff_t = typename value_list_diff<List...>::type;
596
598template<typename, typename>
599struct is_applicable: std::false_type {};
600
607template<typename Func, template<typename...> class Tuple, typename... Args>
608struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
609
616template<typename Func, template<typename...> class Tuple, typename... Args>
617struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
618
624template<typename Func, typename Args>
626
628template<typename, typename, typename>
629struct is_applicable_r: std::false_type {};
630
638template<typename Ret, typename Func, typename... Args>
639struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
640
648template<typename Ret, typename Func, typename Args>
650
656template<typename Type, typename = void>
657struct is_complete: std::false_type {};
658
660template<typename Type>
661struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
662
667template<typename Type>
669
675template<typename Type, typename = void>
676struct is_iterator: std::false_type {};
677
679namespace internal {
680
681template<typename, typename = void>
682struct has_iterator_category: std::false_type {};
683
684template<typename Type>
685struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
686
687} // namespace internal
691template<typename Type>
692struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_cv_t<std::remove_pointer_t<Type>>>>>
693 : internal::has_iterator_category<Type> {};
694
699template<typename Type>
701
707template<typename Type>
709 : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
710
715template<typename Type>
717
723template<typename Type, typename = void>
724struct is_transparent: std::false_type {};
725
727template<typename Type>
728struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
729
734template<typename Type>
736
738namespace internal {
739
740template<typename, typename = void>
741struct has_tuple_size_value: std::false_type {};
742
743template<typename Type>
744struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
745
746template<typename, typename = void>
747struct has_value_type: std::false_type {};
748
749template<typename Type>
750struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
751
752template<typename>
753[[nodiscard]] constexpr bool dispatch_is_equality_comparable();
754
755template<typename Type, std::size_t... Index>
756[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
757 return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
758}
759
760template<typename>
761[[nodiscard]] constexpr bool maybe_equality_comparable(char) {
762 return false;
763}
764
765template<typename Type>
766[[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
767 return true;
768}
769
770template<typename Type>
771[[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
772 // NOLINTBEGIN(modernize-use-transparent-functors)
773 if constexpr(std::is_array_v<Type>) {
774 return false;
775 } else if constexpr(!is_iterator_v<Type> && has_value_type<Type>::value) {
776 if constexpr(std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
777 return maybe_equality_comparable<Type>(0);
778 } else {
779 return false;
780 }
781 } else if constexpr(is_complete_v<std::tuple_size<std::remove_cv_t<Type>>>) {
782 if constexpr(has_tuple_size_value<Type>::value) {
783 return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
784 } else {
785 return maybe_equality_comparable<Type>(0);
786 }
787 } else {
788 return maybe_equality_comparable<Type>(0);
789 }
790 // NOLINTEND(modernize-use-transparent-functors)
791}
792
793} // namespace internal
801template<typename Type>
802struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
803
805template<typename Type>
807
812template<typename Type>
814
820template<typename To, typename From>
823 using type = std::remove_const_t<To>;
824};
825
827template<typename To, typename From>
828struct constness_as<To, const From> {
830 using type = const To;
831};
832
838template<typename To, typename From>
840
845template<typename Member>
847 static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
848
849 template<typename Class, typename Ret, typename... Args>
850 static Class *clazz(Ret (Class::*)(Args...));
851
852 template<typename Class, typename Ret, typename... Args>
853 static Class *clazz(Ret (Class::*)(Args...) const);
854
855 template<typename Class, typename Type>
856 static Class *clazz(Type Class::*);
857
858public:
860 using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
861};
862
867template<typename Member>
869
875template<std::size_t Index, typename Candidate>
877 template<typename Ret, typename... Args>
878 static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
879
880 template<typename Ret, typename Class, typename... Args>
881 static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
882
883 template<typename Ret, typename Class, typename... Args>
884 static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
885
886 template<typename Type, typename Class>
887 static constexpr type_list<Type> pick_up(Type Class ::*);
888
889 template<typename Type>
890 static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
891
892public:
895};
896
902template<std::size_t Index, typename Candidate>
904
905} // namespace entt
906
907template<typename... Type>
908struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
909
910template<std::size_t Index, typename... Type>
911struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
912
913template<auto... Value>
914struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
915
916template<std::size_t Index, auto... Value>
917struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
918
919#endif
Extracts the class of a non-static member object or function.
std::remove_pointer_t< decltype(clazz(std::declval< Member >()))> type
The class of the given non-static member object or function.
Extracts the n-th argument of a callable type.
type_list_element_t< Index, decltype(pick_up(std::declval< Candidate >()))> type
N-th argument of the callable type.
EnTT default namespace.
Definition dense_map.hpp:22
typename member_class< Member >::type member_class_t
Helper type.
constexpr bool is_equality_comparable_v
Helper variable template.
constexpr choice_t< N > choice
Variable template for the choice trick.
std::integral_constant< decltype(Value), Value > integral_constant
Wraps a static constant.
typename constness_as< To, From >::type constness_as_t
Alias template to facilitate the transcription of the constness.
constexpr std::size_t size_of_v
Helper variable template.
typename nth_argument< Index, Candidate >::type nth_argument_t
Helper type.
typename type_list_cat< List... >::type type_list_cat_t
Helper type.
typename type_list_transform< List, Op >::type type_list_transform_t
Helper type.
typename value_list_unique< Type >::type value_list_unique_t
Helper type.
constexpr std::size_t type_list_index_v
Helper variable template.
constexpr bool is_iterator_v
Helper variable template.
typename value_list_cat< List... >::type value_list_cat_t
Helper type.
constexpr auto value_list_element_v
Helper type.
typename type_list_diff< List... >::type type_list_diff_t
Helper type.
constexpr bool is_applicable_v
Helper variable template.
constexpr bool is_transparent_v
Helper variable template.
typename type_identity< Type >::type type_identity_t
Helper type.
constexpr bool is_complete_v
Helper variable template.
constexpr bool type_list_contains_v
Helper variable template.
typename type_list_element< Index, List >::type type_list_element_t
Helper type.
constexpr std::size_t value_list_index_v
Helper variable template.
typename type_list_unique< List >::type type_list_unique_t
Helper type.
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
typename value_list_element< Index, List >::type value_list_element_t
Helper type.
constexpr bool value_list_contains_v
Helper variable template.
typename value_list_diff< List... >::type value_list_diff_t
Helper type.
Type unpack_as_type
Using declaration to be used to repeat the same type a number of times equal to the size of a given p...
integral_constant< Value > tag
Alias template to facilitate the creation of named values.
constexpr bool is_applicable_r_v
Helper variable template.
constexpr auto unpack_as_value
Helper variable template to be used to repeat the same value a number of times equal to the size of a...
constexpr bool is_ebco_eligible_v
Helper variable template.
Utility class to disambiguate overloaded functions.
const To type
The type resulting from the transcription of the constness.
Transcribes the constness of a type to another type.
std::remove_const_t< To > type
The type resulting from the transcription of the constness.
Same as std::is_invocable_r, but with tuples for arguments.
Same as std::is_invocable, but with tuples.
Provides the member constant value to true if a given type is complete, false otherwise.
Provides the member constant value to true if a given type is both an empty and non-final class,...
Provides the member constant value to true if a given type is equality comparable,...
Provides the member constant value to true if a given type is an iterator, false otherwise.
Provides the member constant value to true if Type::is_transparent is valid and denotes a type,...
A type-only sizeof wrapper that returns 0 where sizeof complains.
Identity type trait.
Type type
Identity type.
typename type_list_cat< type_list< Type..., Other... >, List... >::type type
A type list composed by the types of all the type lists.
Concatenates multiple type lists.
Primary template isn't defined on purpose.
Provides the member constant value to true if a type list contains a given type, false otherwise.
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.
Primary template isn't defined on purpose.
Primary template isn't defined on purpose.
std::size_t value_type
Unsigned integer type.
Primary template isn't defined on purpose.
Primary template isn't defined on purpose.
Removes duplicates types from a type list.
typename internal::type_list_unique< List >::type type
A type list without duplicate types.
A class to use to push around lists of types, nothing more.
static constexpr auto size
Compile-time number of elements in the type list.
typename value_list_cat< value_list< Value..., Other... >, List... >::type type
A value list composed by the values of all the value lists.
Concatenates multiple value lists.
Primary template isn't defined on purpose.
Provides the member constant value to true if a value list contains a given value,...
value_list_cat_t< std::conditional_t< value_list_contains_v< value_list< Other... >, Value >, value_list<>, value_list< Value > >... > type
A value list that is the difference between the two value lists.
Primary template isn't defined on purpose.
Primary template isn't defined on purpose.
std::size_t value_type
Unsigned integer type.
Primary template isn't defined on purpose.
std::conditional_t<((Value==Other)||...), typename value_list_unique< value_list< Other... > >::type, value_list_cat_t< value_list< Value >, typename value_list_unique< value_list< Other... > >::type > > type
A value list without duplicate types.
Primary template isn't defined on purpose.
A class to use to push around lists of constant values, nothing more.
static constexpr auto size
Compile-time number of elements in the value list.