aboutsummaryrefslogtreecommitdiff
path: root/test/source/TestTypeTraits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/source/TestTypeTraits.cpp')
-rw-r--r--test/source/TestTypeTraits.cpp2038
1 files changed, 2038 insertions, 0 deletions
diff --git a/test/source/TestTypeTraits.cpp b/test/source/TestTypeTraits.cpp
new file mode 100644
index 0000000..0fb6280
--- /dev/null
+++ b/test/source/TestTypeTraits.cpp
@@ -0,0 +1,2038 @@
+/////////////////////////////////////////////////////////////////////////////
+// Copyright (c) Electronic Arts Inc. All rights reserved.
+/////////////////////////////////////////////////////////////////////////////
+
+
+#include "EASTLTest.h"
+#include <EASTL/type_traits.h>
+#include <EASTL/vector.h>
+#include <EAStdC/EAAlignment.h>
+#include "ConceptImpls.h"
+
+
+
+using namespace eastl;
+
+
+bool GetType(const true_type&)
+{
+ return true;
+}
+
+bool GetType(const false_type&)
+{
+ return false;
+}
+
+int GetType(const integral_constant<size_t, (size_t)4>&)
+{
+ return 4;
+}
+
+int GetType(const integral_constant<size_t, (size_t)8>&)
+{
+ return 8;
+}
+
+int GetType(const integral_constant<size_t, (size_t)16>&)
+{
+ return 16;
+}
+
+int GetType(const integral_constant<size_t, (size_t)32>&)
+{
+ return 32;
+}
+
+#ifdef _MSC_VER
+ __declspec(align(32)) class ClassAlign32{ };
+#else
+ class ClassAlign32{ } __attribute__((aligned(32)));
+#endif
+
+
+struct Struct
+{
+ // Empty
+};
+
+class Class
+{
+ // Empty
+};
+
+class Subclass : public Class
+{
+ // Empty
+};
+
+class ClassEmpty
+{
+ // Empty
+};
+
+class ClassNonEmpty
+{
+public:
+ int x;
+};
+
+enum Enum
+{
+ kValue1
+};
+
+union Union
+{
+ int x;
+ short y;
+};
+
+struct FinalStruct final
+{
+};
+
+class FinalClass final
+{
+};
+
+#if !EASTL_TYPE_TRAIT_is_union_CONFORMANCE
+ EASTL_DECLARE_UNION(Union) // We have to do this because is_union simply cannot work without user help.
+#endif
+
+
+
+// Used for union_cast tests below.
+// C++11 allows for PodA/PodB to have a trivial default (i.e. compiler-generated) constructor,
+// but as of this writing (3/2012) most C++ compilers don't have support for this yet.
+struct PodA{
+ int mX;
+};
+
+struct PodB{
+ int mX;
+};
+
+bool operator ==(const PodA& a1, const PodA& a2) { return (a1.mX == a2.mX); }
+
+
+// std::tr1::is_volatile<T>::value == true if and only if, for a given type T:
+// * std::tr1::is_scalar<T>::value == true, or
+// * T is a class or struct that has no user-defined copy assignment operator or destructor,
+// and T has no non-static data members M for which is_pod<M>::value == false, and no members of reference type, or
+// * T is the type of an array of objects E for which is_pod<E>::value == true
+// is_pod may only be applied to complete types.
+
+struct Pod1
+{
+ // Empty
+};
+#if !EASTL_TYPE_TRAIT_is_pod_CONFORMANCE
+ EASTL_DECLARE_POD(Pod1) // We have to do this because is_pod simply cannot work without user help.
+#endif
+#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE
+ EASTL_DECLARE_STANDARD_LAYOUT(Pod1) // We have to do this because is_standard_layout simply cannot work without user help.
+#endif
+
+
+struct Pod2
+{
+ int mX;
+ Pod1 mPod1;
+};
+#if !EASTL_TYPE_TRAIT_is_pod_CONFORMANCE
+ EASTL_DECLARE_POD(Pod2)
+#endif
+#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE
+ EASTL_DECLARE_STANDARD_LAYOUT(Pod2)
+#endif
+
+struct Pod3
+{
+ Pod2 mPod2;
+ int mX;
+ Pod1 mPod1;
+};
+#if !EASTL_TYPE_TRAIT_is_pod_CONFORMANCE
+ EASTL_DECLARE_POD(Pod3)
+#endif
+#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE
+ EASTL_DECLARE_STANDARD_LAYOUT(Pod3)
+#endif
+
+
+struct NonPod1
+{
+ NonPod1(){}
+ virtual ~NonPod1(){}
+};
+
+struct NonPod2
+{
+ virtual ~NonPod2(){}
+ virtual void Function(){}
+};
+
+#if EASTL_VARIABLE_TEMPLATES_ENABLED
+ struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } };
+
+ template<typename, typename = eastl::void_t<>>
+ struct has_increment_operator : eastl::false_type {};
+
+ template <typename T>
+ struct has_increment_operator<T, eastl::void_t<decltype(++eastl::declval<T>())>> : eastl::true_type {};
+#endif
+
+
+// We use this for the is_copy_constructible test in order to verify that
+// is_copy_constructible in fact returns false for this type and not true.
+// std::is_copy_constructible specification: std::is_constructible<T, const T&>::value is true.
+// Note that the specification refers to const T& and not T&. So we rig our class to
+// accept T& and not const T&. This situation is significant because as of this
+// writing the clang <type_traits> implementation appears to be broken and mis-implements
+// the is_copy_constructible type trait to return true for ConstructibleOnlyWithNonConstReference
+// when in fact it should return false.
+EA_DISABLE_VC_WARNING(4521) // disable warning : "multiple copy constructors specified"
+struct ConstructibleOnlyWithNonConstReference
+{
+ ConstructibleOnlyWithNonConstReference(ConstructibleOnlyWithNonConstReference&) {}
+
+ #if defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
+ private: ConstructibleOnlyWithNonConstReference() {}
+ private: ConstructibleOnlyWithNonConstReference(const ConstructibleOnlyWithNonConstReference&) {}
+ #else
+ ConstructibleOnlyWithNonConstReference() = delete;
+ ConstructibleOnlyWithNonConstReference(const ConstructibleOnlyWithNonConstReference&) = delete;
+ #endif
+};
+EA_RESTORE_VC_WARNING()
+
+#if defined(EA_COMPILER_NO_NOEXCEPT)
+ //This is needed because VS2013 supports is_nothrow__xxx type traits but doesn't support C++11 noexcept.
+ //So we use throw() to allow the is_nothrow_xxxx and similiar tests to work in VS2013
+ #define EASTL_TEST_NOEXCEPT throw()
+#else
+ #define EASTL_TEST_NOEXCEPT EA_NOEXCEPT
+#endif
+
+struct ThrowConstructibleTest
+{
+ ThrowConstructibleTest(const int = 0) EASTL_TEST_NOEXCEPT { }
+ ThrowConstructibleTest(const float) EA_NOEXCEPT_IF(false) { }
+};
+
+
+
+struct NoThrowAssignable { };
+
+struct ThrowAssignableTest
+{
+ void operator=(const NoThrowAssignable&) EASTL_TEST_NOEXCEPT { }
+ void operator=(const ThrowAssignableTest&) { }
+};
+
+
+struct NoThrowDestructible
+{
+ ~NoThrowDestructible() EASTL_TEST_NOEXCEPT {}
+};
+
+#if !defined(EA_COMPILER_NO_EXCEPTIONS)
+ struct ThrowDestructible
+ {
+ ~ThrowDestructible() noexcept(false) { throw(int()); }
+ };
+
+ struct ThrowDestructibleNoexceptFalse
+ {
+ virtual ~ThrowDestructibleNoexceptFalse() EA_NOEXCEPT_IF(false) { }
+ };
+#endif
+
+
+struct HasTrivialConstructor
+{
+ int x;
+};
+#if !EASTL_TYPE_TRAIT_has_trivial_constructor_CONFORMANCE
+ EASTL_DECLARE_TRIVIAL_CONSTRUCTOR(HasTrivialConstructor) // We have to do this because has_trivial_constructor simply cannot work without user help.
+#endif
+#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE
+ EASTL_DECLARE_STANDARD_LAYOUT(HasTrivialConstructor)
+#endif
+
+
+struct NoTrivialConstructor
+{
+ NoTrivialConstructor() { px = &x; }
+ int x;
+ int* px;
+};
+#if !EASTL_TYPE_TRAIT_is_standard_layout_CONFORMANCE
+ EASTL_DECLARE_STANDARD_LAYOUT(NoTrivialConstructor)
+#endif
+
+
+struct HasTrivialCopy
+{
+ void Function(){}
+ int x;
+};
+#if !EASTL_TYPE_TRAIT_has_trivial_constructor_CONFORMANCE
+ EASTL_DECLARE_TRIVIAL_COPY(HasTrivialCopy) // We have to do this because has_trivial_copy simply cannot work without user help.
+#endif
+
+
+#if defined(EA_COMPILER_MSVC) && (_MSC_VER == 1900)
+ // http://blogs.msdn.com/b/vcblog/archive/2014/06/06/c-14-stl-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx
+ // VS2015-preview has a bug regarding C++14 implicit noexcept rules for destructors. We explicitly define noexcept below for VS2015-preview only.
+ //
+ // Re-evaluate when VS2015 RTM has been released.
+ //
+ struct NoTrivialCopy1
+ {
+ virtual ~NoTrivialCopy1() EASTL_TEST_NOEXCEPT {}
+ virtual void Function(){}
+ };
+#else
+ struct NoTrivialCopy1
+ {
+ virtual ~NoTrivialCopy1() {}
+ virtual void Function(){}
+ };
+#endif
+
+struct NoTrivialCopy2
+{
+ NoTrivialCopy1 ntv;
+};
+
+struct NonCopyable
+{
+ NonCopyable() : mX(0) {}
+ NonCopyable(int x) : mX(x) {}
+
+ int mX;
+
+ EA_NON_COPYABLE(NonCopyable)
+};
+
+struct HasTrivialAssign
+{
+ void Function(){}
+ int x;
+};
+#if !EASTL_TYPE_TRAIT_has_trivial_assign_CONFORMANCE
+ EASTL_DECLARE_TRIVIAL_ASSIGN(HasTrivialAssign) // We have to do this because has_trivial_assign simply cannot work without user help.
+#endif
+
+struct NoTrivialAssign1
+{
+ virtual ~NoTrivialAssign1(){}
+ virtual void Function(){}
+};
+
+struct NoTrivialAssign2
+{
+ NoTrivialAssign1 nta;
+};
+
+struct Polymorphic1
+{
+ virtual ~Polymorphic1(){}
+ virtual void Function(){}
+};
+
+struct Polymorphic2 : public Polymorphic1
+{
+ // Empty
+};
+
+struct Polymorphic3
+{
+ virtual ~Polymorphic3(){}
+ virtual void Function() = 0;
+};
+
+struct NonPolymorphic1
+{
+ void Function(){}
+};
+
+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;
+};
+
+struct AbstractWithDtor
+{
+ virtual ~AbstractWithDtor(){}
+ virtual void Function() = 0;
+};
+
+struct DeletedDtor
+{
+ #if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
+ ~DeletedDtor() = delete;
+ #endif
+};
+
+#if (EASTL_TYPE_TRAIT_is_destructible_CONFORMANCE == 0)
+ EASTL_DECLARE_IS_DESTRUCTIBLE(DeletedDtor, false)
+#endif
+
+struct Assignable
+{
+ void operator=(const Assignable&){}
+ void operator=(const Pod1&){}
+};
+
+class HiddenAssign
+{
+public:
+ HiddenAssign();
+
+private:
+ HiddenAssign(const HiddenAssign& x);
+ HiddenAssign& operator=(const HiddenAssign& x);
+};
+
+#if !EASTL_TYPE_TRAIT_has_trivial_assign_CONFORMANCE
+ EASTL_DECLARE_TRIVIAL_ASSIGN(HiddenAssign)
+#endif
+
+
+
+// This class exercises is_convertible for the case that the class has an explicit copy constructor.
+struct IsConvertibleTest1
+{
+ IsConvertibleTest1() {}
+ IsConvertibleTest1(int, int) {}
+ explicit IsConvertibleTest1(const IsConvertibleTest1&) {}
+ ~IsConvertibleTest1(){}
+};
+
+
+
+// Helpers for enable_if tests
+template<typename T>
+typename eastl::enable_if<eastl::is_floating_point<T>::value, T>::type EnableIfTestFunction(T)
+ { return 999; }
+
+template<typename T>
+typename eastl::enable_if<eastl::is_integral<T>::value, T>::type EnableIfTestFunction(T)
+ { return 888; }
+
+template<typename T>
+typename eastl::disable_if<eastl::is_signed<T>::value, T>::type EnableIfTestFunction(T)
+ { return 777; }
+
+
+
+// Test that EASTL_DECLARE_TRIVIAL_ASSIGN can be used to get around case whereby
+// the copy constructor and operator= are private. Normally vector requires this.
+// ** This is disabled because it turns out that vector in fact requires the
+// constructor for some uses. But we have code below which tests just part of vector.
+// template class eastl::vector<HiddenAssign>;
+
+
+typedef char Array[32];
+typedef const char ArrayConst[32];
+
+
+typedef Class& Reference;
+typedef const Class& ConstReference;
+
+
+typedef const int ConstInt;
+typedef int Int;
+typedef volatile int VolatileInt;
+typedef const volatile int ConstVolatileInt;
+typedef int& IntReference;
+typedef const int& ConstIntReference; // Note here that the int is const, not the reference to the int.
+typedef const volatile int& ConstVolatileIntReference; // Note here that the int is const, not the reference to the int.
+
+
+typedef void FunctionVoidVoid();
+typedef int FunctionIntVoid();
+typedef int FunctionIntFloat(float);
+typedef void (*FunctionVoidVoidPtr)();
+
+namespace
+{
+ const eastl::string gEmptyStringInstance("");
+
+ const eastl::integral_constant<int*, nullptr> gIntNullptrConstant;
+ static_assert(gIntNullptrConstant() == nullptr, "");
+}
+
+int TestTypeTraits()
+{
+ int nErrorCount = 0;
+
+
+ // static_min / static_max
+ #if EASTL_TYPE_TRAIT_static_min_CONFORMANCE
+ static_assert((static_min<3, 7, 1, 5>::value == 1), "static_min failure");
+ static_assert((static_max<3, 7, 1, 5>::value == 7), "static_max failure");
+ #else
+ static_assert((static_min<7, 1>::value == 1), "static_min failure");
+ static_assert((static_max<7, 1>::value == 7), "static_max failure");
+ #endif
+
+ // enable_if, disable_if.
+ EATEST_VERIFY((EnableIfTestFunction((double)1.1) == 999));
+ EATEST_VERIFY((EnableIfTestFunction((int)1) == 888));
+ EATEST_VERIFY((EnableIfTestFunction((int)-4) == 888));
+
+
+ // conditional
+ static_assert(sizeof(conditional<true, int8_t, int16_t>::type) == sizeof(int8_t), "conditional failure");
+ static_assert(sizeof(conditional<false, int8_t, int16_t>::type) == sizeof(int16_t), "conditional failure");
+
+ // bool_constant
+ static_assert(bool_constant<is_same<int, int>::value>::value == true, "bool_constant failure");
+ static_assert(bool_constant<is_same<int, short>::value>::value == false, "bool_constant failure");
+ static_assert(is_same<bool_constant<false>::type, integral_constant<bool, false>::type>::value, "bool_constant failure");
+
+
+
+ // identity
+ static_assert(sizeof(identity<int>::type) == sizeof(int), "identity failure");
+ static_assert((is_same<int, identity<int>::type >::value == true), "identity failure");
+
+ // type_identity
+ static_assert(sizeof(type_identity<int>::type) == sizeof(int), "type_identity failure");
+ static_assert((is_same<int, type_identity<int>::type >::value == true), "type_identity failure");
+ static_assert(sizeof(type_identity_t<int>) == sizeof(int), "type_identity failure");
+ static_assert((is_same_v<int, type_identity_t<int>> == true), "type_identity failure");
+
+
+
+ // is_void
+ static_assert(is_void<void>::value == true, "is_void failure");
+ static_assert(is_void<const void>::value == true, "is_void failure");
+ static_assert(is_void<int>::value == false, "is_void failure");
+
+
+ // is_null_pointer
+ #if defined(EA_COMPILER_CPP11_ENABLED)
+ #if !defined(EA_COMPILER_NO_DECLTYPE) && !defined(_MSC_VER) // VS2012 is broken for just the case of decltype(nullptr).
+ static_assert(is_null_pointer<decltype(nullptr)>::value == true, "is_null_pointer failure");
+ static_assert(is_null_pointer<decltype(NULL)>::value == false, "is_null_pointer failure");
+ #endif
+ #if defined(EA_HAVE_nullptr_t_IMPL)
+ static_assert(is_null_pointer<std::nullptr_t>::value == true, "is_null_pointer failure"); // Can't enable this until we are using an updated <EABase/nullptr.h> that is savvy to C++11 clang (defines nullptr) being used with C++98 GNU libstdc++ (defines std::nullptr_t).
+ #endif
+ static_assert(is_null_pointer<void*>::value == false, "is_null_pointer failure");
+ static_assert(is_null_pointer<intptr_t>::value == false, "is_null_pointer failure");
+ #endif
+
+ // is_integral
+ static_assert(is_integral<int>::value == true, "is_integral failure");
+ EATEST_VERIFY(GetType(is_integral<int>()) == true);
+
+ static_assert(is_integral<const int>::value == true, "is_integral failure");
+ EATEST_VERIFY(GetType(is_integral<const int>()) == true);
+
+ static_assert(is_integral<float>::value == false, "is_integral failure");
+ EATEST_VERIFY(GetType(is_integral<float>()) == false);
+
+ static_assert(is_integral<bool>::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");
+ static_assert(is_integral<int>::value, "is_integral failure");
+ static_assert(is_integral<long long>::value, "is_integral failure");
+ static_assert(is_integral<long>::value, "is_integral failure");
+ static_assert(is_integral<short>::value, "is_integral failure");
+ static_assert(is_integral<signed char>::value, "is_integral failure");
+ static_assert(is_integral<unsigned char>::value, "is_integral failure");
+ static_assert(is_integral<unsigned int>::value, "is_integral failure");
+ static_assert(is_integral<unsigned long long>::value, "is_integral failure");
+ static_assert(is_integral<unsigned long>::value, "is_integral failure");
+ static_assert(is_integral<unsigned short>::value, "is_integral failure");
+#ifndef EA_WCHAR_T_NON_NATIVE // If wchar_t is a native type instead of simply a define to an existing type which is already handled...
+ static_assert(is_integral<wchar_t>::value, "is_integral failure");
+#endif
+
+
+ // is_floating_point
+ static_assert(is_floating_point<double>::value == true, "is_floating_point failure");
+ EATEST_VERIFY(GetType(is_floating_point<double>()) == true);
+
+ static_assert(is_floating_point<const double>::value == true, "is_floating_point failure");
+ EATEST_VERIFY(GetType(is_floating_point<const double>()) == true);
+
+ static_assert(is_floating_point<int>::value == false, "is_floating_point failure");
+ EATEST_VERIFY(GetType(is_floating_point<int>()) == false);
+
+
+ // is_arithmetic
+ static_assert(is_arithmetic<float>::value == true, "is_arithmetic failure");
+ static_assert(is_arithmetic_v<float> == true, "is_arithmetic failure");
+ EATEST_VERIFY(GetType(is_arithmetic<float>()) == true);
+
+ static_assert(is_arithmetic<Class>::value == false, "is_arithmetic failure");
+ static_assert(is_arithmetic_v<Class> == false, "is_arithmetic failure");
+ EATEST_VERIFY(GetType(is_arithmetic<Class>()) == false);
+
+
+ // is_fundamental
+ static_assert(is_fundamental<void>::value == true, "is_fundamental failure");
+ static_assert(is_fundamental_v<void> == true, "is_fundamental failure");
+ EATEST_VERIFY(GetType(is_fundamental<void>()) == true);
+
+ #ifndef EA_WCHAR_T_NON_NATIVE // If wchar_t is a native type instead of simply a define to an existing type which is already handled...
+ static_assert(is_fundamental<wchar_t>::value == true, "is_fundamental failure");
+ static_assert(is_fundamental_v<wchar_t> == true, "is_fundamental failure");
+ EATEST_VERIFY(GetType(is_fundamental<wchar_t>()) == true);
+ #endif
+
+ static_assert(is_fundamental<Class>::value == false, "is_fundamental failure");
+ static_assert(is_fundamental_v<Class> == false, "is_fundamental failure");
+ EATEST_VERIFY(GetType(is_fundamental<Class>()) == false);
+
+ static_assert(is_fundamental<std::nullptr_t>::value == true, "is_fundamental failure");
+ static_assert(is_fundamental_v<std::nullptr_t> == true, "is_fundamental failure");
+
+
+ // is_array
+ static_assert(is_array<Array>::value == true, "is_array failure");
+ EATEST_VERIFY(GetType(is_array<Array>()) == true);
+
+ static_assert(is_array<ArrayConst>::value == true, "is_array failure");
+ EATEST_VERIFY(GetType(is_array<ArrayConst>()) == true);
+
+ static_assert(is_array<int[]>::value == true, "is_array failure");
+
+ static_assert(is_array<uint32_t>::value == false, "is_array failure");
+ EATEST_VERIFY(GetType(is_array<uint32_t>()) == false);
+
+ static_assert(is_array<uint32_t*>::value == false, "is_array failure");
+ EATEST_VERIFY(GetType(is_array<uint32_t*>()) == false);
+
+
+ // is_reference
+ static_assert(is_reference<Class&>::value == true, "is_reference failure");
+ EATEST_VERIFY(GetType(is_reference<Class&>()) == true);
+
+ static_assert(is_reference<const Class&>::value == true, "is_reference failure");
+ EATEST_VERIFY(GetType(is_reference<const Class&>()) == true);
+
+ static_assert(is_reference<Class>::value == false, "is_reference failure");
+ EATEST_VERIFY(GetType(is_reference<Class>()) == false);
+
+ static_assert(is_reference<const Class*>::value == false, "is_reference failure");
+ EATEST_VERIFY(GetType(is_reference<const Class*>()) == false);
+
+
+ // is_member_function_pointer
+ 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");
+
+
+ // is_member_object_pointer
+ static_assert(is_member_object_pointer<int>::value == false, "is_member_object_pointer failure");
+ static_assert(is_member_object_pointer<int(Class::*)>::value == true, "is_member_object_pointer failure");
+ static_assert(is_member_object_pointer<int(Class::*)()>::value == false, "is_member_object_pointer failure");
+
+
+ // is_member_pointer
+ 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");
+
+
+ // is_pointer
+ static_assert(is_pointer<Class*>::value == true, "is_pointer failure");
+ static_assert(is_pointer<const Class*>::value == true, "is_pointer failure");
+ static_assert(is_pointer<Class>::value == false, "is_pointer failure");
+ static_assert(is_pointer<const Class&>::value == false, "is_pointer failure");
+ #if defined(EA_HAVE_nullptr_t_IMPL)
+ static_assert(is_pointer<std::nullptr_t>::value == false, "is_pointer failure");
+ #endif
+
+ // is_enum
+ static_assert(is_enum<Enum>::value == true, "is_enum failure ");
+ static_assert(is_enum_v<Enum> == true, "is_enum failure ");
+ EATEST_VERIFY(GetType(is_enum<Enum>()) == true);
+
+ static_assert(is_enum<const Enum>::value == true, "is_enum failure ");
+ static_assert(is_enum_v<const Enum> == true, "is_enum failure ");
+ EATEST_VERIFY(GetType(is_enum<const Enum>()) == true);
+
+ static_assert(is_enum<Enum*>::value == false, "is_enum failure ");
+ static_assert(is_enum_v<Enum*> == false, "is_enum failure ");
+ EATEST_VERIFY(GetType(is_enum<Enum*>()) == false);
+
+ static_assert(is_enum<Class>::value == false, "is_enum failure ");
+ static_assert(is_enum_v<Class> == false, "is_enum failure ");
+ EATEST_VERIFY(GetType(is_enum<Class>()) == false);
+
+
+ // is_union
+ static_assert(is_union<Union>::value == true, "is_union failure");
+ static_assert(is_union_v<Union> == true, "is_union failure");
+ EATEST_VERIFY(GetType(is_union<Union>()) == true);
+
+ static_assert(is_union<int>::value == false, "is_union failure");
+ static_assert(is_union_v<int> == false, "is_union failure");
+ EATEST_VERIFY(GetType(is_union<int>()) == false);
+
+
+ // is_class
+ static_assert(is_class<Class>::value == true, "is_class failure");
+ EATEST_VERIFY(GetType(is_class<Class>()) == true);
+
+ static_assert(is_class<Struct>::value == true, "is_class failure");
+ EATEST_VERIFY(GetType(is_class<Struct>()) == true);
+
+ static_assert(is_class<Union>::value == false, "is_class failure");
+ EATEST_VERIFY(GetType(is_class<Union>()) == false);
+
+ static_assert(is_class<Enum>::value == false, "is_class failure");
+ EATEST_VERIFY(GetType(is_class<Enum>()) == false);
+
+ static_assert(is_class<int*>::value == false, "is_class failure");
+ EATEST_VERIFY(GetType(is_class<int*>()) == false);
+
+
+ // 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<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");
+ static_assert(is_function<int>::value == false, "is_function failure");
+ static_assert(is_function<int[3]>::value == false, "is_function failure");
+ static_assert(is_function<int[]>::value == false, "is_function failure");
+ static_assert(is_function<Class>::value == false, "is_function failure");
+ #if EASTL_TYPE_TRAIT_is_function_CONFORMANCE
+ // 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_v<void> == false, "is_function failure");
+ static_assert(is_function_v<FunctionVoidVoid> == true, "is_function failure");
+ static_assert(is_function_v<FunctionVoidVoid&> == false, "is_function failure");
+ static_assert(is_function_v<FunctionIntVoid> == true, "is_function failure");
+ static_assert(is_function_v<FunctionIntFloat> == true, "is_function failure");
+ static_assert(is_function_v<FunctionVoidVoidPtr> == false, "is_function failure");
+ static_assert(is_function_v<int> == false, "is_function failure");
+ static_assert(is_function_v<int[3]> == false, "is_function failure");
+ static_assert(is_function_v<int[]> == false, "is_function failure");
+ static_assert(is_function_v<Class> == false, "is_function failure");
+ #if EASTL_TYPE_TRAIT_is_function_CONFORMANCE
+ // typedef int PrintfConst(const char*, ...) const;
+ static_assert(is_function_v<int (const char*, ...)> == true, "is_function failure"); // This is the signature of printf.
+ #endif
+
+
+ // is_object
+ static_assert(is_object<int>::value == true, "is_object failure");
+ EATEST_VERIFY(GetType(is_object<int>()) == true);
+
+ static_assert(is_object<Class>::value == true, "is_object failure");
+ EATEST_VERIFY(GetType(is_object<Class>()) == true);
+
+ static_assert(is_object<Class*>::value == true, "is_object failure");
+ EATEST_VERIFY(GetType(is_object<Class*>()) == true);
+
+ static_assert(is_object<Class&>::value == false, "is_object failure");
+ EATEST_VERIFY(GetType(is_object<Class&>()) == false);
+
+
+ // is_scalar
+ static_assert(is_scalar<int>::value == true, "is_scalar failure");
+ EATEST_VERIFY(GetType(is_scalar<int>()) == true);
+
+ static_assert(is_scalar<double>::value == true, "is_scalar failure");
+ EATEST_VERIFY(GetType(is_scalar<double>()) == true);
+
+ static_assert(is_scalar<Enum>::value == true, "is_scalar failure");
+ EATEST_VERIFY(GetType(is_scalar<Enum>()) == true);
+
+ static_assert(is_scalar<const Class*>::value == true, "is_scalar failure");
+ EATEST_VERIFY(GetType(is_scalar<const Class*>()) == true);
+
+ static_assert(is_scalar<std::nullptr_t>::value == true, "is_scalar failure");
+
+
+ // is_compound
+ static_assert(is_compound<Class>::value == true, "is_compound failure");
+ EATEST_VERIFY(GetType(is_compound<Class>()) == true);
+
+ static_assert(is_compound<const Class&>::value == true, "is_compound failure");
+ EATEST_VERIFY(GetType(is_compound<const Class&>()) == true);
+
+ static_assert(is_compound<int*>::value == true, "is_compound failure");
+ EATEST_VERIFY(GetType(is_compound<int*>()) == true);
+
+ static_assert(is_compound<float>::value == false, "is_compound failure");
+ EATEST_VERIFY(GetType(is_compound<float>()) == false);
+
+ static_assert(is_compound<bool>::value == false, "is_compound failure");
+ EATEST_VERIFY(GetType(is_compound<bool>()) == false);
+
+
+ // is_const
+ static_assert(is_const<Int>::value == false, "is_const failure");
+ EATEST_VERIFY(GetType(is_const<Int>()) == false);
+
+ static_assert(is_const<ConstInt>::value == true, "is_const failure");
+ EATEST_VERIFY(GetType(is_const<ConstInt>()) == true);
+
+ static_assert(is_const<VolatileInt>::value == false, "is_const failure");
+ EATEST_VERIFY(GetType(is_const<VolatileInt>()) == false);
+
+ static_assert(is_const<ConstVolatileInt>::value == true, "is_const failure");
+ EATEST_VERIFY(GetType(is_const<ConstVolatileInt>()) == true);
+
+ static_assert(is_const<IntReference>::value == false, "is_const failure");
+ EATEST_VERIFY(GetType(is_const<IntReference>()) == false);
+
+ static_assert(is_const<ConstIntReference>::value == false, "is_const failure"); // Note here that the int is const, not the reference to the int.
+ EATEST_VERIFY(GetType(is_const<ConstIntReference>()) == false);
+
+ 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);
+
+
+ // is_volatile
+ static_assert(is_volatile<Int>::value == false, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<Int>()) == false);
+
+ static_assert(is_volatile<ConstInt>::value == false, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<ConstInt>()) == false);
+
+ static_assert(is_volatile<VolatileInt>::value == true, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<VolatileInt>()) == true);
+
+ static_assert(is_volatile<ConstVolatileInt>::value == true, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<ConstVolatileInt>()) == true);
+
+ static_assert(is_volatile<IntReference>::value == false, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<IntReference>()) == false);
+
+ static_assert(is_volatile<ConstIntReference>::value == false, "is_volatile failure");
+ EATEST_VERIFY(GetType(is_volatile<ConstIntReference>()) == false);
+
+ 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);
+
+
+ // underlying_type
+ #if EASTL_TYPE_TRAIT_underlying_type_CONFORMANCE && !defined(EA_COMPILER_NO_STRONGLY_TYPED_ENUMS) // If we can execute this test...
+ enum UnderlyingTypeTest : uint16_t { firstVal = 0, secondVal = 1 };
+ static_assert(sizeof(underlying_type<UnderlyingTypeTest>::type) == sizeof(uint16_t), "underlying_type failure");
+ #endif
+
+
+ // is_literal_type
+ static_assert((is_literal_type<int>::value == true), "is_literal_type failure");
+ static_assert((is_literal_type<Enum>::value == true), "is_literal_type failure");
+ #if EASTL_TYPE_TRAIT_is_literal_type_CONFORMANCE
+ static_assert((is_literal_type<PodA>::value == true), "is_literal_type failure");
+ static_assert((is_literal_type<NonPod1>::value == false), "is_literal_type failure");
+ #endif
+
+
+ // is_trivial
+ // is_trivially_copyable
+ // is_trivially_default_constructible
+ #if EASTL_TYPE_TRAIT_is_trivial_CONFORMANCE
+ static_assert(is_trivial<Pod1>::value == true, "is_trivial failure");
+ static_assert(is_trivial<NonPod1>::value == false, "is_trivial failure");
+ #endif
+
+
+ // is_pod
+ static_assert(is_pod<Pod1>::value == true, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<Pod1>()) == true);
+
+ static_assert(is_pod<Pod2>::value == true, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<Pod2>()) == true);
+
+ static_assert(is_pod<Pod3>::value == true, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<Pod3>()) == true);
+
+ static_assert(is_pod<float>::value == true, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<float>()) == true);
+
+ static_assert(is_pod<Pod1*>::value == true, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<Pod1*>()) == true);
+
+ static_assert(is_pod<NonPod1>::value == false, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<NonPod1>()) == false);
+
+ static_assert(is_pod<NonPod2>::value == false, "is_pod failure");
+ EATEST_VERIFY(GetType(is_pod<NonPod2>()) == false);
+
+
+ // is_standard_layout
+ static_assert(is_standard_layout<Pod1>::value == true, "is_standard_layout<Pod1> failure");
+ static_assert(is_standard_layout_v<Pod1> == true, "is_standard_layout<Pod1> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<Pod1>()) == true);
+
+ static_assert(is_standard_layout<Pod2>::value == true, "is_standard_layout<Pod2> failure");
+ static_assert(is_standard_layout_v<Pod2> == true, "is_standard_layout<Pod2> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<Pod2>()) == true);
+
+ static_assert(is_standard_layout<Pod3>::value == true, "is_standard_layout<Pod3> failure");
+ static_assert(is_standard_layout_v<Pod3> == true, "is_standard_layout<Pod3> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<Pod3>()) == true);
+
+ static_assert(is_standard_layout<float>::value == true, "is_standard_layout<float> failure");
+ static_assert(is_standard_layout_v<float> == true, "is_standard_layout<float> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<float>()) == true);
+
+ static_assert(is_standard_layout<Pod1*>::value == true, "is_standard_layout<Pod1*> failure");
+ static_assert(is_standard_layout_v<Pod1*> == true, "is_standard_layout<Pod1*> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<Pod1*>()) == true);
+
+ static_assert(is_standard_layout<NonPod1>::value == false, "is_standard_layout<NonPod1> failure");
+ static_assert(is_standard_layout_v<NonPod1> == false, "is_standard_layout<NonPod1> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<NonPod1>()) == false);
+
+ static_assert(is_standard_layout<NonPod2>::value == false, "is_standard_layout<NonPod2> failure");
+ static_assert(is_standard_layout_v<NonPod2> == false, "is_standard_layout<NonPod2> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<NonPod2>()) == false);
+
+ static_assert(is_standard_layout<HasTrivialConstructor>::value == true, "is_standard_layout<HasTrivialConstructor> failure");
+ static_assert(is_standard_layout_v<HasTrivialConstructor> == true, "is_standard_layout<HasTrivialConstructor> failure");
+ EATEST_VERIFY(GetType(is_standard_layout<HasTrivialConstructor>()) == true);
+
+ static_assert(is_standard_layout<NoTrivialConstructor>::value == true, "is_standard_layout<NoTrivialConstructor> failure"); // A key difference between a POD and Standard Layout is that the latter is true if there is a constructor.
+ static_assert(is_standard_layout_v<NoTrivialConstructor> == true, "is_standard_layout<NoTrivialConstructor> failure"); // A key difference between a POD and Standard Layout is that the latter is true if there is a constructor.
+ EATEST_VERIFY(GetType(is_standard_layout<NoTrivialConstructor>()) == true);
+
+
+ // is_empty
+ static_assert(is_empty<ClassEmpty>::value == true, "is_empty failure");
+ EATEST_VERIFY(GetType(is_empty<ClassEmpty>()) == true);
+
+ static_assert(is_empty<ClassNonEmpty>::value == false, "is_empty failure");
+ EATEST_VERIFY(GetType(is_empty<ClassNonEmpty>()) == false);
+
+ static_assert(is_empty<int>::value == false, "is_empty failure");
+ EATEST_VERIFY(GetType(is_empty<int>()) == false);
+
+ static_assert(is_empty<Enum>::value == false, "is_empty failure");
+ EATEST_VERIFY(GetType(is_empty<Enum>()) == false);
+
+
+ // is_polymorphic
+ static_assert(is_polymorphic<Polymorphic1>::value == true, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(is_polymorphic<Polymorphic1>()) == true);
+
+ static_assert(is_polymorphic<Polymorphic2>::value == true, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(is_polymorphic<Polymorphic2>()) == true);
+
+ static_assert(is_polymorphic<Polymorphic3>::value == true, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(is_polymorphic<Polymorphic3>()) == true);
+
+ static_assert(is_polymorphic<NonPolymorphic1>::value == false, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(is_polymorphic<NonPolymorphic1>()) == false);
+
+ static_assert(is_polymorphic<int>::value == false, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(is_polymorphic<int>()) == false);
+
+ static_assert(is_polymorphic<Polymorphic1*>::value == false, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(is_polymorphic<Polymorphic1*>()) == false);
+
+
+ // has_trivial_constructor
+ static_assert(has_trivial_constructor<int>::value == true, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(has_trivial_constructor<int>()) == true);
+
+ static_assert(has_trivial_constructor<int*>::value == true, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(has_trivial_constructor<int*>()) == true);
+
+ static_assert(has_trivial_constructor<HasTrivialConstructor>::value == true, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(has_trivial_constructor<HasTrivialConstructor>()) == true);
+
+ static_assert(has_trivial_constructor<NoTrivialConstructor>::value == false, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(has_trivial_constructor<NoTrivialConstructor>()) == false);
+
+ static_assert(has_trivial_constructor<int&>::value == false, "has_trivial_constructor failure");
+ EATEST_VERIFY(GetType(has_trivial_constructor<int&>()) == false);
+
+
+ // has_trivial_copy
+ static_assert(has_trivial_copy<int>::value == true, "has_trivial_copy failure");
+ EATEST_VERIFY(GetType(has_trivial_copy<int>()) == true);
+
+ static_assert(has_trivial_copy<int*>::value == true, "has_trivial_copy failure");
+ EATEST_VERIFY(GetType(has_trivial_copy<int*>()) == true);
+
+ static_assert(has_trivial_copy<HasTrivialCopy>::value == true, "has_trivial_copy failure");
+ EATEST_VERIFY(GetType(has_trivial_copy<HasTrivialCopy>()) == true);
+
+ static_assert(has_trivial_copy<NoTrivialCopy1>::value == false, "has_trivial_copy failure");
+ EATEST_VERIFY(GetType(has_trivial_copy<NoTrivialCopy1>()) == false);
+
+ static_assert(has_trivial_copy<NoTrivialCopy2>::value == false, "has_trivial_copy failure");
+ EATEST_VERIFY(GetType(has_trivial_copy<NoTrivialCopy2>()) == false);
+
+
+ // has_trivial_assign
+ static_assert(has_trivial_assign<int>::value == true, "has_trivial_assign failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<int>()) == true);
+
+ static_assert(has_trivial_assign<int*>::value == true, "has_trivial_assign failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<int*>()) == true);
+
+ static_assert(has_trivial_assign<HasTrivialAssign>::value == true, "has_trivial_assign failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<HasTrivialAssign>()) == true);
+
+ static_assert(has_trivial_assign<NoTrivialAssign1>::value == false, "has_trivial_assign failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<NoTrivialAssign1>()) == false);
+
+ static_assert(has_trivial_assign<NoTrivialAssign2>::value == false, "has_trivial_assign failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<NoTrivialAssign2>()) == false);
+
+
+ // has_trivial_destructor
+ static_assert(has_trivial_assign<int>::value == true, "has_trivial_relocate failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<int>()) == true);
+
+ static_assert(has_trivial_assign<int*>::value == true, "has_trivial_relocate failure");
+ EATEST_VERIFY(GetType(has_trivial_assign<int*>()) == true);
+
+
+ // has_trivial_relocate
+ static_assert(has_trivial_relocate<int>::value == true, "has_trivial_relocate failure");
+ EATEST_VERIFY(GetType(has_trivial_relocate<int>()) == true);
+
+ static_assert(has_trivial_relocate<int*>::value == true, "has_trivial_relocate failure");
+ EATEST_VERIFY(GetType(has_trivial_relocate<int*>()) == true);
+
+
+ // is_signed
+ static_assert(is_signed<int>::value == true, "is_signed failure ");
+ static_assert(is_signed_v<int> == true, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<int>()) == true);
+
+ static_assert(is_signed<const int64_t>::value == true, "is_signed failure ");
+ static_assert(is_signed_v<const int64_t> == true, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<const int64_t>()) == true);
+
+ static_assert(is_signed<uint32_t>::value == false, "is_signed failure ");
+ static_assert(is_signed_v<uint32_t> == false, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<uint32_t>()) == false);
+
+ static_assert(is_signed<bool>::value == false, "is_signed failure ");
+ static_assert(is_signed_v<bool> == false, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<bool>()) == false);
+
+ static_assert(is_signed<float>::value == true, "is_signed failure ");
+ static_assert(is_signed_v<float> == true, "is_signed failure ");
+ EATEST_VERIFY(GetType(is_signed<float>()) == true);
+
+ 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);
+
+
+ // is_unsigned
+ static_assert(is_unsigned<unsigned int>::value == true, "is_unsigned failure ");
+ static_assert(is_unsigned_v<unsigned int> == true, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<unsigned int>()) == true);
+
+ static_assert(is_unsigned<const uint64_t>::value == true, "is_unsigned failure ");
+ static_assert(is_unsigned_v<const uint64_t> == true, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<const uint64_t>()) == true);
+
+ static_assert(is_unsigned<int32_t>::value == false, "is_unsigned failure ");
+ 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<float>::value == false, "is_unsigned failure ");
+ static_assert(is_unsigned_v<float> == false, "is_unsigned failure ");
+ EATEST_VERIFY(GetType(is_unsigned<float>()) == false);
+
+ 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);
+
+
+ // is_lvalue_reference
+ static_assert((is_lvalue_reference<Class>::value == false), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference<Class&>::value == true), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference<Class&&>::value == false), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference<int>::value == false), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference<int&>::value == true), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference<int&&>::value == false), "is_lvalue_reference failure");
+
+ static_assert((is_lvalue_reference_v<Class> == false), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference_v<Class&> == true), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference_v<Class&&> == false), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference_v<int> == false), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference_v<int&> == true), "is_lvalue_reference failure");
+ static_assert((is_lvalue_reference_v<int&&> == false), "is_lvalue_reference failure");
+
+
+ // is_rvalue_reference
+ static_assert((is_rvalue_reference<Class>::value == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference<Class&>::value == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference<Class&&>::value == true), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference<int>::value == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference<int&>::value == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference<int&&>::value == true), "is_rvalue_reference failure");
+
+ static_assert((is_rvalue_reference_v<Class> == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference_v<Class&> == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference_v<Class&&> == true), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference_v<int> == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference_v<int&> == false), "is_rvalue_reference failure");
+ static_assert((is_rvalue_reference_v<int&&> == true), "is_rvalue_reference failure");
+
+
+ // is_assignable
+ // See the documentation for is_assignable to understand the results below are as they are.
+ static_assert((eastl::is_assignable<int&, int>::value == true), "is_assignable failure");
+ static_assert((eastl::is_assignable<const int&, int>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<char*, int*>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<char*, const char*>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<PodA, PodB*>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<Assignable, Pod2>::value == false), "is_assignable failure");
+
+ #if EASTL_TYPE_TRAIT_is_assignable_CONFORMANCE
+ // These might not succeed unless the implementation is conforming.
+ static_assert((eastl::is_assignable<Assignable, Assignable>::value == true), "is_assignable failure");
+ static_assert((eastl::is_assignable<Assignable, Pod1>::value == true), "is_assignable failure");
+ static_assert((eastl::is_assignable<PodA&, PodA>::value == true), "is_assignable failure");
+
+ // These cannot succeed unless the implementation is conforming.
+ static_assert((eastl::is_assignable<void, void>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<int, int>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<int, const int>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<const int, int>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<int, int&>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<int64_t, int8_t>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<bool, bool>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<char*, char*>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<int, float>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<const char*, char*>::value == false), "is_assignable failure");
+ static_assert((eastl::is_assignable<int[], int[]>::value == false), "is_assignable failure");
+ #endif
+
+
+ // is_lvalue_assignable
+ static_assert((eastl::is_lvalue_assignable<int&, int>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<char*, int*>::value == false), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<char*, const char*>::value == false), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<PodA, PodB*>::value == false), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<Assignable, Pod2>::value == false), "is_lvalue_assignable failure");
+
+ #if EASTL_TYPE_TRAIT_is_lvalue_assignable_CONFORMANCE
+ // These might not succeed unless the implementation is conforming.
+ static_assert((eastl::is_lvalue_assignable<Assignable, Assignable>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<Assignable, Pod1>::value == true), "is_lvalue_assignable failure");
+
+ // These cannot succeed unless the implementation is conforming.
+ static_assert((eastl::is_lvalue_assignable<void, void>::value == false), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<int, int>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<int, const int>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<const int, int>::value == false), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<int, int&>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<int64_t, int8_t>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<bool, bool>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<char*, char*>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<const char*, char*>::value == true), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<int[], int[]>::value == false), "is_lvalue_assignable failure");
+ static_assert((eastl::is_lvalue_assignable<int[3], int[3]>::value == false), "is_lvalue_assignable failure"); // Despite that you can memcpy these, C++ syntax doesn't all =-based assignment.
+
+ #if !defined(EA_COMPILER_EDG) // EDG (and only EDG) is issuing int8_t->double conversion warnings from the decltype expression inside this trait. That's probably a compiler bug, though we need to verify.
+ static_assert((eastl::is_lvalue_assignable<double, int8_t>::value == true), "is_lvalue_assignable failure"); // Sure this might generate a warning, but it's valid syntax.
+ #endif
+ #endif
+
+
+ // is_copy_assignable
+ static_assert((eastl::is_copy_assignable<int&>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<char>::value == true), "is_copy_assignable failure");
+
+ #if EASTL_TYPE_TRAIT_is_assignable_CONFORMANCE
+ // These might not succeed unless the implementation is conforming.
+ static_assert((eastl::is_copy_assignable<Assignable>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<Assignable>::value == true), "is_copy_assignable failure");
+
+ // These cannot succeed unless the implementation is conforming.
+ static_assert((eastl::is_copy_assignable<char*>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<PodA>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<Assignable>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<void>::value == false), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<int>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<const int>::value == false), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<int64_t>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<bool>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<char*>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<const char*>::value == true), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<int[3]>::value == false), "is_copy_assignable failure");
+ static_assert((eastl::is_copy_assignable<int[]>::value == false), "is_copy_assignable failure");
+ #endif
+
+
+ // is_trivially_assignable
+ static_assert((eastl::is_trivially_assignable<int&, int>::value == true), "is_trivially_assignable failure");
+ static_assert((eastl::is_trivially_assignable<char*, int*>::value == false), "is_trivially_assignable failure");
+ static_assert((eastl::is_trivially_assignable<char*, const char*>::value == false), "is_trivially_assignable failure");
+ static_assert((eastl::is_trivially_assignable<PodA, PodB*>::value == false), "is_trivially_assignable failure");
+ static_assert((eastl::is_trivially_assignable<Assignable, Assignable>::value == false), "is_trivially_assignable failure"); // False because not trivial.
+ static_assert((eastl::is_trivially_assignable<Assignable, Pod1>::value == false), "is_trivially_assignable failure"); // False because not trivial.
+ static_assert((eastl::is_trivially_assignable<Assignable, Pod2>::value == false), "is_trivially_assignable failure");
+
+ // is_nothrow_assignable
+ static_assert((is_nothrow_assignable<void, void>::value == false), "is_nothrow_assignable failure");
+ static_assert((is_nothrow_assignable<int32_t, int32_t>::value == false), "is_nothrow_assignable failure"); // See is_assignable for why this is so.
+ static_assert((is_nothrow_assignable<int32_t&, int32_t>::value == true), "is_nothrow_assignable failure");
+ static_assert((is_nothrow_assignable<int32_t, int8_t>::value == false), "is_nothrow_assignable failure");
+ #if EASTL_TYPE_TRAIT_is_nothrow_assignable_CONFORMANCE
+ static_assert((is_nothrow_assignable<int32_t&, int8_t>::value == true), "is_nothrow_assignable failure");
+ static_assert((is_nothrow_assignable<NoThrowAssignable, NoThrowAssignable>::value == true), "is_nothrow_assignable failure");
+ static_assert((is_nothrow_assignable<ThrowAssignableTest, NoThrowAssignable>::value == true), "is_nothrow_assignable failure");
+ static_assert((is_nothrow_assignable<ThrowAssignableTest, ThrowAssignableTest>::value == false), "is_nothrow_assignable failure");
+ #endif
+
+
+ // is_array_of_known_bounds
+ // is_array_of_unknown_bounds
+ static_assert(is_array_of_known_bounds<void>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_known_bounds<int>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_known_bounds<PodA>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_known_bounds<int[3]>::value == true, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_known_bounds<int[]>::value == false, "is_array_of_known_bounds failure");
+
+ static_assert(is_array_of_unknown_bounds<void>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_unknown_bounds<int>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_unknown_bounds<PodA>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_unknown_bounds<int[3]>::value == false, "is_array_of_known_bounds failure");
+ static_assert(is_array_of_unknown_bounds<int[]>::value == true, "is_array_of_known_bounds failure");
+
+
+ // is_trivially_copyable
+ static_assert(is_trivially_copyable<void>::value == false, "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");
+ static_assert(is_trivially_copyable<int[]>::value == true, "is_trivially_copyable failure");
+ static_assert(is_trivially_copyable<int[4]>::value == true, "is_trivially_copyable failure");
+ #if EASTL_TYPE_TRAIT_is_trivially_copyable_CONFORMANCE
+ static_assert(is_trivially_copyable<NonPod1>::value == false, "is_trivially_copyable failure");
+ static_assert(is_trivially_copyable<NoTrivialCopy1>::value == false, "is_trivially_copyable failure");
+ static_assert(is_trivially_copyable<PodA>::value == true, "is_trivially_copyable failure");
+ #endif
+
+ { // user reported regression
+ struct Foo
+ {
+ int a;
+ Foo(int i) : a(i) {}
+ Foo(Foo&& other) : a(other.a) { other.a = 0; }
+
+ Foo(const Foo&) = delete;
+ Foo& operator=(const Foo&) = delete;
+ };
+
+ static_assert(!eastl::is_trivially_copyable<Foo>::value, "is_trivially_copyable failure");
+ }
+
+
+ // is_trivially_copy_assignable
+ {
+ static_assert(is_trivially_copy_assignable<int>::value == true, "is_trivially_copy_assignable failure");
+ static_assert(is_trivially_copy_assignable<char*>::value == true, "is_trivially_copy_assignable failure");
+ static_assert(is_trivially_copy_assignable<const char*>::value == true, "is_trivially_copy_assignable failure");
+ static_assert(is_trivially_copy_assignable<NoTrivialCopy1>::value == false, "is_trivially_copy_assignable failure");
+
+ #ifdef INTENTIONALLY_DISABLED
+ // These tests currently fail on clang, but they would pass using the std::is_trivially_copy_assignable trait. We should
+ // determine if our implementation is correct, or if clang is actually incorrect.
+ static_assert(is_trivially_copy_assignable<const int>::value == true, "is_trivially_copy_assignable failure");
+ static_assert(is_trivially_copy_assignable<const PodA>::value == true, "is_trivially_copy_assignable failure");
+ static_assert(is_trivially_copy_assignable<PodA>::value == true, "is_trivially_copy_assignable failure");
+ #endif
+ }
+ // is_trivially_default_constructible
+ // To do.
+
+
+ // is_trivial
+ // To do.
+
+
+ // is_constructible
+ static_assert(is_constructible<void>::value == false, "is_constructible failure");
+ static_assert(is_constructible<const void>::value == false, "is_constructible failure");
+ static_assert(is_constructible<int>::value == true, "is_constructible failure");
+ static_assert(is_constructible<int&>::value == false, "is_constructible failure");
+ static_assert(is_constructible<int*>::value == true, "is_constructible failure");
+ static_assert(is_constructible<int[]>::value == false, "is_constructible failure");
+ static_assert(is_constructible<int[4]>::value == true, "is_constructible failure");
+ static_assert(is_constructible<NonPod1>::value == true, " is_constructible failure");
+ static_assert(is_constructible<NoTrivialCopy1>::value == true, "is_constructible failure");
+ static_assert(is_constructible<PodA>::value == true, "is_constructible failure");
+ static_assert(is_constructible<Abstract>::value == false, "is_constructible failure");
+ static_assert(is_constructible<NonCopyable>::value == true, "is_constructible failure");
+ #if EASTL_TYPE_TRAIT_is_trivially_constructible_CONFORMANCE
+ static_assert((is_constructible<int, const int>::value == true), "is_constructible failure");
+ static_assert((is_constructible<char*, const char*>::value == false), "is_constructible failure");
+ static_assert((is_constructible<char*, char* const>::value == true), "is_constructible failure");
+ static_assert((is_constructible<ThrowConstructibleTest, int>::value == true), "is_constructible failure");
+ static_assert((is_constructible<ThrowConstructibleTest, float>::value == true), "is_constructible failure");
+ #endif
+
+
+ // is_trivially_constructible
+ // Need double parentheses because some older compilers need static_assert implemented as a macro.
+ static_assert((is_trivially_constructible<void>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<void, void>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<void, int>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int>::value == true), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int, int>::value == true), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int, Abstract>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int*>::value == true), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int[]>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int[], int[]>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int[4]>::value == true), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<int[4], int[]>::value == false), "is_trivially_constructible failure");
+ #if EASTL_TYPE_TRAIT_is_trivially_constructible_CONFORMANCE
+ static_assert((is_trivially_constructible<NoTrivialCopy1>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<PodA>::value == true), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<PodA, PodA>::value == true), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<Abstract>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<NonPod1>::value == false), "is_trivially_constructible failure");
+ static_assert((is_trivially_constructible<NoTrivialConstructor>::value == false), "is_trivially_constructible failure");
+ #endif
+
+
+ // is_nothrow_constructible
+ static_assert((is_nothrow_constructible<void>::value == false), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<int>::value == true), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<int*>::value == true), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<int[4]>::value == true), "is_nothrow_constructible failure");
+ #if EASTL_TYPE_TRAIT_is_nothrow_constructible_CONFORMANCE
+ static_assert((is_nothrow_constructible<int[]>::value == false), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<Abstract>::value == false), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<int, const int>::value == true), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<char*, const char*>::value == false), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<char*, char* const>::value == true), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<NonPod1>::value == false), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<PodA>::value == true), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<ThrowConstructibleTest, int>::value == true), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<ThrowConstructibleTest, float>::value == false), "is_nothrow_constructible failure");
+ static_assert((is_nothrow_constructible<NoTrivialCopy1>::value == true), "is_nothrow_constructible failure"); //True because it's a compiler-generated constructor.
+ #endif
+
+
+ // is_nothrow_move_constructible
+#if !defined(EA_PLATFORM_MICROSOFT)
+ static_assert((is_nothrow_move_constructible<void>::value == false), "is_nothrow_move_constructible failure");
+ static_assert((is_nothrow_move_constructible<int>::value == true), "is_nothrow_move_constructible failure");
+ static_assert((is_nothrow_move_constructible<int*>::value == true), "is_nothrow_move_constructible failure");
+ static_assert((is_nothrow_move_constructible<const int*>::value == true), "is_nothrow_move_constructible failure");
+ static_assert((is_nothrow_move_constructible<int&>::value == true), "is_nothrow_move_constructible failure");
+ static_assert((is_nothrow_move_constructible<double>::value == true), "is_nothrow_move_constructible failure");
+ static_assert((is_nothrow_move_constructible<ClassEmpty>::value == true), "is_nothrow_move_constructible failure");
+#endif
+
+
+ // is_copy_constructible
+ static_assert((is_copy_constructible<void>::value == false), "is_copy_constructible failure");
+ #if EASTL_TYPE_TRAIT_is_copy_constructible_CONFORMANCE
+ static_assert((is_copy_constructible<int>::value == true), "is_copy_constructible failure");
+ static_assert((is_copy_constructible<char*>::value == true), "is_copy_constructible failure");
+ static_assert((is_copy_constructible<int&>::value == true), "is_copy_constructible failure"); // As of this writing, GCC's libstdc++ reports true for this. I'm trying to find what's correct.
+ static_assert((is_copy_constructible<const int>::value == true), "is_copy_constructible failure");
+ static_assert((is_copy_constructible<HasTrivialCopy>::value == true), "is_copy_constructible failure");
+
+ #if !defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_MSVC) // EDG (and only EDG) is generating warnings about the decltype expression referencing a deleted constructor. This seems like a bug, though we need to verify.
+ // EA_COMPILER_MSVC is disabled because VS2013 fails this test and it may be that EASTL_TYPE_TRAIT_is_copy_constructible_CONFORMANCE should really be 0 for VS2013.
+ static_assert((is_copy_constructible<ConstructibleOnlyWithNonConstReference>::value == false), "is_copy_constructible failure");
+ #endif
+ #endif
+
+
+ // is_destructible
+ 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.
+ #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
+ static_assert(is_destructible<NonPod2>::value == true, "is_destructible failure");
+
+
+ // is_trivially_destructible
+ static_assert(is_trivially_destructible<int>::value == true, "is_trivially_destructible failure");
+ static_assert(is_trivially_destructible<char>::value == true, "is_trivially_destructible failure");
+ static_assert(is_trivially_destructible<char*>::value == true, "is_trivially_destructible failure");
+ static_assert(is_trivially_destructible<void>::value == false, "is_trivially_destructible failure");
+ #if EASTL_TYPE_TRAIT_is_trivially_destructible_CONFORMANCE
+ 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<DeletedDtor>::value == false, "is_trivially_destructible failure");
+ 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<void>::value == false, "is_nothrow_destructible failure");
+ #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");
+ #endif
+ #if EASTL_TYPE_TRAIT_is_nothrow_destructible_CONFORMANCE && !defined(EA_COMPILER_NO_EXCEPTIONS)
+ static_assert(is_nothrow_destructible<ThrowDestructible>::value == false, "is_nothrow_destructible failure");
+ static_assert(is_nothrow_destructible<ThrowDestructibleNoexceptFalse>::value == false, "is_nothrow_destructible failure");
+ #endif
+
+
+ // alignment_of
+ #if !defined(EA_ABI_ARM_APPLE) // Apple on ARM (i.e. iPhone/iPad) doesn't align 8 byte types on 8 byte boundaries, and the hardware allows it.
+ static_assert(alignment_of<uint64_t>::value == 8, "alignment_of failure");
+ EATEST_VERIFY(GetType(alignment_of<uint64_t>()) == 8);
+ #endif
+
+ static_assert(alignment_of<ClassAlign32>::value == 32, "alignment_of failure");
+ EATEST_VERIFY(GetType(alignment_of<ClassAlign32>()) == 32);
+
+
+ // common_type
+ static_assert((is_same<common_type<NonPod2*>::type, NonPod2*>::value), "common_type failure");
+ static_assert((is_same<common_type<int>::type, int>::value), "common_type failure");
+ static_assert((is_same<common_type<void, void>::type, void>::value), "common_type failure");
+ static_assert((is_same<common_type<int, int>::type, int>::value), "common_type failure");
+
+
+ // rank
+ static_assert(rank<int[1][2][3][4][5][6]>::value == 6, "rank failure");
+ static_assert(rank<int[][1][2]>::value == 3, "rank failure");
+ static_assert(rank<int>::value == 0, "rank failure");
+ static_assert(rank<void>::value == 0, "rank failure");
+
+ static_assert(rank_v<int[1][2][3][4][5][6]> == 6, "rank failure");
+ static_assert(rank_v<int[][1][2]> == 3, "rank failure");
+ static_assert(rank_v<int> == 0, "rank failure");
+ static_assert(rank_v<void> == 0, "rank failure");
+
+
+
+ // extent
+ static_assert((extent<int> ::value == 0), "extent failure");
+ static_assert((extent<int[2]> ::value == 2), "extent failure");
+ static_assert((extent<int[2][4]> ::value == 2), "extent failure");
+ static_assert((extent<int[]> ::value == 0), "extent failure");
+ static_assert((extent<int[][4]> ::value == 0), "extent failure");
+ static_assert((extent<int, 1> ::value == 0), "extent failure");
+ static_assert((extent<int[2], 1> ::value == 0), "extent failure");
+ static_assert((extent<int[2][4], 1>::value == 4), "extent failure");
+ static_assert((extent<int[][4], 1> ::value == 4), "extent failure");
+
+ static_assert((extent_v<int> == 0), "extent failure");
+ static_assert((extent_v<int[2]> == 2), "extent failure");
+ static_assert((extent_v<int[2][4]> == 2), "extent failure");
+ static_assert((extent_v<int[]> == 0), "extent failure");
+ static_assert((extent_v<int[][4]> == 0), "extent failure");
+ static_assert((extent_v<int, 1> == 0), "extent failure");
+ static_assert((extent_v<int[2], 1> == 0), "extent failure");
+ static_assert((extent_v<int[2][4], 1> == 4), "extent failure");
+ static_assert((extent_v<int[][4], 1> == 4), "extent failure");
+
+
+
+ // is_aligned
+ static_assert(is_aligned<uint8_t>::value == false, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<uint8_t>()) == false);
+
+ static_assert(is_aligned<uint16_t>::value == false, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<uint16_t>()) == false);
+
+ static_assert(is_aligned<uint32_t>::value == false, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<uint32_t>()) == false);
+
+ static_assert(is_aligned<uint64_t>::value == false, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<uint64_t>()) == false);
+
+ static_assert(is_aligned<uint64_t>::value == false, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<uint64_t>()) == false);
+
+ {
+ #if (kEASTLTestAlign16 == 16) // To do: Rename kEASTLTestAlign16, as what it really means is "is 16 byte alignment+ supported".
+ static_assert(is_aligned<Align16>::value, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<Align16>()));
+
+
+ static_assert(is_aligned<Align32>::value, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<Align32>()));
+
+ static_assert(is_aligned<Align64>::value, "is_aligned failure");
+ EATEST_VERIFY(GetType(is_aligned<Align64>()));
+ #endif
+ }
+
+
+ // is_same
+ static_assert((is_same<uint32_t, uint32_t>::value == true), "is_same failure");
+ static_assert((is_same<void, void>::value == true), "is_same failure");
+ static_assert((is_same<void*, void*>::value == true), "is_same failure");
+ static_assert((is_same<uint64_t, uint64_t>::value == true), "is_same failure");
+ static_assert((is_same<Class, Class>::value == true), "is_same failure");
+ static_assert((is_same<uint64_t, uint32_t>::value == false), "is_same failure");
+ static_assert((is_same<Class, ClassAlign32>::value == false), "is_same failure");
+
+ static_assert((is_same_v<uint32_t, uint32_t> == true), "is_same_v failure");
+ static_assert((is_same_v<void, void> == true), "is_same_v failure");
+ static_assert((is_same_v<void*, void*> == true), "is_same_v failure");
+ static_assert((is_same_v<uint64_t, uint64_t> == true), "is_same_v failure");
+ static_assert((is_same_v<Class, Class> == true), "is_same_v failure");
+ static_assert((is_same_v<uint64_t, uint32_t> == false), "is_same_v failure");
+ static_assert((is_same_v<Class, ClassAlign32> == false), "is_same_v failure");
+
+
+
+ // is_convertible
+ static_assert((is_convertible<uint16_t, uint32_t>::value == true), "is_convertible failure");
+ static_assert((is_convertible<int32_t, int16_t>::value == true), "is_convertible failure"); // This is a conversion from 32 bits down to 16 bits. All compilers natively report that this is true. However, VC++ generates warnings for actual such conversions.
+ static_assert((is_convertible<Subclass, Class>::value == true), "is_convertible failure");
+ static_assert((is_convertible<Subclass*, Class*>::value == true), "is_convertible failure");
+ static_assert((is_convertible<Subclass&, const Class&>::value == true), "is_convertible failure");
+ static_assert((is_convertible<int, Class>::value == false), "is_convertible failure");
+ static_assert((is_convertible<NonPod1, NonPod1>::value == true), "is_convertible failure");
+ static_assert((is_convertible<NonPod1, NonPod2>::value == false), "is_convertible failure");
+ #if EASTL_TYPE_TRAIT_is_convertible_CONFORMANCE // This causes compile failures.
+ static_assert((is_convertible<IsConvertibleTest1, IsConvertibleTest1>::value == false), "is_convertible failure");
+ #endif
+
+ // Test EASTL_DECLARE_TRIVIAL_ASSIGN(HiddenAssign);
+ eastl::vector<HiddenAssign> v;
+ EATEST_VERIFY(v.empty());
+
+
+ // make_signed
+ // make_unsigned
+ {
+ // Test declarations
+ eastl::make_signed<int8_t>::type i8 = -1;
+ EATEST_VERIFY(i8 == -1);
+ eastl::make_unsigned<uint8_t>::type u8 = 0xff;
+ EATEST_VERIFY(u8 == 0xff);
+
+ eastl::make_signed<int16_t>::type i16 = -1;
+ EATEST_VERIFY(i16 == -1);
+ eastl::make_unsigned<uint16_t>::type u16 = 0xffff;
+ EATEST_VERIFY(u16 == 0xffff);
+
+ eastl::make_signed<int32_t>::type i32 = -1;
+ EATEST_VERIFY(i32 == -1);
+ eastl::make_unsigned<uint32_t>::type u32 = 0xffffffff;
+ EATEST_VERIFY(u32 == 0xffffffff);
+
+ eastl::make_signed<int64_t>::type i64 = -1;
+ EATEST_VERIFY(i64 == -1);
+ eastl::make_unsigned<uint64_t>::type u64 = UINT64_C(0xffffffffffffffff);
+ EATEST_VERIFY(u64 == UINT64_C(0xffffffffffffffff));
+
+ // Test conversions via static_cast:
+ u8 = static_cast<eastl::make_unsigned<uint8_t>::type>(i8);
+ EATEST_VERIFY(u8 == 0xff);
+ i8 = static_cast<eastl::make_signed<int8_t>::type>(u8);
+ EATEST_VERIFY(i8 == -1);
+
+ u16 = static_cast<eastl::make_unsigned<uint16_t>::type>(i16);
+ EATEST_VERIFY(u16 == 0xffff);
+ i16 = static_cast<eastl::make_signed<int16_t>::type>(u16);
+ EATEST_VERIFY(i16 == -1);
+
+ u32 = static_cast<eastl::make_unsigned<uint32_t>::type>(i32);
+ EATEST_VERIFY(u32 == 0xffffffff);
+ i32 = static_cast<eastl::make_signed<int32_t>::type>(u32);
+ EATEST_VERIFY(i32 == -1);
+
+ u64 = static_cast<eastl::make_unsigned<uint64_t>::type>(i64);
+ EATEST_VERIFY(u64 == UINT64_C(0xffffffffffffffff));
+ i64 = static_cast<eastl::make_signed<int64_t>::type>(u64);
+ EATEST_VERIFY(i64 == -1);
+ }
+
+ // remove_const
+ // remove_volatile
+ // remove_cv
+ {
+ // To do: Make more thorough tests verifying this. Such tests will probably involve template metaprogramming.
+ remove_const<const int32_t>::type i32 = 47;
+ EATEST_VERIFY(++i32 == 48);
+
+ remove_volatile<volatile int16_t>::type i16 = 47;
+ EATEST_VERIFY(++i16 == 48);
+
+ remove_cv<const volatile int32_t>::type i64 = 47;
+ EATEST_VERIFY(++i64 == 48);
+
+ //static_assert(is_same<std::remove_cv<int (int, ...)>::type , std::remove_cv<int (int, ...) const>::type>::value, "remove_cv failure");
+ }
+
+ // remove_cvref
+ {
+ static_assert(is_same_v<remove_cvref_t<int>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int&>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int&&>, int>, "remove_cvref failure");
+
+ static_assert(is_same_v<remove_cvref_t<const int>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<const int&>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<const int&&>, int>, "remove_cvref failure");
+
+ static_assert(is_same_v<remove_cvref_t<volatile int>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<volatile int&>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<volatile int&&>, int>, "remove_cvref failure");
+
+ static_assert(is_same_v<remove_cvref_t<const volatile int>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<const volatile int&>, int>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<const volatile int&&>, int>, "remove_cvref failure");
+
+ // test pointer types
+ static_assert(is_same_v<remove_cvref_t<int*>, int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int*&>, int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int*&&>, int*>, "remove_cvref failure");
+
+ static_assert(is_same_v<remove_cvref_t<const int*>, const int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<const int*&>, const int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<const int*&&>, const int*>, "remove_cvref failure");
+
+ static_assert(is_same_v<remove_cvref_t<int* const>, int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int* const&>, int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int* const&&>, int*>, "remove_cvref failure");
+
+ static_assert(is_same_v<remove_cvref_t<int* const volatile>, int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int* const volatile&>, int*>, "remove_cvref failure");
+ static_assert(is_same_v<remove_cvref_t<int* const volatile&&>, int*>, "remove_cvref failure");
+ }
+
+
+ // add_const
+ // add_volatile
+ // add_cv
+ {
+ // To do: Make more thorough tests verifying this. Such tests will probably involve template metaprogramming.
+ eastl::add_const<int32_t>::type i32 = 47;
+ EATEST_VERIFY(i32 == 47);
+
+ eastl::add_volatile<volatile int16_t>::type i16 = 47;
+ EATEST_VERIFY(++i16 == 48);
+
+ eastl::add_cv<const volatile int32_t>::type i64 = 47;
+ EATEST_VERIFY(i64 == 47);
+ }
+
+
+ // as_const
+ {
+ {
+ int i = 42;
+ static_assert(eastl::is_same<decltype(eastl::as_const(i)), const int&>::value, "expecting a 'const T&' return type");
+ EATEST_VERIFY(eastl::as_const(i) == 42);
+ }
+
+ {
+ eastl::string str = "Electronic Arts";
+ static_assert(eastl::is_same<decltype(eastl::as_const(str)), const eastl::string&>::value, "expecting a 'const T&' return type");
+ EATEST_VERIFY(eastl::as_const(str) == "Electronic Arts");
+ }
+ }
+
+
+ // remove_reference
+ // add_reference
+ // remove_pointer
+ // add_pointer
+ // remove_extent
+ // remove_all_extents
+ {
+ int x = 17;
+ eastl::add_reference<int>::type xRef = x;
+ x++;
+ EATEST_VERIFY(xRef == 18);
+
+ eastl::remove_reference<int&>::type xValue;
+ xValue = 3;
+ EATEST_VERIFY(xValue == 3);
+
+ eastl::add_pointer<int>::type xPtr = &x;
+ *xPtr = 19;
+ EATEST_VERIFY(x == 19);
+
+ eastl::remove_pointer<int*>::type yValue;
+ yValue = 3;
+ EATEST_VERIFY(yValue == 3);
+
+ // 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.
+ typedef int IntArray1[37];
+ typedef eastl::remove_extent<IntArray1>::type Int;
+ static_assert((eastl::is_same<Int, int>::value == true), "remove_extent/is_same failure");
+
+ // remove_all_extents
+ typedef int IntArray2[37][54];
+ typedef eastl::remove_all_extents<IntArray2>::type Int2;
+ static_assert((eastl::is_same<Int2, int>::value == true), "remove_all_extents/is_same failure");
+ }
+
+
+ // decay
+ {
+ static_assert((eastl::is_same<uint32_t, eastl::decay<uint32_t>::type>::value == true), "is_same failure");
+ static_assert((eastl::is_same<uint32_t, eastl::decay<const uint32_t>::type>::value == true), "is_same failure");
+ static_assert((eastl::is_same<uint32_t, eastl::decay<volatile uint32_t>::type>::value == true), "is_same failure");
+ static_assert((eastl::is_same<uint32_t, eastl::decay<uint32_t&>::type>::value == true), "is_same failure");
+ static_assert((eastl::is_same<uint32_t, eastl::decay<const uint32_t&>::type>::value == true), "is_same failure");
+ static_assert((eastl::is_same<uint32_t, eastl::decay<const volatile uint32_t&>::type>::value == true), "is_same failure");
+ #if !EASTL_NO_RVALUE_REFERENCES
+ static_assert((eastl::is_same<uint32_t, eastl::decay<uint32_t&&>::type>::value == true), "is_same failure");
+ #endif
+ static_assert((eastl::is_same<uint32_t*, eastl::decay<uint32_t[3]>::type>::value == true), "is_same failure");
+ static_assert((eastl::is_same<uint32_t(*)(char), eastl::decay<uint32_t(char)>::type>::value == true), "is_same failure");
+ }
+
+
+ // aligned_storage
+ // Some compilers don't support or ignore alignment specifications for stack variables,
+ // so we limit our testing to compilers that are known to support it.
+ #if (EA_ALIGN_MAX_AUTOMATIC >= 64) && defined(EA_PLATFORM_DESKTOP) // Actually there are additional compilers that support alignment of stack-based variables, most significantly clang, GCC 4.4+, and probably others.
+ {
+ // Test the creation of a single aligned value.
+ const size_t kArraySize = 100;
+ const size_t kExpectedAlignment = 64;
+ typedef uint16_t Type;
+
+ eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type data;
+ Type* value = new(&data) Type;
+ *value = 37;
+ EATEST_VERIFY_F((EA::StdC::GetAlignment(value) >= kExpectedAlignment) && (*value == 37),
+ "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(value));
+
+ // Create an array of 100 values aligned.
+ eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type dataArray[kArraySize];
+ Type* valueArray = new(dataArray) Type[kArraySize];
+ valueArray[0] = 37;
+ EATEST_VERIFY_F((EA::StdC::GetAlignment(valueArray) >= kExpectedAlignment) && (valueArray[0] == 37),
+ "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(valueArray));
+ }
+ {
+ // Test the creation of a single aligned value.
+ const size_t kArraySize = 17;
+ const size_t kExpectedAlignment = 128;
+ typedef uint8_t Type;
+
+ eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type data;
+ Type* value = new(&data) Type;
+ *value = 37;
+ EATEST_VERIFY_F((EA::StdC::GetAlignment(value) >= kExpectedAlignment) && (*value == 37),
+ "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(value));
+
+ // Create an array of 100 values aligned.
+ eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type dataArray[kArraySize];
+ Type* valueArray = new(dataArray) Type[kArraySize];
+ valueArray[0] = 37;
+ EATEST_VERIFY_F((EA::StdC::GetAlignment(valueArray) >= kExpectedAlignment) && (valueArray[0] == 37),
+ "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(valueArray));
+ }
+ {
+ // Test the creation of a single aligned value.
+ const size_t kArraySize = 27;
+ const size_t kExpectedAlignment = 256;
+ typedef uint32_t Type;
+
+ eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type data;
+ Type* value = new(&data) Type;
+ *value = 37;
+ EATEST_VERIFY_F((EA::StdC::GetAlignment(value) >= kExpectedAlignment) && (*value == 37),
+ "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(value));
+
+ // Create an array of 100 values aligned.
+ eastl::aligned_storage<sizeof(Type), kExpectedAlignment>::type dataArray[kArraySize];
+ Type* valueArray = new(dataArray) Type[kArraySize];
+ valueArray[0] = 37;
+ EATEST_VERIFY_F((EA::StdC::GetAlignment(valueArray) >= kExpectedAlignment) && (valueArray[0] == 37),
+ "eastl::aligned_storage failure: Expected: %u, Actual: %u", (unsigned)kExpectedAlignment, (unsigned)EA::StdC::GetAlignment(valueArray));
+ }
+ #endif
+
+
+ // aligned_union
+ // Some compilers don't support or ignore alignment specifications for stack variables,
+ // so we limit our testing to compilers that are known to support it.
+ {
+ union AlignedUnion
+ {
+ char c;
+ int i;
+ float f;
+ char a[32];
+
+ AlignedUnion(float fValue) : f(fValue) {}
+ };
+
+ typedef aligned_union<sizeof(AlignedUnion), char, int, float>::type AlignedUnionStorage;
+
+ static_assert((EA_ALIGN_OF(AlignedUnionStorage) >= EA_ALIGN_OF(float)) && (EA_ALIGN_OF(AlignedUnionStorage) <= EA_ALIGN_OF(double)), "aligned_union failure");
+ static_assert(sizeof(AlignedUnionStorage) >= sizeof(AlignedUnion), "aligned_union failure");
+
+ AlignedUnionStorage alignedUnionStorage; // Since we know that our alignment is a simple value <= default alignment, we can just declare an object here and it will work with all compilers, including those that are limited in the stack alignments they support.
+ AlignedUnion* pAlignedUnion = new (&alignedUnionStorage) AlignedUnion(21.4f);
+ EATEST_VERIFY(pAlignedUnion->f == 21.4f);
+ pAlignedUnion->i = 37;
+ EATEST_VERIFY(pAlignedUnion->i == 37);
+ }
+
+
+ // union_cast
+ {
+ float f32 = -1234.f;
+ uint32_t n32 = union_cast<uint32_t>(f32);
+ float f32New = union_cast<float>(n32);
+ EATEST_VERIFY(f32 == f32New);
+
+ double f64 = -1234.0;
+ uint64_t n64 = union_cast<uint64_t>(f64);
+ double f64New = union_cast<double>(n64);
+ EATEST_VERIFY(f64 == f64New);
+
+ PodA a = { -1234 };
+ PodB b = union_cast<PodB>(a);
+ PodA aNew = union_cast<PodA>(b);
+ EATEST_VERIFY(a == aNew);
+
+ PodA* pA = new PodA;
+ PodB* pB = union_cast<PodB*>(pA);
+ PodA* pANew = union_cast<PodA*>(pB);
+ EATEST_VERIFY(pA == pANew);
+ delete pA;
+ }
+
+ // 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");
+ }
+
+ // 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");
+ }
+ }
+ #endif
+
+ // conjunction
+ {
+ static_assert( conjunction<>::value, "conjunction failure");
+ static_assert(!conjunction<false_type>::value, "conjunction failure");
+ static_assert(!conjunction<false_type, false_type>::value, "conjunction failure");
+ static_assert(!conjunction<false_type, false_type, false_type>::value, "conjunction failure");
+ static_assert(!conjunction<false_type, false_type, false_type, true_type>::value, "conjunction failure");
+ static_assert(!conjunction<false_type, false_type, true_type, true_type>::value, "conjunction failure");
+ static_assert(!conjunction<false_type, true_type, true_type, true_type>::value, "conjunction failure");
+ static_assert(!conjunction<true_type, true_type, true_type, true_type, false_type>::value, "conjunction failure");
+ static_assert(!conjunction<true_type, false_type, true_type, true_type, true_type>::value, "conjunction failure");
+ static_assert( conjunction<true_type, true_type, true_type, true_type, true_type>::value, "conjunction failure");
+ static_assert( conjunction<true_type, true_type, true_type, true_type>::value, "conjunction failure");
+ static_assert( conjunction<true_type, true_type, true_type>::value, "conjunction failure");
+ static_assert( conjunction<true_type>::value, "conjunction failure");
+
+ #if EASTL_VARIABLE_TEMPLATES_ENABLED
+ static_assert( conjunction_v<>, "conjunction failure");
+ static_assert(!conjunction_v<false_type>, "conjunction failure");
+ static_assert(!conjunction_v<false_type, false_type>, "conjunction failure");
+ static_assert(!conjunction_v<false_type, false_type, false_type>, "conjunction failure");
+ static_assert(!conjunction_v<false_type, false_type, false_type, true_type>, "conjunction failure");
+ static_assert(!conjunction_v<false_type, false_type, true_type, true_type>, "conjunction failure");
+ static_assert(!conjunction_v<false_type, true_type, true_type, true_type>, "conjunction failure");
+ static_assert(!conjunction_v<true_type, true_type, true_type, true_type, false_type>, "conjunction failure");
+ static_assert(!conjunction_v<true_type, false_type, true_type, true_type, true_type>, "conjunction failure");
+ static_assert( conjunction_v<true_type, true_type, true_type, true_type, true_type>, "conjunction failure");
+ static_assert( conjunction_v<true_type, true_type, true_type, true_type>, "conjunction failure");
+ static_assert( conjunction_v<true_type, true_type, true_type>, "conjunction failure");
+ static_assert( conjunction_v<true_type>, "conjunction failure");
+ #endif
+ }
+
+ // disjunction
+ {
+ static_assert(!disjunction<>::value, "disjunction failure");
+ static_assert(!disjunction<false_type>::value, "disjunction failure");
+ static_assert(!disjunction<false_type, false_type>::value, "disjunction failure");
+ static_assert(!disjunction<false_type, false_type, false_type>::value, "disjunction failure");
+ static_assert( disjunction<false_type, false_type, false_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<false_type, false_type, true_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<false_type, true_type, true_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<true_type, true_type, true_type, true_type, false_type>::value, "disjunction failure");
+ static_assert( disjunction<true_type, false_type, true_type, true_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<true_type, true_type, true_type, true_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<true_type, true_type, true_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<true_type, true_type, true_type>::value, "disjunction failure");
+ static_assert( disjunction<true_type>::value, "disjunction failure");
+
+ #if EASTL_VARIABLE_TEMPLATES_ENABLED
+ static_assert(!disjunction_v<>, "disjunction failure");
+ static_assert(!disjunction_v<false_type>, "disjunction failure");
+ static_assert(!disjunction_v<false_type, false_type>, "disjunction failure");
+ static_assert(!disjunction_v<false_type, false_type, false_type>, "disjunction failure");
+ static_assert( disjunction_v<false_type, false_type, false_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<false_type, false_type, true_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<false_type, true_type, true_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<true_type, true_type, true_type, true_type, false_type>, "disjunction failure");
+ static_assert( disjunction_v<true_type, false_type, true_type, true_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<true_type, true_type, true_type, true_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<true_type, true_type, true_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<true_type, true_type, true_type>, "disjunction failure");
+ static_assert( disjunction_v<true_type>, "disjunction failure");
+ #endif
+ }
+
+ // negation
+ {
+ static_assert( negation<false_type>::value, "negation failure");
+ static_assert(!negation<true_type>::value, "negation failure");
+
+ #if EASTL_VARIABLE_TEMPLATES_ENABLED
+ static_assert( negation_v<false_type>, "negation failure");
+ static_assert(!negation_v<true_type>, "negation failure");
+ #endif
+ }
+
+ // has_unique_object_representations
+ {
+ static_assert( has_unique_object_representations<bool>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<char16_t>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<char32_t>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<char>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<int>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<long long>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<long>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<short>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<signed char>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<unsigned char>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<unsigned int>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<unsigned long long>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<unsigned long>::value, "has_unique_object_representations failure");
+ static_assert( has_unique_object_representations<unsigned short>::value, "has_unique_object_representations failure");
+ static_assert(!has_unique_object_representations<void>::value, "has_unique_object_representations failure");
+#ifndef EA_WCHAR_T_NON_NATIVE // If wchar_t is a native type instead of simply a define to an existing type which is already handled...
+ static_assert( has_unique_object_representations<wchar_t>::value, "has_unique_object_representations failure");
+#endif
+
+ #if EASTL_TYPE_TRAIT_has_unique_object_representations_CONFORMANCE
+ {
+ struct packed_type { int a; };
+ static_assert( has_unique_object_representations<packed_type>::value, "has_unique_object_representations failure");
+
+ struct padded_type { int a; char b; int c; };
+ static_assert(!has_unique_object_representations<padded_type>::value, "has_unique_object_representations failure");
+ }
+ #endif
+ }
+
+ // is_final
+ {
+ #if (EA_COMPILER_HAS_FEATURE(is_final))
+ static_assert(std::is_final<FinalStruct>::value == eastl::is_final<FinalStruct>::value, "final struct not correctly detected");
+ static_assert(std::is_final<FinalClass>::value == eastl::is_final<FinalClass>::value, "final class not correctly detected");
+ static_assert(std::is_final<Enum>::value == eastl::is_final<Enum>::value, "enum not correctly detected");
+ static_assert(std::is_final<int>::value == eastl::is_final<int>::value, "int not correctly detected");
+ static_assert(std::is_final<Struct>::value == eastl::is_final<Struct>::value, "non-final struct not correctly detected");
+ static_assert(std::is_final<Class>::value == eastl::is_final<Class>::value, "non-final class not correctly detected");
+ #endif
+
+ // endian (big-endian and little; no mixed-endian/middle-endian)
+ static_assert(eastl::endian::big != eastl::endian::little, "little-endian and big-endian are not the same");
+ static_assert(eastl::endian::native == eastl::endian::big || eastl::endian::native == eastl::endian::little, "native may be little endian or big endian");
+ static_assert(!(eastl::endian::native == eastl::endian::big && eastl::endian::native == eastl::endian::little), "native cannot be both big and little endian");
+
+ #ifdef EA_SYSTEM_LITTLE_ENDIAN
+ static_assert(eastl::endian::native == eastl::endian::little, "must be little endian");
+ static_assert(eastl::endian::native != eastl::endian::big, "must not be big endian");
+ #else
+ static_assert(eastl::endian::native != eastl::endian::little, "must not be little endian");
+ static_assert(eastl::endian::native == eastl::endian::big, "must be big endian");
+ #endif
+ }
+
+ // has_equality
+ {
+ static_assert( has_equality_v<int>, "has_equality failure");
+ static_assert( has_equality_v<short>, "has_equality failure");
+ static_assert( has_equality_v<long>, "has_equality failure");
+ static_assert( has_equality_v<long long>, "has_equality failure");
+ static_assert( has_equality_v<TestObject>, "has_equality failure");
+ static_assert(!has_equality_v<MissingEquality>, "has_equality failure");
+ }
+
+ // is_aggregate
+ #if EASTL_TYPE_TRAIT_is_aggregate_CONFORMANCE
+ {
+ static_assert(!is_aggregate_v<int>, "is_aggregate failure");
+ static_assert( is_aggregate_v<int[]>, "is_aggregate failure");
+
+ {
+ struct Aggregrate {};
+ static_assert(is_aggregate_v<Aggregrate>, "is_aggregate failure");
+ }
+
+ {
+ struct NotAggregrate { NotAggregrate() {} }; // user provided ctor
+ 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.
+ {
+ struct NotAggregrate { int data = 42; }; // default member initializer
+ static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure");
+ }
+ #endif
+
+ {
+ struct NotAggregrate { virtual void foo() {} }; // virtual member function
+ static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure");
+ }
+ }
+ #endif
+
+ return nErrorCount;
+}
+
+
+
+
+
+
+