EnTT 3.11.0
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 <type_traits>
7#include <utility>
8#include "../config/config.h"
9#include "fwd.hpp"
10
11namespace entt {
12
17template<std::size_t N>
19 // Unfortunately, doxygen cannot parse such a construct.
20 : choice_t<N - 1>
21{};
22
24template<>
25struct choice_t<0> {};
26
31template<std::size_t N>
32inline constexpr choice_t<N> choice{};
33
42template<typename Type>
45 using type = Type;
46};
47
52template<typename Type>
54
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
254template<typename>
256
262template<typename Type, typename... Other>
263struct type_list_unique<type_list<Type, Other...>> {
265 using type = std::conditional_t<
266 (std::is_same_v<Type, Other> || ...),
267 typename type_list_unique<type_list<Other...>>::type,
269};
270
272template<>
276};
277
282template<typename Type>
284
291template<typename List, typename Type>
293
299template<typename... Type, typename Other>
300struct type_list_contains<type_list<Type...>, Other>: std::disjunction<std::is_same<Type, Other>...> {};
301
307template<typename List, typename Type>
309
311template<typename...>
313
319template<typename... Type, typename... Other>
320struct type_list_diff<type_list<Type...>, type_list<Other...>> {
322 using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
323};
324
329template<typename... List>
330using type_list_diff_t = typename type_list_diff<List...>::type;
331
333template<typename, template<typename...> class>
335
341template<typename... Type, template<typename...> class Op>
342struct type_list_transform<type_list<Type...>, Op> {
345};
346
352template<typename List, template<typename...> class Op>
354
359template<auto... Value>
364 static constexpr auto size = sizeof...(Value);
365};
366
368template<std::size_t, typename>
370
377template<std::size_t Index, auto Value, auto... Other>
378struct value_list_element<Index, value_list<Value, Other...>>
379 : value_list_element<Index - 1u, value_list<Other...>> {};
380
386template<auto Value, auto... Other>
387struct value_list_element<0u, value_list<Value, Other...>> {
389 static constexpr auto value = Value;
390};
391
397template<std::size_t Index, typename List>
399
406template<auto... Value, auto... Other>
408 return {};
409}
410
412template<typename...>
414
416template<>
420};
421
428template<auto... Value, auto... Other, typename... List>
429struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
431 using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
432};
433
438template<auto... Value>
439struct value_list_cat<value_list<Value...>> {
441 using type = value_list<Value...>;
442};
443
448template<typename... List>
449using value_list_cat_t = typename value_list_cat<List...>::type;
450
452template<typename, typename>
453struct is_applicable: std::false_type {};
454
461template<typename Func, template<typename...> class Tuple, typename... Args>
462struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
463
470template<typename Func, template<typename...> class Tuple, typename... Args>
471struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
472
478template<typename Func, typename Args>
480
482template<typename, typename, typename>
483struct is_applicable_r: std::false_type {};
484
492template<typename Ret, typename Func, typename... Args>
493struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
494
502template<typename Ret, typename Func, typename Args>
504
510template<typename Type, typename = void>
511struct is_complete: std::false_type {};
512
514template<typename Type>
515struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
516
521template<typename Type>
523
529template<typename Type, typename = void>
530struct is_iterator: std::false_type {};
531
537namespace internal {
538
539template<typename, typename = void>
540struct has_iterator_category: std::false_type {};
541
542template<typename Type>
543struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
544
545} // namespace internal
546
553template<typename Type>
554struct is_iterator<Type, std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_pointer_t<Type>>, void>>>
555 : internal::has_iterator_category<Type> {};
556
561template<typename Type>
563
569template<typename Type>
571 : std::conjunction<std::is_empty<Type>, std::negation<std::is_final<Type>>> {};
572
577template<typename Type>
579
585template<typename Type, typename = void>
586struct is_transparent: std::false_type {};
587
589template<typename Type>
590struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
591
596template<typename Type>
598
604template<typename Type, typename = void>
605struct is_equality_comparable: std::false_type {};
606
612namespace internal {
613
614template<typename, typename = void>
615struct has_tuple_size_value: std::false_type {};
616
617template<typename Type>
618struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
619
620template<typename Type, std::size_t... Index>
621[[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
622 return (is_equality_comparable<std::tuple_element_t<Index, Type>>::value && ...);
623}
624
625template<typename>
626[[nodiscard]] constexpr bool maybe_equality_comparable(choice_t<0>) {
627 return true;
628}
629
630template<typename Type>
631[[nodiscard]] constexpr auto maybe_equality_comparable(choice_t<1>) -> decltype(std::declval<typename Type::value_type>(), bool{}) {
632 if constexpr(is_iterator_v<Type>) {
633 return true;
634 } else if constexpr(std::is_same_v<typename Type::value_type, Type>) {
635 return maybe_equality_comparable<Type>(choice<0>);
636 } else {
637 return is_equality_comparable<typename Type::value_type>::value;
638 }
639}
640
641template<typename Type>
642[[nodiscard]] constexpr std::enable_if_t<is_complete_v<std::tuple_size<std::remove_cv_t<Type>>>, bool> maybe_equality_comparable(choice_t<2>) {
643 if constexpr(has_tuple_size_value<Type>::value) {
644 return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
645 } else {
646 return maybe_equality_comparable<Type>(choice<1>);
647 }
648}
649
650} // namespace internal
651
658template<typename Type>
659struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
660 : std::bool_constant<internal::maybe_equality_comparable<Type>(choice<2>)> {};
661
666template<typename Type>
668
674template<typename To, typename From>
677 using type = std::remove_const_t<To>;
678};
679
681template<typename To, typename From>
682struct constness_as<To, const From> {
684 using type = const To;
685};
686
692template<typename To, typename From>
694
699template<typename Member>
701 static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
702
703 template<typename Class, typename Ret, typename... Args>
704 static Class *clazz(Ret (Class::*)(Args...));
705
706 template<typename Class, typename Ret, typename... Args>
707 static Class *clazz(Ret (Class::*)(Args...) const);
708
709 template<typename Class, typename Type>
710 static Class *clazz(Type Class::*);
711
712public:
714 using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
715};
716
721template<typename Member>
723
729template<std::size_t Index, auto Candidate>
731 template<typename Ret, typename... Args>
732 static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
733
734 template<typename Ret, typename Class, typename... Args>
735 static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
736
737 template<typename Ret, typename Class, typename... Args>
738 static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
739
740 template<typename Type, typename Class>
741 static constexpr type_list<Type> pick_up(Type Class ::*);
742
743public:
745 using type = type_list_element_t<Index, decltype(pick_up(Candidate))>;
746};
747
753template<std::size_t Index, auto Candidate>
755
756} // namespace entt
757
758#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 given function or member function.
type_list_element_t< Index, decltype(pick_up(Candidate))> type
N-th argument of the given function or member function.
EnTT default namespace.
Definition: dense_map.hpp:21
constexpr bool is_equality_comparable_v
Helper variable template.
constexpr choice_t< N > choice
Variable template for the choice trick.
Definition: type_traits.hpp:32
typename type_identity< Type >::type type_identity_t
Helper type.
Definition: type_traits.hpp:53
std::integral_constant< decltype(Value), Value > integral_constant
Wraps a static constant.
Definition: type_traits.hpp:96
typename value_list_cat< List... >::type value_list_cat_t
Helper type.
constexpr std::size_t size_of_v
Helper variable template.
Definition: type_traits.hpp:73
constexpr std::size_t type_list_index_v
Helper variable template.
constexpr bool is_iterator_v
Helper variable template.
typename member_class< Member >::type member_class_t
Helper type.
constexpr auto value_list_element_v
Helper type.
typename type_list_transform< List, Op >::type type_list_transform_t
Helper type.
constexpr bool is_applicable_v
Helper variable template.
typename type_list_cat< List... >::type type_list_cat_t
Helper type.
constexpr bool is_transparent_v
Helper variable template.
typename type_list_unique< Type >::type type_list_unique_t
Helper type.
typename constness_as< To, From >::type constness_as_t
Alias template to facilitate the transcription of the constness.
constexpr bool is_complete_v
Helper variable template.
constexpr bool type_list_contains_v
Helper variable template.
integral_constant< Value > tag
Alias template to facilitate the creation of named values.
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
typename type_list_element< Index, List >::type type_list_element_t
Helper type.
typename nth_argument< Index, Candidate >::type nth_argument_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...
Definition: type_traits.hpp:81
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...
Definition: type_traits.hpp:89
typename type_list_diff< List... >::type type_list_diff_t
Helper type.
constexpr bool is_ebco_eligible_v
Helper variable template.
Utility class to disambiguate overloaded functions.
Definition: type_traits.hpp:21
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.
Definition: type_traits.hpp:61
Identity type trait.
Definition: type_traits.hpp:43
Type type
Identity type.
Definition: type_traits.hpp:45
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.
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.
Primary template isn't defined on purpose.
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.
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.