20#ifndef QB_TYPE_TRAITS_H
21#define QB_TYPE_TRAITS_H
35inline std::remove_reference_t<T> &&
37 return static_cast<std::remove_reference_t<T> &&
>(t);
49fwd(std::remove_reference_t<T> &t)
noexcept {
50 return std::forward<T>(t);
62fwd(std::remove_reference_t<T> &&t)
noexcept {
63 return std::forward<T>(t);
88 return static_cast<T &
>(*this);
98 return static_cast<T &
>(*this);
117 template <
typename C>
118 static yes &test(
typename C::const_iterator *);
119 template <
typename C>
120 static no &test(...);
123 static const bool value =
sizeof(test<T>(
nullptr)) ==
sizeof(yes);
137 template <
typename C>
139 f(
typename std::enable_if<std::is_same<
140 decltype(
static_cast<typename C::const_iterator (C::*)() const
>(&C::begin)),
141 typename C::const_iterator (C::*)()
const>::value>
::type *);
143 template <
typename C>
146 template <
typename C>
148 g(
typename std::enable_if<
150 decltype(
static_cast<typename C::const_iterator (C::*)() const
>(&C::end)),
151 typename C::const_iterator (C::*)()
const>::value,
154 template <
typename C>
159 static bool const beg_value =
sizeof(f<T>(
nullptr)) ==
sizeof(yes);
162 static bool const end_value =
sizeof(g<T>(
nullptr)) ==
sizeof(yes);
171template <
typename T,
typename U =
void>
182 typename T::key_type, typename T::mapped_type,
183 decltype(std::declval<T &>()[std::declval<const typename T::key_type &>()])>>
200 :
public std::integral_constant<bool, detail::has_const_iterator<T>::value &&
201 detail::has_begin_end<T>::beg_value &&
202 detail::has_begin_end<T>::end_value> {};
210template <
typename T, std::
size_t N>
218template <std::
size_t N>
235template <
typename T1,
typename T2>
243template <
typename... Args>
255template <
typename T,
bool cond>
260 constexpr static bool value =
false;
271 typedef typename std::remove_reference<T>::type
type;
295template <
typename...>
304template <
typename T,
typename U>
314template <
typename...>
326template <
typename T,
typename U = Vo
id<>>
336 T,
typename std::enable_if<!std::is_void<typename T::container_type>::value>
::type>
349template <
typename Iter,
typename T = Vo
id<>>
352 using type =
typename std::iterator_traits<Iter>::value_type;
362template <
typename Iter>
365 using type =
typename std::decay<typename Iter::container_type::value_type>::type;
378template <
typename Iter,
typename T = Vo
id<>>
386template <
typename Iter>
397template <
typename Iter>
399 typename std::enable_if<!std::is_void<
400 typename std::iterator_traits<Iter>::value_type>::value>
::type>
401 : std::integral_constant<bool, !std::is_convertible<Iter, std::string_view>::value> {
421template <
typename T,
typename = Vo
id<>>
431 T, typename std::enable_if<std::is_void<decltype(std::declval<T>().push_back(
432 std::declval<typename T::value_type>()))>::value>
::type> : std::true_type {};
441template <
typename T,
typename = Vo
id<>>
451 T, typename std::enable_if<std::is_same<
452 decltype(std::declval<T>().insert(std::declval<typename T::const_iterator>(),
453 std::declval<typename T::value_type>())),
454 typename T::iterator>::value>
::type> : std::true_type {};
465 : std::integral_constant<
466 bool, has_push_back<T>::value &&
467 !std::is_same<typename std::decay<T>::type, std::string>::value> {};
478 : std::integral_constant<bool, has_insert<T>::value && !has_push_back<T>::value> {};
488template <
size_t num,
typename... T>
501template <
size_t num,
typename T,
typename... Y>
513template <
typename T,
typename... Y>
526template <
size_t... Indexes>
528 enum { size =
sizeof...(Indexes) };
539template <
size_t num,
typename tp = indexes_tuple<>>
550template <
size_t num,
size_t... Indexes>
552 :
index_builder<num - 1, indexes_tuple<Indexes..., sizeof...(Indexes)>> {};
561template <
size_t... Indexes>
564 enum { size =
sizeof...(Indexes) };
591 template <
typename... U>
604template <
typename... Args>
615template <
typename A,
typename =
void>
635template <
typename T, T>
644template <
typename Alias,
typename AmbiguitySeed>
646 template <
typename C>
647 static char (&f(
decltype(&C::value)))[1];
648 template <
typename C>
649 static char (&f(...))[2];
653 (
sizeof(f<AmbiguitySeed>(0)) == 1),
654 "Member name specified in AmbiguitySeed is different from member name specified "
655 "in Alias, or wrong Alias/AmbiguitySeed has been specified.");
658 static bool const value =
sizeof(f<Alias>(0)) == 2;
669#define CREATE_MEMBER_CHECK(member) \
671 template <typename T, typename = std::true_type> \
672 struct Alias_##member; \
674 template <typename T> \
675 struct Alias_##member< \
676 T, std::integral_constant<bool, got_type<decltype(&T::member)>::value>> { \
677 static const decltype(&T::member) value; \
680 struct AmbiguitySeed_##member { \
684 template <typename T> \
685 struct has_member_##member { \
686 static const bool value = \
687 has_member<Alias_##member<ambiguate<T, AmbiguitySeed_##member>>, \
688 Alias_##member<AmbiguitySeed_##member>>::value; \
698#define CREATE_MEMBER_VAR_CHECK(var_name) \
700 template <typename T, typename = std::true_type> \
701 struct has_member_var_##var_name : std::false_type {}; \
703 template <typename T> \
704 struct has_member_var_##var_name< \
705 T, std::integral_constant< \
706 bool, !std::is_member_function_pointer<decltype(&T::var_name)>::value>> \
716#define CREATE_MEMBER_CLASS_CHECK(class_name) \
718 template <typename T, typename = std::true_type> \
719 struct has_member_class_##class_name : std::false_type {}; \
721 template <typename T> \
722 struct has_member_class_##class_name< \
723 T, std::integral_constant<bool, std::is_class<typename got_type< \
724 typename T::class_name>::type>::value>> \
734#define CREATE_MEMBER_UNION_CHECK(union_name) \
736 template <typename T, typename = std::true_type> \
737 struct has_member_union_##union_name : std::false_type {}; \
739 template <typename T> \
740 struct has_member_union_##union_name< \
741 T, std::integral_constant<bool, std::is_union<typename got_type< \
742 typename T::union_name>::type>::value>> \
752#define CREATE_MEMBER_ENUM_CHECK(enum_name) \
754 template <typename T, typename = std::true_type> \
755 struct has_member_enum_##enum_name : std::false_type {}; \
757 template <typename T> \
758 struct has_member_enum_##enum_name< \
760 std::integral_constant< \
761 bool, std::is_enum<typename got_type<typename T::enum_name>::type>::value>> \
772#define CREATE_MEMBER_FUNC_CHECK(func) \
773 template <typename T> \
774 struct has_member_func_##func { \
775 static const bool value = \
776 has_member_##func<T>::value && !has_member_var_##func<T>::value && \
777 !has_member_class_##func<T>::value && !has_member_union_##func<T>::value && \
778 !has_member_enum_##func<T>::value; \
788#define CREATE_MEMBER_CHECKS(member) \
789 CREATE_MEMBER_CHECK(member); \
790 CREATE_MEMBER_VAR_CHECK(member); \
791 CREATE_MEMBER_CLASS_CHECK(member); \
792 CREATE_MEMBER_UNION_CHECK(member); \
793 CREATE_MEMBER_ENUM_CHECK(member); \
794 CREATE_MEMBER_FUNC_CHECK(member)
804#define GENERATE_HAS_METHOD(method) \
806 template <typename C, typename Ret, typename... Args> \
807 class has_method_##method { \
808 template <typename T> \
809 static constexpr auto check(T *) -> typename std::is_same< \
810 decltype(std::declval<T>().method(std::declval<Args>()...)), Ret>::type; \
812 template <typename> \
813 static constexpr std::false_type check(...); \
815 typedef decltype(check<C>(0)) type; \
818 static constexpr bool value = type::value; \
829#define GENERATE_HAS_MEMBER(member) \
832 class HasMember_##member { \
834 using Yes = char[2]; \
835 using No = char[1]; \
845 static No &test(decltype(U::member) *); \
846 template <typename U> \
847 static Yes &test(U *); \
850 static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
854 struct has_member_##member \
855 : public std::integral_constant<bool, HasMember_##member<T>::RESULT> {};
865#define GENERATE_HAS_MEMBER_TYPE(Type) \
868 class HasMemberType_##Type { \
870 using Yes = char[2]; \
871 using No = char[1]; \
881 static No &test(typename U::Type *); \
882 template <typename U> \
883 static Yes &test(U *); \
886 static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
890 struct has_member_type_##Type \
891 : public std::integral_constant<bool, HasMemberType_##Type<T>::RESULT> {};
T && fwd(std::remove_reference_t< T > &t) noexcept
Alias for std::forward with a concise syntax (lvalue overload).
Definition type_traits.h:49
std::remove_reference_t< T > && mv(T &&t) noexcept
Alias for std::move with a concise syntax.
Definition type_traits.h:36
void Void
Helper alias to void for SFINAE purposes.
Definition type_traits.h:315
Helper class to force ambiguity of class members.
Definition type_traits.h:605
A type
The type that was found.
Definition type_traits.h:626
Type trait to check if a type exists.
Definition type_traits.h:616
Type trait to check if a type has a specific member.
Definition type_traits.h:645
static bool const value
Whether the member exists.
Definition type_traits.h:658
Base class for implementing the Curiously Recurring Template Pattern (CRTP).
Definition type_traits.h:80
T & impl() noexcept
Access the derived class instance.
Definition type_traits.h:87
T const & impl() const noexcept
Access the derived class instance (const version)
Definition type_traits.h:97
Type trait to detect whether T has begin() and end() methods.
Definition type_traits.h:135
static bool const beg_value
Whether the type has a valid begin() method.
Definition type_traits.h:159
static bool const end_value
Whether the type has a valid end() method.
Definition type_traits.h:162
Type trait to detect whether T has a const_iterator type.
Definition type_traits.h:115
Internal implementation to detect map-like types.
Definition type_traits.h:172
expand(U const &...)
Constructor that expands a parameter pack.
Definition type_traits.h:592
Type trait to check if a type T has an insert(T::const_iterator, T::value_type) member function.
Definition type_traits.h:442
Type trait to check if a type T has a push_back(T::value_type) member function.
Definition type_traits.h:422
indexes_tuple< Indexes... > type
The final tuple type with all indices.
Definition type_traits.h:563
Generates a compile-time sequence of indices as an indexes_tuple.
Definition type_traits.h:540
Represents a compile-time tuple of size_t indexes.
Definition type_traits.h:527
Type trait to check if type T is an associative container.
Definition type_traits.h:478
Type trait to check if a type T is a container.
Definition type_traits.h:202
Type trait to check if a type T is an inserter iterator (e.g., std::back_inserter).
Definition type_traits.h:327
Type trait to check if an iterator T points to map elements (i.e., std::pair).
Definition type_traits.h:412
Type trait to check if a type T is map-like.
Definition type_traits.h:286
Type trait to check if a type is a std::pair.
Definition type_traits.h:296
Type trait to check if type T is a sequence container.
Definition type_traits.h:467
Type trait to check if a type Iter is an iterator.
Definition type_traits.h:379
typename std::decay< typename Iter::container_type::value_type >::type type
The value type of the underlying container.
Definition type_traits.h:365
Type trait to extract the value_type from an iterator Iter.
Definition type_traits.h:350
typename std::iterator_traits< Iter >::value_type type
The value type of the iterator.
Definition type_traits.h:352
T type
The type at the specified index.
Definition type_traits.h:515
Metafunction for selecting the Nth type in a variadic template parameter pack.
Definition type_traits.h:489
static constexpr bool value
Whether reference was removed.
Definition type_traits.h:273
std::remove_reference< T >::type type
Resulting type with reference removed.
Definition type_traits.h:271
Conditionally removes a reference from type T if cond is true.
Definition type_traits.h:256
static constexpr bool value
Whether reference was removed.
Definition type_traits.h:260
T type
Resulting type (unchanged if condition is false)
Definition type_traits.h:258
Template struct used for type identification in the event system.
Definition Event.h:53
Helper for signature checking.
Definition type_traits.h:636
#define GENERATE_HAS_METHOD(method)
Macro to generate a type trait to check for a method with a specific signature.
Definition type_traits.h:804
#define CREATE_MEMBER_CHECKS(member)
Macro to create all member check variants for a single member name.
Definition type_traits.h:788