aboutsummaryrefslogtreecommitdiff
path: root/EASTL/test/source/TestTypeTraits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'EASTL/test/source/TestTypeTraits.cpp')
-rw-r--r--EASTL/test/source/TestTypeTraits.cpp304
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");