Files
EASTL/test/source/TestTypeTraits.cpp
jeanlemotan 48ab06b1d9 First
2024-07-02 18:10:39 +02:00

2440 lines
123 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/////////////////////////////////////////////////////////////////////////////
// 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(){}
};
struct HasIncrementOperator { HasIncrementOperator& operator++() { return *this; } };
template <class T>
using has_increment_operator_detection = decltype(++eastl::declval<T>());
template<typename, typename = eastl::void_t<>>
struct has_increment_operator_using_void_t : eastl::false_type {};
template <typename T>
struct has_increment_operator_using_void_t<T, eastl::void_t<has_increment_operator_detection<T>>> : eastl::true_type {};
// We use this for the is_copy_constructible test in order to verify that
// 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(){}
};
// Disable the following warning:
// warning: struct Abstract has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
// We explicitly want this class not to have a virtual destructor to test our type traits.
EA_DISABLE_VC_WARNING(4265)
EA_DISABLE_CLANG_WARNING(-Wnon-virtual-dtor)
EA_DISABLE_GCC_WARNING(-Wnon-virtual-dtor)
struct Abstract
{
virtual void Function() = 0;
};
EA_RESTORE_GCC_WARNING()
EA_RESTORE_CLANG_WARNING()
EA_RESTORE_VC_WARNING()
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<char8_t>::value, "is_integral failure");
static_assert(is_integral<char16_t>::value, "is_integral failure");
static_assert(is_integral<char32_t>::value, "is_integral failure");
static_assert(is_integral<char>::value, "is_integral failure");
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_bounded_array
static_assert(is_bounded_array<Array>::value == true, "is_bounded_array failure");
EATEST_VERIFY(GetType(is_bounded_array<Array>()) == true);
static_assert(is_bounded_array<ArrayConst>::value == true, "is_bounded_array failure");
EATEST_VERIFY(GetType(is_bounded_array<ArrayConst>()) == true);
static_assert(is_bounded_array<int>::value == false, "is_bounded_array failure");
static_assert(is_bounded_array<int[32]>::value == true, "is_bounded_array failure");
static_assert(is_bounded_array<int[]>::value == false, "is_bounded_array failure");
static_assert(is_bounded_array<uint32_t>::value == false, "is_bounded_array failure");
EATEST_VERIFY(GetType(is_bounded_array<uint32_t>()) == false);
static_assert(is_bounded_array<uint32_t*>::value == false, "is_bounded_array failure");
EATEST_VERIFY(GetType(is_bounded_array<uint32_t*>()) == false);
//is_unbounded_array
static_assert(is_unbounded_array<Array>::value == false, "is_unbounded_array failure");
EATEST_VERIFY(GetType(is_unbounded_array<Array>()) == false);
static_assert(is_unbounded_array<ArrayConst>::value == false, "is_unbounded_array failure");
EATEST_VERIFY(GetType(is_unbounded_array<ArrayConst>()) == false);
static_assert(is_unbounded_array<int>::value == false, "is_unbounded_array failure");
static_assert(is_unbounded_array<int[32]>::value == false, "is_unbounded_array failure");
static_assert(is_unbounded_array<int[]>::value == true, "is_unbounded_array failure");
static_assert(is_unbounded_array<uint32_t>::value == false, "is_unbounded_array failure");
EATEST_VERIFY(GetType(is_unbounded_array<uint32_t>()) == false);
static_assert(is_unbounded_array<uint32_t*>::value == false, "is_unbounded_array failure");
EATEST_VERIFY(GetType(is_unbounded_array<uint32_t*>()) == false);
// is_reference
static_assert(is_reference<Class&>::value == true, "is_reference failure");
EATEST_VERIFY(GetType(is_reference<Class&>()) == true);
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<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");
static_assert(is_member_function_pointer<int(Class::*)(...)>::value == true, "is_member_function_pointer failure");
static_assert(is_member_function_pointer<int(Class::*)() noexcept>::value == true, "is_member_function_pointer failure");
static_assert(is_member_function_pointer<int(Class::*)() &>::value == true, "is_member_function_pointer failure");
static_assert(is_member_function_pointer<int(Class::*)() &&>::value == true, "is_member_function_pointer failure");
// is_member_object_pointer
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");
static_assert(is_member_pointer<int(Class::* const)>::value == true, "is_member_pointer failure");
static_assert(is_member_pointer<int(Class::* volatile)>::value == true, "is_member_pointer failure");
static_assert(is_member_pointer<int(Class::* const volatile)>::value == true, "is_member_pointer failure");
// is_pointer
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);
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<Enum&&>::value == false, "is_enum failure ");
static_assert(is_enum_v<Enum&&> == false, "is_enum failure ");
EATEST_VERIFY(GetType(is_enum<Enum&&>()) == 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<int (float)>::value == true, "is_function failure");
static_assert(is_function<int (float) const>::value == true, "is_function failure");
static_assert(is_function<int(float) volatile>::value == true, "is_function failure");
static_assert(is_function<int(float) const volatile>::value == true, "is_function failure");
static_assert(is_function<int(float)&>::value == true, "is_function failure");
static_assert(is_function<int(float)&&>::value == true, "is_function failure");
static_assert(is_function<int(float) noexcept>::value == true, "is_function failure");
static_assert(is_function<FunctionIntFloat &>::value == false, "is_function failure"); // reference to function, not a l-value reference qualified function
static_assert(is_function<FunctionIntFloat &&>::value == false, "is_function failure");
static_assert(is_function_v<void> == false, "is_function failure");
static_assert(is_function_v<FunctionVoidVoid> == true, "is_function failure");
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);
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);
static_assert(is_const<void() const>::value == false, "is_const failure");
EATEST_VERIFY(GetType(is_const<void() const>()) == false);
// is_volatile
static_assert(is_volatile<Int>::value == false, "is_volatile failure");
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);
static_assert(is_volatile<void() const>::value == false, "is_volatile failure");
EATEST_VERIFY(GetType(is_volatile<void() const>()) == false);
// underlying_type and to_underlying
#if EASTL_TYPE_TRAIT_underlying_type_CONFORMANCE && !defined(EA_COMPILER_NO_STRONGLY_TYPED_ENUMS) // If we can execute this test...
enum UnderlyingTypeTest : uint16_t { firstVal = 0, secondVal = 1 };
constexpr bool isUnderlyingTypeCorrect = is_same_v<underlying_type_t<UnderlyingTypeTest>, uint16_t>;
static_assert(isUnderlyingTypeCorrect, "Wrong type for underlying_type_t.");
EATEST_VERIFY(isUnderlyingTypeCorrect);
auto v1 = to_underlying(UnderlyingTypeTest::firstVal);
auto v2 = to_underlying(UnderlyingTypeTest::secondVal);
constexpr bool isToUnderlyingReturnTypeCorrect = is_same_v<decltype(v1), uint16_t>;
static_assert(isToUnderlyingReturnTypeCorrect, "Wrong return type for to_underlying.");
EATEST_VERIFY(isToUnderlyingReturnTypeCorrect);
EATEST_VERIFY(v1 == 0 && v2 == 1);
#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);
static_assert(is_signed<char16_t>::value == false, "is_signed failure ");
static_assert(is_signed_v<char16_t> == false, "is_signed failure ");
EATEST_VERIFY(GetType(is_signed<char16_t>()) == false);
static_assert(is_signed<char32_t>::value == false, "is_signed failure ");
static_assert(is_signed_v<char32_t> == false, "is_signed failure ");
EATEST_VERIFY(GetType(is_signed<char32_t>()) == false);
#if EASTL_GCC_STYLE_INT128_SUPPORTED
static_assert(is_signed<__int128_t>::value == true, "is_signed failure ");
static_assert(is_signed_v<__int128_t> == true, "is_signed failure ");
EATEST_VERIFY(GetType(is_signed<__int128_t>()) == true);
static_assert(is_signed<__uint128_t>::value == false, "is_signed failure ");
static_assert(is_signed_v<__uint128_t> == false, "is_signed failure ");
EATEST_VERIFY(GetType(is_signed<__uint128_t>()) == false);
#endif
// is_unsigned
static_assert(is_unsigned<unsigned int>::value == true, "is_unsigned failure ");
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 == true, "is_unsigned failure ");
static_assert(is_unsigned_v<bool> == true, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<bool>()) == true);
static_assert(is_unsigned<float>::value == false, "is_unsigned failure ");
static_assert(is_unsigned_v<float> == false, "is_unsigned failure ");
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);
static_assert(is_unsigned<char16_t>::value == true, "is_unsigned failure ");
static_assert(is_unsigned_v<char16_t> == true, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<char16_t>()) == true);
static_assert(is_unsigned<char32_t>::value == true, "is_unsigned failure ");
static_assert(is_unsigned_v<char32_t> == true, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<char32_t>()) == true);
#if EASTL_GCC_STYLE_INT128_SUPPORTED
static_assert(is_unsigned<__int128_t>::value == false, "is_unsigned failure ");
static_assert(is_unsigned_v<__int128_t> == false, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<__int128_t>()) == false);
static_assert(is_unsigned<__uint128_t>::value == true, "is_unsigned failure ");
static_assert(is_unsigned_v<__uint128_t> == true, "is_unsigned failure ");
EATEST_VERIFY(GetType(is_unsigned<__uint128_t>()) == true);
#endif
// is_lvalue_reference
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");
EATEST_VERIFY(GetType(is_trivially_copyable<void>()) == false);
static_assert(is_trivially_copyable<int>::value == true, "is_trivially_copyable failure");
static_assert(is_trivially_copyable<int*>::value == true, "is_trivially_copyable failure");
static_assert(is_trivially_copyable<int[]>::value == true, "is_trivially_copyable failure");
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 == 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<int&>::value == true, "is_destructible failure");
static_assert(is_destructible<int&&>::value == true, "is_destructible failure");
static_assert(is_destructible<char>::value == true, "is_destructible failure");
static_assert(is_destructible<char*>::value == true, "is_destructible failure");
static_assert(is_destructible<PodA>::value == true, "is_destructible failure");
static_assert(is_destructible<void>::value == false, "is_destructible failure");
static_assert(is_destructible<int[3]>::value == true, "is_destructible failure");
static_assert(is_destructible<int[]>::value == false, "is_destructible failure"); // You can't call operator delete on this class.
static_assert(is_destructible<Abstract>::value == true, "is_destructible failure");
static_assert(is_destructible<AbstractWithDtor>::value == true, "is_destructible failure");
#if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
static_assert(is_destructible<DeletedDtor>::value == false, "is_destructible failure"); // You can't call operator delete on this class.
#endif
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<int&>::value == true, "is_trivially_destructible failure");
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 == true, "is_trivially_destructible failure");
static_assert(is_trivially_destructible<AbstractWithDtor>::value == false, "is_trivially_destructible failure"); // Having a user-defined destructor make it non-trivial.
#if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
static_assert(is_trivially_destructible<DeletedDtor>::value == false, "is_trivially_destructible failure");
#endif
static_assert(is_trivially_destructible<NonPod2>::value == false, "is_trivially_destructible failure"); // This case differs from is_destructible, because we have a declared destructor.
#endif
// is_nothrow_destructible
static_assert(is_nothrow_destructible<int>::value == true, "is_nothrow_destructible failure");
static_assert(is_nothrow_destructible<int&>::value == true, "is_nothrow_destructible failure");
static_assert(is_nothrow_destructible<int&&>::value == true, "is_nothrow_destructible failure");
static_assert(is_nothrow_destructible<void>::value == false, "is_nothrow_destructible failure");
static_assert(is_nothrow_destructible<Abstract>::value == true, "is_nothrow_destructible failure");
static_assert(is_nothrow_destructible<AbstractWithDtor>::value == true, "is_nothrow_destructible failure");
#if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
static_assert(is_nothrow_destructible<DeletedDtor>::value == false, "is_nothrow_destructible failure"); // You can't call operator delete on this class.
#endif
#if EASTL_TYPE_TRAIT_is_nothrow_destructible_CONFORMANCE
static_assert(is_nothrow_destructible<NonPod2>::value == true, "is_nothrow_destructible failure"); // NonPod2 is nothrow destructible because it has an empty destructor (makes no calls) which has no exception specification. Thus its exception specification defaults to noexcept(true) [C++11 Standard, 15.4 paragraph 14]
static_assert(is_nothrow_destructible<NoThrowDestructible>::value == true, "is_nothrow_destructible failure");
#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);
static_assert(eastl::is_same_v<signed char, eastl::make_signed<unsigned char>::type>);
static_assert(eastl::is_same_v<short, eastl::make_signed<unsigned short>::type>);
static_assert(eastl::is_same_v<int, eastl::make_signed<unsigned int>::type>);
static_assert(eastl::is_same_v<long, eastl::make_signed<unsigned long>::type>);
static_assert(eastl::is_same_v<long long, eastl::make_signed<unsigned long long>::type>);
static_assert(eastl::is_same_v<const signed char, eastl::make_signed<const unsigned char>::type>);
static_assert(eastl::is_same_v<const short, eastl::make_signed<const unsigned short>::type>);
static_assert(eastl::is_same_v<const int, eastl::make_signed<const unsigned int>::type>);
static_assert(eastl::is_same_v<const long, eastl::make_signed<const unsigned long>::type>);
static_assert(eastl::is_same_v<const long long, eastl::make_signed<const unsigned long long>::type>);
static_assert(eastl::is_same_v<volatile signed char, eastl::make_signed<volatile unsigned char>::type>);
static_assert(eastl::is_same_v<volatile short, eastl::make_signed<volatile unsigned short>::type>);
static_assert(eastl::is_same_v<volatile int, eastl::make_signed<volatile unsigned int>::type>);
static_assert(eastl::is_same_v<volatile long, eastl::make_signed<volatile unsigned long>::type>);
static_assert(eastl::is_same_v<volatile long long, eastl::make_signed<volatile unsigned long long>::type>);
static_assert(eastl::is_same_v<const volatile signed char, eastl::make_signed<const volatile unsigned char>::type>);
static_assert(eastl::is_same_v<const volatile short, eastl::make_signed<const volatile unsigned short>::type>);
static_assert(eastl::is_same_v<const volatile int, eastl::make_signed<const volatile unsigned int>::type>);
static_assert(eastl::is_same_v<const volatile long, eastl::make_signed<const volatile unsigned long>::type>);
static_assert(eastl::is_same_v<const volatile long long, eastl::make_signed<const volatile unsigned long long>::type>);
static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<signed char>::type>);
static_assert(eastl::is_same_v<unsigned short, eastl::make_unsigned<short>::type>);
static_assert(eastl::is_same_v<unsigned int, eastl::make_unsigned<int>::type>);
static_assert(eastl::is_same_v<unsigned long, eastl::make_unsigned<long>::type>);
static_assert(eastl::is_same_v<unsigned long long, eastl::make_unsigned<long long>::type>);
static_assert(eastl::is_same_v<const unsigned char, eastl::make_unsigned<const signed char>::type>);
static_assert(eastl::is_same_v<const unsigned short, eastl::make_unsigned<const short>::type>);
static_assert(eastl::is_same_v<const unsigned int, eastl::make_unsigned<const int>::type>);
static_assert(eastl::is_same_v<const unsigned long, eastl::make_unsigned<const long>::type>);
static_assert(eastl::is_same_v<const unsigned long long, eastl::make_unsigned<const long long>::type>);
static_assert(eastl::is_same_v<volatile unsigned char, eastl::make_unsigned<volatile signed char>::type>);
static_assert(eastl::is_same_v<volatile unsigned short, eastl::make_unsigned<volatile short>::type>);
static_assert(eastl::is_same_v<volatile unsigned int, eastl::make_unsigned<volatile int>::type>);
static_assert(eastl::is_same_v<volatile unsigned long, eastl::make_unsigned<volatile long>::type>);
static_assert(eastl::is_same_v<volatile unsigned long long, eastl::make_unsigned<volatile long long>::type>);
static_assert(eastl::is_same_v<const volatile unsigned char, eastl::make_unsigned<const volatile signed char>::type>);
static_assert(eastl::is_same_v<const volatile unsigned short, eastl::make_unsigned<const volatile short>::type>);
static_assert(eastl::is_same_v<const volatile unsigned int, eastl::make_unsigned<const volatile int>::type>);
static_assert(eastl::is_same_v<const volatile unsigned long, eastl::make_unsigned<const volatile long>::type>);
static_assert(eastl::is_same_v<const volatile unsigned long long, eastl::make_unsigned<const volatile long long>::type>);
static_assert(eastl::is_same_v<signed char, eastl::make_signed<signed char>::type>);
static_assert(eastl::is_same_v<short, eastl::make_signed<signed short>::type>);
static_assert(eastl::is_same_v<int, eastl::make_signed<signed int>::type>);
static_assert(eastl::is_same_v<long, eastl::make_signed<signed long>::type>);
static_assert(eastl::is_same_v<long long, eastl::make_signed<signed long long>::type>);
static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<unsigned char>::type>);
static_assert(eastl::is_same_v<unsigned short, eastl::make_unsigned<unsigned short>::type>);
static_assert(eastl::is_same_v<unsigned int, eastl::make_unsigned<unsigned int>::type>);
static_assert(eastl::is_same_v<unsigned long, eastl::make_unsigned<unsigned long>::type>);
static_assert(eastl::is_same_v<unsigned long long, eastl::make_unsigned<unsigned long long>::type>);
#if EASTL_GCC_STYLE_INT128_SUPPORTED
static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__int128_t>::type>);
static_assert(eastl::is_same_v<__uint128_t, eastl::make_unsigned<__uint128_t>::type>);
static_assert(eastl::is_same_v<__int128_t, eastl::make_signed<__int128_t>::type>);
static_assert(eastl::is_same_v<__int128_t, eastl::make_signed<__uint128_t>::type>);
#endif
// Char tests
static_assert(sizeof(char) == sizeof(eastl::make_signed<char>::type));
static_assert(sizeof(wchar_t) == sizeof(eastl::make_signed<wchar_t>::type));
static_assert(sizeof(char8_t) == sizeof(eastl::make_signed<char8_t>::type));
static_assert(sizeof(char16_t) == sizeof(eastl::make_signed<char16_t>::type));
static_assert(sizeof(char32_t) == sizeof(eastl::make_signed<char32_t>::type));
static_assert(sizeof(char) == sizeof(eastl::make_unsigned<char>::type));
static_assert(sizeof(wchar_t) == sizeof(eastl::make_unsigned<wchar_t>::type));
static_assert(sizeof(char8_t) == sizeof(eastl::make_unsigned<char8_t>::type));
static_assert(sizeof(char16_t) == sizeof(eastl::make_unsigned<char16_t>::type));
static_assert(sizeof(char32_t) == sizeof(eastl::make_unsigned<char32_t>::type));
static_assert(eastl::is_same_v<signed char, eastl::make_signed<char8_t>::type>);
static_assert(eastl::is_same_v<unsigned char, eastl::make_unsigned<char8_t>::type>);
// Enum tests
enum EnumUCharSize : unsigned char {};
enum EnumUShortSize : unsigned short {};
enum EnumUIntSize : unsigned int {};
enum EnumULongSize : unsigned long {};
enum EnumULongLongSize : unsigned long long {};
static_assert(eastl::is_signed_v<eastl::make_signed<EnumUCharSize>::type>);
static_assert(eastl::is_signed_v<eastl::make_signed<EnumUShortSize>::type>);
static_assert(eastl::is_signed_v<eastl::make_signed<EnumUIntSize>::type>);
static_assert(eastl::is_signed_v<eastl::make_signed<EnumULongSize>::type>);
static_assert(eastl::is_signed_v<eastl::make_signed<EnumULongLongSize>::type>);
static_assert(sizeof(EnumUCharSize) == sizeof(eastl::make_signed<EnumUCharSize>::type));
static_assert(sizeof(EnumUShortSize) == sizeof(eastl::make_signed<EnumUShortSize>::type));
static_assert(sizeof(EnumUIntSize) == sizeof(eastl::make_signed<EnumUIntSize>::type));
static_assert(sizeof(EnumULongSize) == sizeof(eastl::make_signed<EnumULongSize>::type));
static_assert(sizeof(EnumULongLongSize) == sizeof(eastl::make_signed<EnumULongLongSize>::type));
enum EnumCharSize : signed char {};
enum EnumShortSize : short {};
enum EnumIntSize : int {};
enum EnumLongSize : long {};
enum EnumLongLongSize : long long {};
static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumCharSize>::type>);
static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumShortSize>::type>);
static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumIntSize>::type>);
static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumLongSize>::type>);
static_assert(eastl::is_unsigned_v<eastl::make_unsigned<EnumLongLongSize>::type>);
static_assert(sizeof(EnumCharSize) == sizeof(eastl::make_unsigned<EnumCharSize>::type));
static_assert(sizeof(EnumShortSize) == sizeof(eastl::make_unsigned<EnumShortSize>::type));
static_assert(sizeof(EnumIntSize) == sizeof(eastl::make_unsigned<EnumIntSize>::type));
static_assert(sizeof(EnumLongSize) == sizeof(eastl::make_unsigned<EnumLongSize>::type));
static_assert(sizeof(EnumLongLongSize) == sizeof(eastl::make_unsigned<EnumLongLongSize>::type));
}
// 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);
// ref to T
// -> T*
static_assert(is_same_v<add_pointer_t<int&>, int*>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<int(&)()>, int(*)()>, "add_pointer failure");
// object type (a (possibly cv-qualified) type other than function type, reference type or void), or
// a function type that is not cv- or ref-qualified, or a (possibly cv-qualified) void type
// -> T*
static_assert(is_same_v<add_pointer_t<int>, int*>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<int*>, int**>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<int()>, int(*)()>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<void>, void*>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<const void>, const void*>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<volatile void>, volatile void*>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<const volatile void>, const volatile void*>, "add_pointer failure");
// otherwise (cv- or ref-qualified function type)
// -> T
static_assert(is_same_v<add_pointer_t<int() const>, int() const>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<int() volatile>, int() volatile>, "add_pointer failure");
static_assert(is_same_v<add_pointer_t<int() const volatile>, int() const volatile>, "add_pointer failure");
// remove_extent
// If T is an array of some type X, provides the member typedef type equal to X, otherwise
// type is T. Note that if T is a multidimensional array, only the first dimension is removed.
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");
}
// add_lvalue_reference
{
// function type with no cv- or ref-qualifier
// -> T&
static_assert(is_same_v<add_lvalue_reference_t<void()>, void(&)()>, "add_lvalue_reference failure");
// object type (a (possibly cv-qualified) type other than function type, reference type or void)
// -> T&
static_assert(is_same_v<add_lvalue_reference_t<int>, int&>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<const int>, const int&>, "add_lvalue_reference failure");
// if T is an rvalue reference (to some type U)
// -> U&
static_assert(is_same_v<add_lvalue_reference_t<int&&>, int&>, "add_lvalue_reference failure");
// otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void)
// -> T
static_assert(is_same_v<add_lvalue_reference_t<void() const>, void() const>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<void()&>, void()&>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<void()&&>, void()&&>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<int&>, int&>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<const int&>, const int&>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<void>, void>, "add_lvalue_reference failure");
static_assert(is_same_v<add_lvalue_reference_t<const void>, const void>, "add_lvalue_reference failure");
}
// add_rvalue_reference
{
// function type with no cv- or ref-qualifier
// -> T&&
static_assert(is_same_v<add_rvalue_reference_t<void()>, void(&&)()>, "add_rvalue_reference failure");
// object type (a (possibly cv-qualified) type other than function type, reference type or void)
// -> T&&
static_assert(is_same_v<add_rvalue_reference_t<int>, int&&>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<const int>, const int&&>, "add_rvalue_reference failure");
// otherwise (cv- or ref-qualified function type, or reference type, or (possibly cv-qualified) void)
// -> T
static_assert(is_same_v<add_rvalue_reference_t<void() const>, void() const>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<void()&>, void()&>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<void()&&>, void()&&>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<int&>, int&>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<int&&>, int&&>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<const int&>, const int&>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<void>, void>, "add_rvalue_reference failure");
static_assert(is_same_v<add_rvalue_reference_t<const void>, const void>, "add_rvalue_reference failure");
}
// decay
{
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
{
{
static_assert(is_same<void_t<void>, void>::value, "void_t failure");
static_assert(is_same<void_t<int>, void>::value, "void_t failure");
static_assert(is_same<void_t<short>, void>::value, "void_t failure");
static_assert(is_same<void_t<long>, void>::value, "void_t failure");
static_assert(is_same<void_t<long long>, void>::value, "void_t failure");
static_assert(is_same<void_t<ClassEmpty>, void>::value, "void_t failure");
static_assert(is_same<void_t<ClassNonEmpty>, void>::value, "void_t failure");
static_assert(is_same<void_t<vector<int>>, void>::value, "void_t failure");
}
// new sfinae mechansim test
{
static_assert(has_increment_operator_using_void_t<HasIncrementOperator>::value, "void_t sfinae failure");
static_assert(!has_increment_operator_using_void_t<ClassEmpty>::value, "void_t sfinae failure");
}
}
// detected idiom
{
static_assert(is_detected<has_increment_operator_detection, HasIncrementOperator>::value, "is_detected failure.");
static_assert(!is_detected<has_increment_operator_detection, ClassEmpty>::value, "is_detected failure.");
static_assert(is_same<detected_t<has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "is_detected_t failure.");
static_assert(is_same<detected_t<has_increment_operator_detection, ClassEmpty>, nonesuch>::value, "is_detected_t failure.");
using detected_or_positive_result = detected_or<float, has_increment_operator_detection, HasIncrementOperator>;
using detected_or_negative_result = detected_or<float, has_increment_operator_detection, ClassEmpty>;
static_assert(detected_or_positive_result::value_t::value, "detected_or failure.");
static_assert(!detected_or_negative_result::value_t::value, "detected_or failure.");
static_assert(is_same<detected_or_positive_result::type, HasIncrementOperator&>::value, "detected_or failure.");
static_assert(is_same<detected_or_negative_result::type, float>::value, "detected_or failure.");
static_assert(is_same<detected_or_t<float, has_increment_operator_detection, HasIncrementOperator>, HasIncrementOperator&>::value, "detected_or_t failure.");
static_assert(is_same<detected_or_t<float, has_increment_operator_detection, ClassEmpty>, float>::value, "detected_or_t failure.");
static_assert(is_detected_exact<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure.");
static_assert(!is_detected_exact<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_exact failure.");
static_assert(is_detected_exact<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure.");
static_assert(!is_detected_exact<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_exact failure.");
static_assert(is_detected_convertible<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure.");
static_assert(is_detected_convertible<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure.");
static_assert(!is_detected_convertible<float, has_increment_operator_detection, HasIncrementOperator>::value, "is_detected_convertible failure.");
static_assert(!is_detected_convertible<nonesuch, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure.");
static_assert(!is_detected_convertible<float, has_increment_operator_detection, ClassEmpty>::value, "is_detected_convertible failure.");
#if EASTL_VARIABLE_TEMPLATES_ENABLED
static_assert(is_detected_v<has_increment_operator_detection, HasIncrementOperator>, "is_detected_v failure.");
static_assert(!is_detected_v<has_increment_operator_detection, ClassEmpty>, "is_detected_v failure.");
static_assert(is_detected_exact_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure.");
static_assert(!is_detected_exact_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_exact_v failure.");
static_assert(is_detected_exact_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure.");
static_assert(!is_detected_exact_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_exact_v failure.");
static_assert(is_detected_convertible_v<HasIncrementOperator&, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure.");
static_assert(is_detected_convertible_v<HasIncrementOperator, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure.");
static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, HasIncrementOperator>, "is_detected_convertible_v failure.");
static_assert(!is_detected_convertible_v<nonesuch, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure.");
static_assert(!is_detected_convertible_v<float, has_increment_operator_detection, ClassEmpty>, "is_detected_convertible_v failure.");
#endif
}
// conjunction
{
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");
}
#if defined(EA_COMPILER_CPP11_ENABLED) && !defined(EA_COMPILER_CPP14_ENABLED)
// See https://en.cppreference.com/w/cpp/language/aggregate_initialization
// In C++11 the requirement was added to aggregate types that no default member initializers exist,
// however this requirement was removed in C++14.
{
struct NotAggregrate { int data = 42; }; // default member initializer
static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure");
}
#endif
{
struct NotAggregrate { virtual void foo() {} }; // virtual member function
static_assert(!is_aggregate_v<NotAggregrate>, "is_aggregate failure");
}
}
#endif
// is_complete_type
{
struct Foo
{
int x;
};
struct FooEmpty
{
};
struct Bar;
void FooFunc();
static_assert(eastl::internal::is_complete_type_v<Foo>, "is_complete_type failure");
static_assert(eastl::internal::is_complete_type_v<FooEmpty>, "is_complete_type failure");
static_assert(!eastl::internal::is_complete_type_v<Bar>, "is_complete_type failure");
static_assert(!eastl::internal::is_complete_type_v<void>, "is_complete_type failure");
static_assert(!eastl::internal::is_complete_type_v<volatile void>, "is_complete_type failure");
static_assert(!eastl::internal::is_complete_type_v<const void>, "is_complete_type failure");
static_assert(!eastl::internal::is_complete_type_v<const volatile void>, "is_complete_type failure");
static_assert(eastl::internal::is_complete_type_v<decltype(FooFunc)>, "is_complete_type failure");
}
return nErrorCount;
}