diff options
Diffstat (limited to 'EASTL/test/source/TestTypeTraits.cpp')
-rw-r--r-- | EASTL/test/source/TestTypeTraits.cpp | 304 |
1 files changed, 269 insertions, 35 deletions
diff --git a/EASTL/test/source/TestTypeTraits.cpp b/EASTL/test/source/TestTypeTraits.cpp index 0353be9..2670e24 100644 --- a/EASTL/test/source/TestTypeTraits.cpp +++ b/EASTL/test/source/TestTypeTraits.cpp @@ -173,15 +173,16 @@ struct NonPod2 virtual void Function(){} }; -#if EASTL_VARIABLE_TEMPLATES_ENABLED - struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } }; +struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } }; - template<typename, typename = eastl::void_t<>> - struct has_increment_operator : eastl::false_type {}; +template <class T> +using has_increment_operator_detection = decltype(++eastl::declval<T>()); - template <typename T> - struct has_increment_operator<T, eastl::void_t<decltype(++eastl::declval<T>())>> : eastl::true_type {}; -#endif +template<typename, typename = eastl::void_t<>> +struct has_increment_operator_using_void_t : eastl::false_type {}; + +template <typename T> +struct has_increment_operator_using_void_t<T, eastl::void_t<has_increment_operator_detection<T>>> : eastl::true_type {}; // We use this for the is_copy_constructible test in order to verify that @@ -359,13 +360,19 @@ struct NonPolymorphic1 void Function(){} }; +// Disable the following warning: +// warning: ‘struct Abstract’ has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor] +// We explicitly want this class not to have a virtual destructor to test our type traits. +EA_DISABLE_VC_WARNING(4265) +EA_DISABLE_CLANG_WARNING(-Wnon-virtual-dtor) +EA_DISABLE_GCC_WARNING(-Wnon-virtual-dtor) struct Abstract { - #if defined(EA_COMPILER_GNUC) // GCC warns about this, so we include it for this class, even though for this compiler it partly defeats the purpose of its usage. - virtual ~Abstract(){} - #endif virtual void Function() = 0; }; +EA_RESTORE_GCC_WARNING() +EA_RESTORE_CLANG_WARNING() +EA_RESTORE_VC_WARNING() struct AbstractWithDtor { @@ -542,6 +549,7 @@ int TestTypeTraits() EATEST_VERIFY(GetType(is_integral<float>()) == false); static_assert(is_integral<bool>::value, "is_integral failure"); + static_assert(is_integral<char8_t>::value, "is_integral failure"); static_assert(is_integral<char16_t>::value, "is_integral failure"); static_assert(is_integral<char32_t>::value, "is_integral failure"); static_assert(is_integral<char>::value, "is_integral failure"); @@ -616,6 +624,42 @@ int TestTypeTraits() EATEST_VERIFY(GetType(is_array<uint32_t*>()) == false); + //is_bounded_array + static_assert(is_bounded_array<Array>::value == true, "is_bounded_array failure"); + EATEST_VERIFY(GetType(is_bounded_array<Array>()) == true); + + static_assert(is_bounded_array<ArrayConst>::value == true, "is_bounded_array failure"); + EATEST_VERIFY(GetType(is_bounded_array<ArrayConst>()) == true); + + static_assert(is_bounded_array<int>::value == false, "is_bounded_array failure"); + static_assert(is_bounded_array<int[32]>::value == true, "is_bounded_array failure"); + static_assert(is_bounded_array<int[]>::value == false, "is_bounded_array failure"); + + static_assert(is_bounded_array<uint32_t>::value == false, "is_bounded_array failure"); + EATEST_VERIFY(GetType(is_bounded_array<uint32_t>()) == false); + + static_assert(is_bounded_array<uint32_t*>::value == false, "is_bounded_array failure"); + EATEST_VERIFY(GetType(is_bounded_array<uint32_t*>()) == false); + + + //is_unbounded_array + static_assert(is_unbounded_array<Array>::value == false, "is_unbounded_array failure"); + EATEST_VERIFY(GetType(is_unbounded_array<Array>()) == false); + + static_assert(is_unbounded_array<ArrayConst>::value == false, "is_unbounded_array failure"); + EATEST_VERIFY(GetType(is_unbounded_array<ArrayConst>()) == false); + + static_assert(is_unbounded_array<int>::value == false, "is_unbounded_array failure"); + static_assert(is_unbounded_array<int[32]>::value == false, "is_unbounded_array failure"); + static_assert(is_unbounded_array<int[]>::value == true, "is_unbounded_array failure"); + + static_assert(is_unbounded_array<uint32_t>::value == false, "is_unbounded_array failure"); + EATEST_VERIFY(GetType(is_unbounded_array<uint32_t>()) == false); + + static_assert(is_unbounded_array<uint32_t*>::value == false, "is_unbounded_array failure"); + EATEST_VERIFY(GetType(is_unbounded_array<uint32_t*>()) == false); + + // is_reference static_assert(is_reference<Class&>::value == true, "is_reference failure"); EATEST_VERIFY(GetType(is_reference<Class&>()) == true); @@ -640,6 +684,10 @@ int TestTypeTraits() static_assert(is_member_function_pointer<int>::value == false, "is_member_function_pointer failure"); static_assert(is_member_function_pointer<int(Class::*)>::value == false, "is_member_function_pointer failure"); static_assert(is_member_function_pointer<int(Class::*)()>::value == true, "is_member_function_pointer failure"); + static_assert(is_member_function_pointer<int(Class::*)(...)>::value == true, "is_member_function_pointer failure"); + static_assert(is_member_function_pointer<int(Class::*)() noexcept>::value == true, "is_member_function_pointer failure"); + static_assert(is_member_function_pointer<int(Class::*)() &>::value == true, "is_member_function_pointer failure"); + static_assert(is_member_function_pointer<int(Class::*)() &&>::value == true, "is_member_function_pointer failure"); // is_member_object_pointer @@ -652,6 +700,9 @@ int TestTypeTraits() static_assert(is_member_pointer<int>::value == false, "is_member_pointer failure"); static_assert(is_member_pointer<int(Class::*)>::value == true, "is_member_pointer failure"); static_assert(is_member_pointer<int(Class::*)()>::value == true, "is_member_pointer failure"); + static_assert(is_member_pointer<int(Class::* const)>::value == true, "is_member_pointer failure"); + static_assert(is_member_pointer<int(Class::* volatile)>::value == true, "is_member_pointer failure"); + static_assert(is_member_pointer<int(Class::* const volatile)>::value == true, "is_member_pointer failure"); // is_pointer @@ -719,7 +770,7 @@ int TestTypeTraits() // is_function static_assert(is_function<void>::value == false, "is_function failure"); static_assert(is_function<FunctionVoidVoid>::value == true, "is_function failure"); - static_assert(is_function<FunctionVoidVoid&>::value == false, "is_function failure"); + static_assert(is_function<FunctionVoidVoid&>::value == false, "is_function failure"); static_assert(is_function<FunctionIntVoid>::value == true, "is_function failure"); static_assert(is_function<FunctionIntFloat>::value == true, "is_function failure"); static_assert(is_function<FunctionVoidVoidPtr>::value == false, "is_function failure"); @@ -731,6 +782,16 @@ int TestTypeTraits() // typedef int PrintfConst(const char*, ...) const; static_assert(is_function<int (const char*, ...)>::value == true, "is_function failure"); // This is the signature of printf. #endif + + static_assert(is_function<int (float)>::value == true, "is_function failure"); + static_assert(is_function<int (float) const>::value == true, "is_function failure"); + static_assert(is_function<int(float) volatile>::value == true, "is_function failure"); + static_assert(is_function<int(float) const volatile>::value == true, "is_function failure"); + static_assert(is_function<int(float)&>::value == true, "is_function failure"); + static_assert(is_function<int(float)&&>::value == true, "is_function failure"); + static_assert(is_function<int(float) noexcept>::value == true, "is_function failure"); + static_assert(is_function<FunctionIntFloat &>::value == false, "is_function failure"); // reference to function, not a l-value reference qualified function + static_assert(is_function<FunctionIntFloat &&>::value == false, "is_function failure"); static_assert(is_function_v<void> == false, "is_function failure"); static_assert(is_function_v<FunctionVoidVoid> == true, "is_function failure"); @@ -820,6 +881,8 @@ int TestTypeTraits() static_assert(is_const<ConstVolatileIntReference>::value == false, "is_const failure"); // Note here that the int is const, not the reference to the int. EATEST_VERIFY(GetType(is_const<ConstVolatileIntReference>()) == false); + static_assert(is_const<void() const>::value == false, "is_const failure"); + EATEST_VERIFY(GetType(is_const<void() const>()) == false); // is_volatile static_assert(is_volatile<Int>::value == false, "is_volatile failure"); @@ -843,6 +906,9 @@ int TestTypeTraits() static_assert(is_volatile<ConstVolatileIntReference>::value == false, "is_volatile failure"); // Note here that the int is volatile, not the reference to the int. EATEST_VERIFY(GetType(is_volatile<ConstVolatileIntReference>()) == false); + static_assert(is_volatile<void() const>::value == false, "is_volatile failure"); + EATEST_VERIFY(GetType(is_volatile<void() const>()) == false); + // underlying_type and to_underlying #if EASTL_TYPE_TRAIT_underlying_type_CONFORMANCE && !defined(EA_COMPILER_NO_STRONGLY_TYPED_ENUMS) // If we can execute this test... @@ -1067,7 +1133,24 @@ int TestTypeTraits() static_assert(is_signed<double>::value == true, "is_signed failure "); static_assert(is_signed_v<double> == true, "is_signed failure "); EATEST_VERIFY(GetType(is_signed<double>()) == true); - + + static_assert(is_signed<char16_t>::value == false, "is_signed failure "); + static_assert(is_signed_v<char16_t> == false, "is_signed failure "); + EATEST_VERIFY(GetType(is_signed<char16_t>()) == false); + + static_assert(is_signed<char32_t>::value == false, "is_signed failure "); + static_assert(is_signed_v<char32_t> == false, "is_signed failure "); + EATEST_VERIFY(GetType(is_signed<char32_t>()) == false); + +#if EASTL_GCC_STYLE_INT128_SUPPORTED + static_assert(is_signed<__int128_t>::value == true, "is_signed failure "); + static_assert(is_signed_v<__int128_t> == true, "is_signed failure "); + EATEST_VERIFY(GetType(is_signed<__int128_t>()) == true); + + static_assert(is_signed<__uint128_t>::value == false, "is_signed failure "); + static_assert(is_signed_v<__uint128_t> == false, "is_signed failure "); + EATEST_VERIFY(GetType(is_signed<__uint128_t>()) == false); +#endif // is_unsigned static_assert(is_unsigned<unsigned int>::value == true, "is_unsigned failure "); @@ -1082,9 +1165,9 @@ int TestTypeTraits() static_assert(is_unsigned_v<int32_t> == false, "is_unsigned failure "); EATEST_VERIFY(GetType(is_unsigned<int32_t>()) == false); - static_assert(is_unsigned<bool>::value == false, "is_unsigned failure "); - static_assert(is_unsigned_v<bool> == false, "is_unsigned failure "); - EATEST_VERIFY(GetType(is_unsigned<bool>()) == false); + static_assert(is_unsigned<bool>::value == true, "is_unsigned failure "); + static_assert(is_unsigned_v<bool> == true, "is_unsigned failure "); + EATEST_VERIFY(GetType(is_unsigned<bool>()) == true); static_assert(is_unsigned<float>::value == false, "is_unsigned failure "); static_assert(is_unsigned_v<float> == false, "is_unsigned failure "); @@ -1093,6 +1176,24 @@ int TestTypeTraits() static_assert(is_unsigned<double>::value == false, "is_unsigned failure "); static_assert(is_unsigned_v<double> == false, "is_unsigned failure "); EATEST_VERIFY(GetType(is_unsigned<double>()) == false); + + static_assert(is_unsigned<char16_t>::value == true, "is_unsigned failure "); + static_assert(is_unsigned_v<char16_t> == true, "is_unsigned failure "); + EATEST_VERIFY(GetType(is_unsigned<char16_t>()) == true); + + static_assert(is_unsigned<char32_t>::value == true, "is_unsigned failure "); + static_assert(is_unsigned_v<char32_t> == true, "is_unsigned failure "); + EATEST_VERIFY(GetType(is_unsigned<char32_t>()) == true); + +#if EASTL_GCC_STYLE_INT128_SUPPORTED + static_assert(is_unsigned<__int128_t>::value == false, "is_unsigned failure "); + static_assert(is_unsigned_v<__int128_t> == false, "is_unsigned failure "); + EATEST_VERIFY(GetType(is_unsigned<__int128_t>()) == false); + + static_assert(is_unsigned<__uint128_t>::value == true, "is_unsigned failure "); + static_assert(is_unsigned_v<__uint128_t> == true, "is_unsigned failure "); + EATEST_VERIFY(GetType(is_unsigned<__uint128_t>()) == true); +#endif // is_lvalue_reference @@ -1252,6 +1353,7 @@ int TestTypeTraits() // is_trivially_copyable static_assert(is_trivially_copyable<void>::value == false, "is_trivially_copyable failure"); + EATEST_VERIFY(GetType(is_trivially_copyable<void>()) == false); static_assert(is_trivially_copyable<int>::value == true, "is_trivially_copyable failure"); static_assert(is_trivially_copyable<int*>::value == true, "is_trivially_copyable failure"); static_assert(is_trivially_copyable<int[]>::value == true, "is_trivially_copyable failure"); @@ -1395,14 +1497,16 @@ int TestTypeTraits() // is_destructible static_assert(is_destructible<int>::value == true, "is_destructible failure"); + static_assert(is_destructible<int&>::value == true, "is_destructible failure"); + static_assert(is_destructible<int&&>::value == true, "is_destructible failure"); static_assert(is_destructible<char>::value == true, "is_destructible failure"); static_assert(is_destructible<char*>::value == true, "is_destructible failure"); static_assert(is_destructible<PodA>::value == true, "is_destructible failure"); static_assert(is_destructible<void>::value == false, "is_destructible failure"); static_assert(is_destructible<int[3]>::value == true, "is_destructible failure"); static_assert(is_destructible<int[]>::value == false, "is_destructible failure"); // You can't call operator delete on this class. - static_assert(is_destructible<Abstract>::value == false, "is_destructible failure"); // You can't call operator delete on this class. - static_assert(is_destructible<AbstractWithDtor>::value == false, "is_destructible failure"); // You can't call operator delete on this class. + static_assert(is_destructible<Abstract>::value == true, "is_destructible failure"); + static_assert(is_destructible<AbstractWithDtor>::value == true, "is_destructible failure"); #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) static_assert(is_destructible<DeletedDtor>::value == false, "is_destructible failure"); // You can't call operator delete on this class. #endif @@ -1420,18 +1524,25 @@ int TestTypeTraits() static_assert(is_trivially_destructible<PodA>::value == true, "is_trivially_destructible failure"); static_assert(is_trivially_destructible<int[3]>::value == true, "is_trivially_destructible failure"); static_assert(is_trivially_destructible<int[]>::value == false, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<Abstract>::value == false, "is_trivially_destructible failure"); - static_assert(is_trivially_destructible<AbstractWithDtor>::value == false, "is_trivially_destructible failure"); + static_assert(is_trivially_destructible<Abstract>::value == true, "is_trivially_destructible failure"); + static_assert(is_trivially_destructible<AbstractWithDtor>::value == false, "is_trivially_destructible failure"); // Having a user-defined destructor make it non-trivial. + #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) static_assert(is_trivially_destructible<DeletedDtor>::value == false, "is_trivially_destructible failure"); + #endif static_assert(is_trivially_destructible<NonPod2>::value == false, "is_trivially_destructible failure"); // This case differs from is_destructible, because we have a declared destructor. #endif // is_nothrow_destructible static_assert(is_nothrow_destructible<int>::value == true, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<int&>::value == true, "is_nothrow_destructible failure"); - static_assert(is_nothrow_destructible<int&&>::value == true, "is_nothrow_destructible failure"); + static_assert(is_nothrow_destructible<int&>::value == true, "is_nothrow_destructible failure"); + static_assert(is_nothrow_destructible<int&&>::value == true, "is_nothrow_destructible failure"); static_assert(is_nothrow_destructible<void>::value == false, "is_nothrow_destructible failure"); + static_assert(is_nothrow_destructible<Abstract>::value == true, "is_nothrow_destructible failure"); + static_assert(is_nothrow_destructible<AbstractWithDtor>::value == true, "is_nothrow_destructible failure"); + #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) + static_assert(is_nothrow_destructible<DeletedDtor>::value == false, "is_nothrow_destructible failure"); // You can't call operator delete on this class. + #endif #if EASTL_TYPE_TRAIT_is_nothrow_destructible_CONFORMANCE static_assert(is_nothrow_destructible<NonPod2>::value == true, "is_nothrow_destructible failure"); // NonPod2 is nothrow destructible because it has an empty destructor (makes no calls) which has no exception specification. Thus its exception specification defaults to noexcept(true) [C++11 Standard, 15.4 paragraph 14] static_assert(is_nothrow_destructible<NoThrowDestructible>::value == true, "is_nothrow_destructible failure"); @@ -1669,7 +1780,7 @@ int TestTypeTraits() static_assert(eastl::is_same_v<unsigned long, eastl::make_unsigned<unsigned long>::type>); static_assert(eastl::is_same_v<unsigned long long, eastl::make_unsigned<unsigned long long>::type>); - #if EASTL_INT128_SUPPORTED && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) + #if EASTL_GCC_STYLE_INT128_SUPPORTED static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__int128_t>::type>); static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__uint128_t>::type>); @@ -1680,13 +1791,18 @@ int TestTypeTraits() // Char tests static_assert(sizeof(char) == sizeof(eastl::make_signed<char>::type)); static_assert(sizeof(wchar_t) == sizeof(eastl::make_signed<wchar_t>::type)); + static_assert(sizeof(char8_t) == sizeof(eastl::make_signed<char8_t>::type)); static_assert(sizeof(char16_t) == sizeof(eastl::make_signed<char16_t>::type)); static_assert(sizeof(char32_t) == sizeof(eastl::make_signed<char32_t>::type)); static_assert(sizeof(char) == sizeof(eastl::make_unsigned<char>::type)); static_assert(sizeof(wchar_t) == sizeof(eastl::make_unsigned<wchar_t>::type)); + static_assert(sizeof(char8_t) == sizeof(eastl::make_unsigned<char8_t>::type)); static_assert(sizeof(char16_t) == sizeof(eastl::make_unsigned<char16_t>::type)); static_assert(sizeof(char32_t) == sizeof(eastl::make_unsigned<char32_t>::type)); + static_assert(eastl::is_same_v<signed char, eastl::make_signed<char8_t>::type>); + static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<char8_t>::type>); + // Enum tests enum EnumUCharSize : unsigned char {}; enum EnumUShortSize : unsigned short {}; @@ -1833,6 +1949,28 @@ int TestTypeTraits() yValue = 3; EATEST_VERIFY(yValue == 3); + // ref to T + // -> T* + static_assert(is_same_v<add_pointer_t<int&>, int*>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<int(&)()>, int(*)()>, "add_pointer failure"); + + // object type (a (possibly cv-qualified) type other than function type, reference type or void), or + // a function type that is not cv- or ref-qualified, or a (possibly cv-qualified) void type + // -> T* + static_assert(is_same_v<add_pointer_t<int>, int*>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<int*>, int**>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<int()>, int(*)()>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<void>, void*>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<const void>, const void*>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<volatile void>, volatile void*>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<const volatile void>, const volatile void*>, "add_pointer failure"); + + // otherwise (cv- or ref-qualified function type) + // -> T + static_assert(is_same_v<add_pointer_t<int() const>, int() const>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<int() volatile>, int() volatile>, "add_pointer failure"); + static_assert(is_same_v<add_pointer_t<int() const volatile>, int() const volatile>, "add_pointer failure"); + // remove_extent // If T is an array of some type X, provides the member typedef type equal to X, otherwise // type is T. Note that if T is a multidimensional array, only the first dimension is removed. @@ -1846,6 +1984,55 @@ int TestTypeTraits() static_assert((eastl::is_same<Int2, int>::value == true), "remove_all_extents/is_same failure"); } + // add_lvalue_reference + { + // function type with no cv- or ref-qualifier + // -> T& + static_assert(is_same_v<add_lvalue_reference_t<void()>, void(&)()>, "add_lvalue_reference failure"); + + // object type (a (possibly cv-qualified) type other than function type, reference type or void) + // -> T& + static_assert(is_same_v<add_lvalue_reference_t<int>, int&>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<const int>, const int&>, "add_lvalue_reference failure"); + + // if T is an rvalue reference (to some type U) + // -> U& + static_assert(is_same_v<add_lvalue_reference_t<int&&>, int&>, "add_lvalue_reference failure"); + + // otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void) + // -> T + static_assert(is_same_v<add_lvalue_reference_t<void() const>, void() const>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<void()&>, void()&>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<void()&&>, void()&&>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<int&>, int&>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<const int&>, const int&>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<void>, void>, "add_lvalue_reference failure"); + static_assert(is_same_v<add_lvalue_reference_t<const void>, const void>, "add_lvalue_reference failure"); + } + + // add_rvalue_reference + { + // function type with no cv- or ref-qualifier + // -> T&& + static_assert(is_same_v<add_rvalue_reference_t<void()>, void(&&)()>, "add_rvalue_reference failure"); + + // object type (a (possibly cv-qualified) type other than function type, reference type or void) + // -> T&& + static_assert(is_same_v<add_rvalue_reference_t<int>, int&&>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<const int>, const int&&>, "add_rvalue_reference failure"); + + // otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void) + // -> T + static_assert(is_same_v<add_rvalue_reference_t<void() const>, void() const>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<void()&>, void()&>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<void()&&>, void()&&>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<int&>, int&>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<int&&>, int&&>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<const int&>, const int&>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<void>, void>, "add_rvalue_reference failure"); + static_assert(is_same_v<add_rvalue_reference_t<const void>, const void>, "add_rvalue_reference failure"); + } + // decay { @@ -1979,26 +2166,71 @@ int TestTypeTraits() } // void_t - #if EASTL_VARIABLE_TEMPLATES_ENABLED { { - static_assert(is_same_v<void_t<void>, void>, "void_t failure"); - static_assert(is_same_v<void_t<int>, void>, "void_t failure"); - static_assert(is_same_v<void_t<short>, void>, "void_t failure"); - static_assert(is_same_v<void_t<long>, void>, "void_t failure"); - static_assert(is_same_v<void_t<long long>, void>, "void_t failure"); - static_assert(is_same_v<void_t<ClassEmpty>, void>, "void_t failure"); - static_assert(is_same_v<void_t<ClassNonEmpty>, void>, "void_t failure"); - static_assert(is_same_v<void_t<vector<int>>, void>, "void_t failure"); + static_assert(is_same<void_t<void>, void>::value, "void_t failure"); + static_assert(is_same<void_t<int>, void>::value, "void_t failure"); + static_assert(is_same<void_t<short>, void>::value, "void_t failure"); + static_assert(is_same<void_t<long>, void>::value, "void_t failure"); + static_assert(is_same<void_t<long long>, void>::value, "void_t failure"); + static_assert(is_same<void_t<ClassEmpty>, void>::value, "void_t failure"); + static_assert(is_same<void_t<ClassNonEmpty>, void>::value, "void_t failure"); + static_assert(is_same<void_t<vector<int>>, void>::value, "void_t failure"); } // new sfinae mechansim test { - static_assert(has_increment_operator<HasIncrementOperator>::value, "void_t sfinae failure"); - static_assert(!has_increment_operator<ClassEmpty>::value, "void_t sfinae failure"); + static_assert(has_increment_operator_using_void_t<HasIncrementOperator>::value, "void_t sfinae failure"); + static_assert(!has_increment_operator_using_void_t<ClassEmpty>::value, "void_t sfinae failure"); } } + + // detected idiom + { + static_assert(is_detected<has_increment_operator_detection, HasIncrementOperator>::value, "is_detected failure."); + static_assert(!is_detected<has_increment_operator_detection, ClassEmpty>::value, "is_detected failure."); + + static_assert(is_same<detected_t<has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "is_detected_t failure."); + static_assert(is_same<detected_t<has_increment_operator_detection, ClassEmpty>, nonesuch>::value, "is_detected_t failure."); + + using detected_or_positive_result = detected_or<float, has_increment_operator_detection, HasIncrementOperator>; + using detected_or_negative_result = detected_or<float, has_increment_operator_detection, ClassEmpty>; + static_assert(detected_or_positive_result::value_t::value, "detected_or failure."); + static_assert(!detected_or_negative_result::value_t::value, "detected_or failure."); + static_assert(is_same<detected_or_positive_result::type, HasIncrementOperator&>::value, "detected_or failure."); + static_assert(is_same<detected_or_negative_result::type, float>::value, "detected_or failure."); + + static_assert(is_same<detected_or_t<float, has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "detected_or_t failure."); + static_assert(is_same<detected_or_t<float, has_increment_operator_detection, ClassEmpty>, float>::value, "detected_or_t failure."); + + static_assert(is_detected_exact<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure."); + static_assert(!is_detected_exact<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure."); + static_assert(is_detected_exact<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure."); + static_assert(!is_detected_exact<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure."); + + static_assert(is_detected_convertible<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure."); + static_assert(is_detected_convertible<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure."); + static_assert(!is_detected_convertible<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure."); + static_assert(!is_detected_convertible<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure."); + static_assert(!is_detected_convertible<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure."); + + + #if EASTL_VARIABLE_TEMPLATES_ENABLED + static_assert(is_detected_v<has_increment_operator_detection, HasIncrementOperator>, "is_detected_v failure."); + static_assert(!is_detected_v<has_increment_operator_detection, ClassEmpty>, "is_detected_v failure."); + + static_assert(is_detected_exact_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure."); + static_assert(!is_detected_exact_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure."); + static_assert(is_detected_exact_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure."); + static_assert(!is_detected_exact_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure."); + + static_assert(is_detected_convertible_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure."); + static_assert(is_detected_convertible_v<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure."); + static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure."); + static_assert(!is_detected_convertible_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure."); + static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure."); #endif + } // conjunction { @@ -2160,8 +2392,10 @@ int TestTypeTraits() static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure"); } - #ifndef EA_COMPILER_MSVC - // NOTE(rparolin): MSVC is incorrectly categorizing the aggregate type in this test-case. + #if defined(EA_COMPILER_CPP11_ENABLED) && !defined(EA_COMPILER_CPP14_ENABLED) + // See https://en.cppreference.com/w/cpp/language/aggregate_initialization + // In C++11 the requirement was added to aggregate types that no default member initializers exist, + // however this requirement was removed in C++14. { struct NotAggregrate { int data = 42; }; // default member initializer static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure"); |