/* Type traits for OctaSTD. * * This file is part of OctaSTD. See COPYING.md for futher information. */ #ifndef OCTA_TRAITS_H #define OCTA_TRAITS_H #include #include "octa/types.h" #include "octa/utility.h" /* libc++ and cppreference.com occasionally used for reference */ /* missing: * * UnderlyingType */ namespace octa { /* removers */ template struct RemoveConst { typedef T type; }; template struct RemoveConst { typedef T type; }; template struct RemoveVolatile { typedef T type; }; template struct RemoveVolatile { typedef T type; }; template struct RemoveConstVolatile { typedef typename RemoveVolatile::type>::type type; }; /* integral constant */ template struct IntegralConstant { static constexpr const T value = val; typedef T value_type; typedef IntegralConstant type; constexpr operator value_type() const { return value; } constexpr value_type operator()() const { return value; } }; typedef IntegralConstant true_t; typedef IntegralConstant false_t; template constexpr const T IntegralConstant::value; /* is void */ template struct IsVoidBase : false_t {}; template< > struct IsVoidBase: true_t {}; template struct IsVoid: IsVoidBase::type> {}; /* is null pointer */ template struct IsNullPointerBase : false_t {}; template< > struct IsNullPointerBase: true_t {}; template struct IsNullPointer: IsNullPointerBase< typename RemoveConstVolatile::type > {}; /* is integer */ template struct IsIntegralBase: false_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template<> struct IsIntegralBase: true_t {}; template struct IsIntegral: IsIntegralBase::type> {}; /* is floating point */ template struct IsFloatingPointBase : false_t {}; template<> struct IsFloatingPointBase: true_t {}; template<> struct IsFloatingPointBase: true_t {}; template<> struct IsFloatingPointBase: true_t {}; template struct IsFloatingPoint: IsFloatingPointBase::type> {}; /* is array */ template struct IsArray : false_t {}; template struct IsArray: true_t {}; template struct IsArray: true_t {}; /* is pointer */ template struct IsPointerBase : false_t {}; template struct IsPointerBase: true_t {}; template struct IsPointer: IsPointerBase::type> {}; /* is lvalue reference */ template struct IsLvalueReference : false_t {}; template struct IsLvalueReference: true_t {}; /* is rvalue reference */ template struct IsRvalueReference : false_t {}; template struct IsRvalueReference: true_t {}; /* is enum */ template struct IsEnum: IntegralConstant {}; /* is union */ template struct IsUnion: IntegralConstant {}; /* is class */ template struct IsClass: IntegralConstant {}; /* is function */ template struct IsReference; namespace internal { struct FunctionTestDummy {}; template char function_test(T *); template char function_test(FunctionTestDummy); template int function_test(...); template T &function_source(int); template FunctionTestDummy function_source(...); } template::value || IsUnion::value || IsVoid::value || IsReference::value || IsNullPointer::value > struct IsFunctionBase: IntegralConstant(internal::function_source(0))) == 1 > {}; template struct IsFunctionBase: false_t {}; template struct IsFunction: IsFunctionBase {}; /* is arithmetic */ template struct IsArithmetic: IntegralConstant::value || IsFloatingPoint::value) > {}; /* is fundamental */ template struct IsFundamental: IntegralConstant::value || IsVoid::value || IsNullPointer::value) > {}; /* is compound */ template struct IsCompound: IntegralConstant::value > {}; /* is pointer to member function */ template struct IsMemberFunctionPointer: true_t {}; /* is pointer to member */ template struct IsMemberPointerBase: false_t {}; template struct IsMemberPointerBase: true_t {}; template struct IsMemberPointer: IsMemberPointerBase< typename RemoveConstVolatile::type > {}; /* is pointer to member object */ template struct IsMemberObjectPointer: IntegralConstant::value && !IsMemberFunctionPointer::value) > {}; /* is reference */ template struct IsReference: IntegralConstant::value || IsRvalueReference::value) > {}; /* is object */ template struct IsObject: IntegralConstant::value && !IsVoid::value && !IsReference::value) > {}; /* is scalar */ template struct IsScalar: IntegralConstant::value || IsPointer::value || IsEnum::value || IsNullPointer ::value || IsArithmetic::value) > {}; /* is abstract */ template struct IsAbstract: IntegralConstant {}; /* is const */ template struct IsConst : false_t {}; template struct IsConst: true_t {}; /* is volatile */ template struct IsVolatile : false_t {}; template struct IsVolatile: true_t {}; /* is empty */ template struct IsEmpty: IntegralConstant {}; /* is POD */ template struct IsPOD: IntegralConstant {}; /* is polymorphic */ template struct IsPolymorphic: IntegralConstant {}; /* is signed */ template struct IsSigned: IntegralConstant {}; /* is unsigned */ template struct IsUnsigned: IntegralConstant {}; /* is standard layout */ template struct RemoveAllExtents; template struct IsStandardLayout: IntegralConstant::type>::value > {}; /* is literal type */ template struct IsLiteralType: IntegralConstant::type>::value || IsStandardLayout::value > {}; /* is base of */ template struct IsBaseOf: IntegralConstant {}; /* type equality */ template struct IsSame : false_t {}; template struct IsSame: true_t {}; /* extent */ template struct Extent: IntegralConstant {}; template struct Extent: IntegralConstant {}; template struct Extent: IntegralConstant::value> {}; template struct Extent: IntegralConstant {}; template struct Extent: IntegralConstant::value> {}; /* rank */ template struct Rank: IntegralConstant {}; template struct Rank: IntegralConstant::value + 1> {}; template struct Rank: IntegralConstant::value + 1> {}; /* remove reference */ template using RemoveReference = internal::RemoveReference; /* remove pointer */ template struct RemovePointer { typedef T type; }; template struct RemovePointer { typedef T type; }; template struct RemovePointer { typedef T type; }; template struct RemovePointer { typedef T type; }; template struct RemovePointer { typedef T type; }; /* add pointer */ template struct AddPointer { typedef typename RemoveReference::type *type; }; /* add lvalue reference */ template struct AddLvalueReference { typedef T &type; }; template struct AddLvalueReference { typedef T &type; }; template struct AddLvalueReference { typedef T &type; }; template<> struct AddLvalueReference { typedef void type; }; template<> struct AddLvalueReference { typedef const void type; }; template<> struct AddLvalueReference { typedef volatile void type; }; template<> struct AddLvalueReference { typedef const volatile void type; }; /* add rvalue reference */ template using AddRvalueReference = internal::AddRvalueReference; /* remove extent */ template struct RemoveExtent { typedef T type; }; template struct RemoveExtent { typedef T type; }; template struct RemoveExtent { typedef T type; }; /* remove all extents */ template struct RemoveAllExtents { typedef T type; }; template struct RemoveAllExtents { typedef typename RemoveAllExtents::type type; }; template struct RemoveAllExtents { typedef typename RemoveAllExtents::type type; }; /* conditional */ template struct Conditional { typedef T type; }; template struct Conditional { typedef U type; }; /* result of call at compile time */ namespace internal { template inline auto result_of_invoke(F &&f, A &&...args) -> decltype(forward(f)(forward(args)...)) { return forward(f)(forward(args)...); } template inline auto result_of_invoke(T B::*pmd, D &&ref) -> decltype(forward(ref).*pmd) { return forward(ref).*pmd; } template inline auto result_of_invoke(PMD &&pmd, P &&ptr) -> decltype((*forward

(ptr)).*forward(pmd)) { return (*forward

(ptr)).*forward(pmd); } template inline auto result_of_invoke(T B::*pmf, D &&ref, A &&...args) -> decltype((forward(ref).*pmf)(forward(args)...)) { return (forward(ref).*pmf)(forward(args)...); } template inline auto result_of_invoke(PMF &&pmf, P &&ptr, A &&...args) -> decltype(((*forward

(ptr)).*forward(pmf))(forward(args)...)) { return ((*forward

(ptr)).*forward(pmf))(forward(args)...); } template struct ResultOf {}; template struct ResultOf(), declval()...)))> { using type = decltype(result_of_invoke(declval(), declval()...)); }; } template struct ResultOf: internal::ResultOf {}; /* enable_if */ template struct enable_if {}; template struct enable_if { typedef T type; }; /* decay */ template struct Decay { private: typedef typename RemoveReference::type U; public: typedef typename Conditional::value, typename RemoveExtent::type *, typename Conditional::value, typename AddPointer::type, typename RemoveConstVolatile::type >::type >::type type; }; } #endif