1 #ifndef _TYPETRAITS_HPP 2 #define _TYPETRAITS_HPP 13 #include <type_traits> 16 #include <metaprogramming/SwallowSemicolon.hpp> 35 #define NON_CONST_QUALIF 55 #define FORBID_CONSTRUCT_BY_COPY(CLASS) 108 template <
typename T>
110 static constexpr
bool isClass=
114 template <
typename From,
117 static constexpr
bool canBeConverted=
118 std::is_convertible_v<From,To>;
121 template <
typename T>
123 static constexpr
bool isTriviallyCopyable=
124 std::is_trivially_copyable_v<T>;
131 template <
typename T1,
134 static constexpr
bool isSame=
140 template <
typename T>
141 static constexpr
bool isSame<T,T> =
149 template <
typename T=
void,
151 constexpr
bool _areSame()
153 if constexpr(
sizeof...(Tail)==0)
156 return (isSame<T,Tail> && ...);
162 template <
typename...Ts>
164 constexpr
bool areSame=
168 #define STATIC_ASSERT_ARE_SAME(...) 169 static_assert(areSame<__VA_ARGS__>,"Error, types are not the same") 172 template <
class...Args>
191 template <
typename T,
193 struct _Conditional<
true,T,F>
202 template <
typename T,
204 struct _Conditional<
false,T,F>
217 typename _Conditional<B,T,F>::type;
222 template <
typename T>
224 typename std::remove_reference<T>::type;
227 template <
typename T>
230 std::is_lvalue_reference<T>::value;
233 template <
typename T>
236 std::is_rvalue_reference<T>::value;
241 typename T=RemRef<_T>>
248 template <
typename T>
250 typename std::remove_cv<T>::type;
255 template <
typename _T,
256 typename T=RemRef<_T>>
258 constexpr
bool isConst=
259 not isSame<RemoveCV<T>,T>;
264 typename T=RemoveCV<_T>>
266 Conditional<B,
const T,T>;
269 template <
typename T>
276 template <
typename T>
278 static constexpr
bool isPointer=
279 std::is_pointer_v<T>;
286 template <
typename T>
287 constexpr
auto fundamentalHelper()
289 if constexpr(isConst<T>)
291 fundamentalHelper<RemoveCV<T>>();
293 if constexpr(isPointer<T>)
295 fundamentalHelper<std::remove_pointer_t<T>>();
302 template <
typename T>
304 decltype(fundamentalHelper<T>());
309 template <
typename Base,
313 std::is_base_of<Base,RemRef<Derived>>::value;
318 template <
typename F>
321 std::is_function_v<F>;
324 template <
typename F>
326 std::add_pointer_t<F>;
329 template <
typename F>
330 using AddPointerIfFunction=
331 Conditional<isFunction<F>,
341 template <
typename T>
342 constexpr T& asMutable(
const T& v) noexcept
344 return const_cast<T&>(v);
352 #define CALL_CLASS_CONST_METHOD_REMOVING_CONST(...) 353 asMutable(std::as_const(*this).__VA_ARGS__) 376 #define PROVIDE_ALSO_NON_CONST_METHOD(NAME) 378 template <typename...Ts> 388 #define STATIC_ASSERT_IS_BASE_OF(BASE,DERIVED) 389 static_assert(isBaseOf<BASE,DERIVED>,"Error, type not derived from what expected") 392 #define STATIC_ASSERT_IS_NOT_BASE_OF(BASE,DERIVED) 393 static_assert(not isBaseOf<BASE,DERIVED>,"Error, type derived from what not expected") 396 template <
typename Base,
398 struct ConstrainIsBaseOf
408 template <
typename Base,
422 #define STATIC_ASSERT_ARE_N_TYPES(N,UNEXP_PARPACK) 423 static_assert(N==sizeof...(UNEXP_PARPACK),"Error, expecting a different number of types") 436 template <
typename T>
441 #define STATIC_ASSERT_IS_FLOATING_POINT(T) 442 static_assert(isFloatingPoint<T>,"Error, type is not a floating point") 445 template <
typename T>
454 template <
typename T>
456 constexpr
bool isIntegral=std::is_integral<T>::value;
459 #define STATIC_ASSERT_IS_INTEGRAL(T) 460 static_assert(isIntegral<T>,"Error, type is not an integral") 463 template <
typename T>
472 template <
typename Head=
int,
476 areIntegrals<Head>
and areIntegrals<Tail...>;
479 template <
typename T>
480 constexpr
bool areIntegrals<T> =
484 #define STATIC_ASSERT_ARE_INTEGRALS(...) 485 static_assert(areIntegrals<__VA_ARGS__>,"Error, types are not all an integral") 488 template <
typename...Args>
500 #define PROVIDE_ENABLE_IF_FOR(TYPE, 503 template <typename T, 505 using EnableIfIs ## TYPE= 506 EnableIf<__VA_ARGS__,Ret> 509 #define PROVIDE_ENABLE_IF_FOR_IS_TYPE(TYPE) 514 #define PROVIDE_ENABLE_IF_FOR_TYPE(TYPE) 526 #define DEFINE_BASE_TYPE(TYPE,...) 527 struct Base ## TYPE __VA_ARGS__ {}; 530 template <typename T> 532 constexpr bool is ## TYPE= 533 isBaseOf<Base ## TYPE,T>; 538 template <typename T> 539 using ConstrainIs ## TYPE= 540 ConstrainIsBaseOf<Base ## TYPE,T>; 543 template <typename T> 544 using ConstrainIsNot ## TYPE= 545 ConstrainIsNotBaseOf<Base ## TYPE,T>; 548 template <typename...Args> 549 struct ConstrainAre ## TYPE ## s 551 static_assert((is ## TYPE<Args> && ...), 552 "Error, types are not all " #TYPE); 560 #define STATIC_ASSERT_HAS_MEMBER(TAG,...) 561 static_assert(hasMember_ ## TAG<__VA_ARGS__>,"Type does not have member " #TAG) 581 #define DEFINE_HAS_MEMBER(TAG) 585 template <typename Type> 586 struct HasMember_ ## TAG 611 template <typename U, 619 template <typename U> 620 static No& test(Check<int Fallback::*,&U::TAG>*); 626 template <typename U> 627 static Yes& test(...); 632 static constexpr bool result= 633 sizeof(test<Derived>(nullptr))==sizeof(Yes); 637 template <typename Type> 639 constexpr bool hasMember_ ## TAG ## Helper() 641 if constexpr(isClass<Type>) 643 HasMember_ ## TAG<Type>::result; 652 template <typename Type> 654 constexpr bool hasMember_ ## TAG= 655 hasMember_ ## TAG ## Helper<RemRef<Type>>(); 658 template <typename T> 659 struct ConstrainHasMember_ ## TAG 667 #define DEFINE_BINARY_OPERATOR_IMPLEMENTATION_CHECK(CHECK_NAME, 671 template <typename S, 676 template <typename U, 678 static auto test(U*)->decltype(std::declval<U>() 685 static auto test(...)->std::false_type; 688 static constexpr bool res= 689 not isSame<std::false_type,decltype(test<S,T>(0
))>; 693 template <typename S, 696 constexpr bool CHECK_NAME= 697 STRUCT_NAME<S,T>::res 704 template <
typename T>
706 RefIf<isLvalue<T>,std::make_signed_t<RemRef<T>>>;
709 template <
typename T>
711 RefIf<isLvalue<T>,std::make_unsigned_t<RemRef<T>>>;
716 #define DEFINE_IS_THE_TEMPLATED_CLASS(CLASS) 720 template <typename T> 721 constexpr bool _is ## CLASS(const T*) 730 template <typename...Ts> 731 constexpr bool _is ## CLASS(const CLASS<Ts...>*) 740 template <typename T> 742 constexpr bool is ## CLASS= 743 _is ## CLASS((RemRef<T>*)nullptr); 755 template <
typename T>
758 hasMember_begin<T>
and 760 hasMember_resize<T>
and 780 template <
typename T>
781 constexpr
bool canBeGet()
784 using namespace internal;
787 not isSame<RemRef<decltype(get<0>(*
static_cast<RemRef<T>*>(nullptr)))>,FallTrhough>;
791 template <
typename T>
793 constexpr
bool isTupleLike=
constexpr bool isIntegral
Identifies whether a type is an integer-like.
#define STATIC_ASSERT_IS_BASE_OF(BASE, DERIVED)
Static assert if DERIVED does not derive from BASE.
#define DEFINE_HAS_MEMBER(TAG)
constexpr bool isRvalue
Check if the type is rvalue reference.
constexpr bool isFloatingPoint
Identifies whether a type is a floating-point.
#define STATIC_ASSERT_ARE_N_TYPES(N, UNEXP_PARPACK)
Static assert if not passing exactly N types.
Forces a set of types to be the same.
constexpr bool areIntegrals
Identifies whether a set of types are a integer-like.
constexpr bool isLvalue
Check if the type is lvalue reference.
#define DEFINE_BINARY_OPERATOR_IMPLEMENTATION_CHECK(CHECK_NAME,STRUCT_NAME, OPERATOR)
Check that the binary operator exists.
constexpr bool isBaseOf
Identifies whether Base is a base class of Derived.
#define PROVIDE_ENABLE_IF_FOR_IS_TYPE(TYPE)
Provides an EnableIf with the given name if isTYPE exists.
#define STATIC_ASSERT_IS_INTEGRAL(T)
Static assert if the type T is not an integer-like.
FallTrhough get(T)
Default getter.
Forces types to be in the given number.
#define CALL_CLASS_CONST_METHOD_REMOVING_CONST(...)
Call a const method removing any const qualifier.
Forces the type to be a floating-point.
#define STATIC_ASSERT_ARE_INTEGRALS(...)
Static assert if the types T are not an integer-like.
#define STATIC_ASSERT_ARE_SAME(...)
Assert if types are not the same.
Forces the type to be integer-like.
#define STATIC_ASSERT_IS_NOT_BASE_OF(BASE, DERIVED)
Static assert if DERIVED does derive from BASE.
constexpr bool isVectorLike
Check if the class T is vector-like.
Forces the type to be integer-like.
constexpr bool isFunction
Returns whether the passed argument is a function.
Forces type Derived not to be derived from Base.
#define DECLAUTO
Short name for decltype(auto)
#define STATIC_ASSERT_HAS_MEMBER(TAG,...)
Class returned from fall-through methods.
#define STATIC_ASSERT_IS_FLOATING_POINT(T)
Static assert if the type T is not a floating-point.
#define PROVIDE_ENABLE_IF_FOR(TYPE,...)