diff --git a/include/bx/bx.h b/include/bx/bx.h index 3555c7b..6c81996 100644 --- a/include/bx/bx.h +++ b/include/bx/bx.h @@ -17,6 +17,7 @@ #include "constants.h" #include "macros.h" #include "debug.h" +#include "typetraits.h" /// #define BX_COUNTOF(_x) sizeof(bx::CountOfRequireArrayArgumentT(_x) ) @@ -37,14 +38,6 @@ namespace bx { - /// Returns true if type `Ty` is trivially copyable / POD type. - template - constexpr bool isTriviallyCopyable(); - - /// Returns true if type `Ty` is signed type. - template - constexpr bool isSigned(); - /// Arithmetic type `Ty` limits. template()> struct LimitsT; diff --git a/include/bx/inline/bx.inl b/include/bx/inline/bx.inl index 506165c..72a2a4f 100644 --- a/include/bx/inline/bx.inl +++ b/include/bx/inline/bx.inl @@ -27,18 +27,6 @@ namespace bx return _x; } - template - inline constexpr bool isTriviallyCopyable() - { - return __is_trivially_copyable(Ty); - } - - template - constexpr bool isSigned() - { - return Ty(-1) < Ty(0); - } - template inline Ty* addressOf(Ty& _a) { @@ -74,7 +62,7 @@ namespace bx template inline void swap(Ty& _a, Ty& _b) { - Ty tmp = _a; _a = _b; _b = tmp; + Ty tmp = move(_a); _a = move(_b); _b = move(tmp); } template diff --git a/include/bx/inline/typetraits.inl b/include/bx/inline/typetraits.inl new file mode 100644 index 0000000..232c4f7 --- /dev/null +++ b/include/bx/inline/typetraits.inl @@ -0,0 +1,462 @@ +/* + * Copyright 2010-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx/blob/master/LICENSE + */ + +#ifndef BX_TYPETRAITS_H_HEADER_GUARD +# error "Must be included from bx/typetraits.h!" +#endif // BX_TYPETRAITS_H_HEADER_GUARD + +namespace bx +{ + // Reference(s): + // + // - GCC type traits compiler intrisics + // https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Type-Traits.html + // + // - Clang type trait primitives + // https://clang.llvm.org/docs/LanguageExtensions.html#type-trait-primitives + + //--- + template + struct IntegralConstantT + { + using ValueType = Ty; + static constexpr Ty value = ValueT; + }; + + template + using BoolConstantT = IntegralConstantT; + using FalseConstant = BoolConstantT; + using TrueConstant = BoolConstantT; + + //--- + template struct TypeIdentityT { using Type = Ty; }; + template using TypeIdentityType = typename TypeIdentityT::Type; + + //--- + template struct ConditionalT { using type = Ty; }; + template< typename Ty, typename Uy> struct ConditionalT { using type = Uy; }; + template using ConditionalType = typename ConditionalT::Type; + + //--- + template struct EnableIfT { }; + template< typename Ty > struct EnableIfT { using type = Ty; }; + template using EnableIfType = typename EnableIfT::Type; + + //--- + template struct AddLvalueReferenceT { using Type = Ty&; }; + template struct AddLvalueReferenceT { using Type = Ty&; }; + template<> struct AddLvalueReferenceT< void> { using Type = void; }; + template<> struct AddLvalueReferenceT { using Type = const void; }; + template<> struct AddLvalueReferenceT { using Type = volatile void; }; + template<> struct AddLvalueReferenceT { using Type = const volatile void; }; + template using AddLvalueReferenceType = typename AddLvalueReferenceT::Type; + + //--- + template struct AddRvalueReferenceT { using Type = Ty&&; }; + template struct AddRvalueReferenceT { using Type = Ty&; }; + template<> struct AddRvalueReferenceT< void> { using Type = void; }; + template<> struct AddRvalueReferenceT { using Type = const void; }; + template<> struct AddRvalueReferenceT { using Type = volatile void; }; + template<> struct AddRvalueReferenceT { using Type = const volatile void; }; + template using AddRvalueReferenceType = typename AddRvalueReferenceT::Type; + + //--- + template struct RemoveReferenceT { using Type = Ty; }; + template struct RemoveReferenceT { using Type = Ty; }; + template struct RemoveReferenceT { using Type = Ty; }; + template using RemoveReferenceType = typename RemoveReferenceT::Type; + + //--- + template struct AddPointerT { using Type = TypeIdentityType*>; }; + template using AddPointerType = typename AddPointerT::Type; + + //--- + template struct RemovePointerT { using Type = Ty; }; + template struct RemovePointerT< Ty* > { using Type = Ty; }; + template struct RemovePointerT< const Ty* > { using Type = Ty; }; + template struct RemovePointerT< volatile Ty* > { using Type = Ty; }; + template struct RemovePointerT { using Type = Ty; }; + template struct RemovePointerT { using Type = Ty; }; + template struct RemovePointerT< Ty* const > { using Type = Ty; }; + template struct RemovePointerT< Ty* volatile> { using Type = Ty; }; + template struct RemovePointerT< Ty* const volatile> { using Type = Ty; }; + template using RemovePointerType = typename RemovePointerT::Type; + + //--- + template struct AddCvT { using Type = const volatile Ty; }; + template using AddCvType = typename AddCvT::Type; + + //--- + template struct RemoveCvT { using Type = Ty; }; + template struct RemoveCvT { using Type = Ty; }; + template struct RemoveCvT { using Type = Ty; }; + template struct RemoveCvT { using Type = Ty; }; + template using RemoveCvType = typename RemoveCvT::Type; + + //--- + template struct AddConstT { using Type = const Ty; }; + template using AddConstType = typename AddConstT::Type; + + //--- + template struct RemoveConstT { using Type = Ty; }; + template struct RemoveConstT { using Type = Ty; }; + template using RemoveConstType = typename RemoveConstT::Type; + + //--- + template struct AddVolatileT { using Type = volatile Ty; }; + template using AddVolatileType = typename AddVolatileT::Type; + + //--- + template struct RemoveVolatileT { using Type = Ty; }; + template struct RemoveVolatileT { using Type = Ty; }; + template using RemoveVolatileType = typename RemoveVolatileT::Type; + + //--- + + template struct IsBoundedArrayT : FalseConstant {}; + template struct IsBoundedArrayT : TrueConstant {}; + + template + inline constexpr bool isBoundedArray() + { + return IsBoundedArrayT::value; + } + + template struct IsUnboundedArrayT : FalseConstant {}; + template struct IsUnboundedArrayT : TrueConstant {}; + + template + inline constexpr bool isUnboundedArray() + { + return IsUnboundedArrayT::value; + } + + template + inline constexpr bool isArray() + { + return isBoundedArray() + || isUnboundedArray() + ; + } + + template + constexpr bool isEnum() + { + return __is_enum(Ty); + } + + template + inline constexpr bool isUnion() + { + return __is_union(Ty); + } + + template + inline constexpr bool isAbstract() + { + return __is_abstract(Ty); + } + + template + inline constexpr bool isAggregate() + { + return __is_aggregate(Ty); + } + + template + inline constexpr bool isBaseOf() + { + return __is_base_of(BaseT, DerivedT); + } + + template + inline constexpr bool isPolymorphic() + { + return __is_polymorphic(Ty); + } + + template + inline constexpr bool isDestructorVirtual() + { + return __has_virtual_destructor(Ty); + } + + template + inline constexpr bool isClass() + { + return __is_class(Ty); + } + + template + inline constexpr bool isFinal() + { + return __is_final(Ty); + } + + template + inline constexpr bool isEmpty() + { + return __is_empty(Ty); + } + + template + inline constexpr bool isStandardLayout() + { + return __is_standard_layout(Ty); + } + + template + inline constexpr bool isTrivial() + { + return __is_trivial(Ty); + } + + template + inline constexpr bool isPod() + { + return isStandardLayout() + && isTrivial() + ; + } + + template + inline constexpr bool isAssignable() + { + return __is_assignable(Ty, FromT); + } + + template + inline constexpr bool isCopyAssignable() + { + return isAssignable< + AddLvalueReferenceType + , AddLvalueReferenceType + >(); + } + + template + inline constexpr bool isMoveAssignable() + { + return isAssignable< + AddLvalueReferenceType + , AddRvalueReferenceType + >(); + } + + template + inline constexpr bool isTriviallyAssignable() + { + return __is_trivially_assignable(Ty, FromT); + } + + template + inline constexpr bool isTriviallyCopyAssignable() + { + return isTriviallyAssignable< + AddLvalueReferenceType + , AddRvalueReferenceType + >(); + } + + template + inline constexpr bool isTriviallyMoveAssignable() + { + return isTriviallyAssignable< + AddLvalueReferenceType + , AddRvalueReferenceType + >(); + } + + template + inline constexpr bool isConstructible() + { + return __is_constructible(Ty, ArgsT...); + } + + template + inline constexpr bool isCopyConstructible() + { + return isConstructible>(); + } + + template + inline constexpr bool isMoveConstructible() + { + return isConstructible(); + } + + template + inline constexpr bool isTriviallyConstructible() + { + return __is_trivially_constructible(Ty, ArgsT...); + } + + template + inline constexpr bool isTriviallyCopyConstructible() + { + return isTriviallyConstructible>(); + } + + template + inline constexpr bool isTriviallyMoveConstructible() + { + return isTriviallyConstructible>(); + } + + template + inline constexpr bool isTriviallyCopyable() + { + return __is_trivially_copyable(Ty); + } + + template + inline constexpr bool isTriviallyDestructible() + { +#if BX_COMPILER_GCC + return __has_trivial_destructor(Ty); +#else + return __is_trivially_destructible(Ty); +#endif // BX_COMPILER_GCC + } + + template struct IsConstT : FalseConstant {}; + template struct IsConstT : TrueConstant {}; + + template + inline constexpr bool isConst() + { + return IsConstT::value; + } + + template struct IsVolatileT : FalseConstant {}; + template struct IsVolatileT : TrueConstant {}; + + template + inline constexpr bool isVolatile() + { + return IsVolatileT::value; + } + + template struct IsLvalueReferenceT : FalseConstant {}; + template struct IsLvalueReferenceT : TrueConstant {}; + + template + inline constexpr bool isLvalueReference() + { + return IsLvalueReferenceT::value; + } + + template struct IsRvalueReferenceT : FalseConstant {}; + template struct IsRvalueReferenceT : TrueConstant {}; + + template + inline constexpr bool isRvalueReference() + { + return IsRvalueReferenceT::value; + } + + template + inline constexpr bool isReference() + { + return isLvalueReference() + || isRvalueReference() + ; + } + + template struct IsPointerT : FalseConstant {}; + template struct IsPointerT : TrueConstant {}; + template struct IsPointerT : TrueConstant {}; + template struct IsPointerT : TrueConstant {}; + template struct IsPointerT : TrueConstant {}; + + template + inline constexpr bool isPointer() + { + return IsPointerT::value; + } + + template + inline constexpr bool isSigned() + { + return Ty(-1) < Ty(0); + } + + template + inline constexpr bool isUnsigned() + { + return Ty(-1) > Ty(0); + } + + template struct IsIntegerT : FalseConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT< signed char > : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT< short > : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT< int > : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT< long > : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + template<> struct IsIntegerT< long long> : TrueConstant {}; + template<> struct IsIntegerT : TrueConstant {}; + + template + inline constexpr bool isInteger() + { + return IsIntegerT::value; + } + + template struct IsFloatingPointT : FalseConstant {}; + template<> struct IsFloatingPointT : TrueConstant {}; + template<> struct IsFloatingPointT< double> : TrueConstant {}; + template<> struct IsFloatingPointT : TrueConstant {}; + + template + inline constexpr bool isFloatingPoint() + { + return IsFloatingPointT::value; + } + + template + inline constexpr bool isArithmetic() + { + return isInteger() + || isFloatingPoint() + ; + } + + template struct IsSameT : FalseConstant {}; + template struct IsSameT : TrueConstant {}; + + template + inline constexpr bool isSame() + { + return IsSameT::value; + } + + template + constexpr RemoveReferenceType&& move(Ty&& _a) + { + return static_cast&&>(_a); + } + + template + inline constexpr Ty&& forward(RemoveReferenceType& _a) + { + return static_cast(_a); + } + + template + inline constexpr Ty&& forward(RemoveReferenceType&& _a) + { + BX_STATIC_ASSERT(!isLvalueReference(), "Can not forward an Rvalue as an Lvalue."); + return static_cast(_a); + } + +} // namespace bx diff --git a/include/bx/typetraits.h b/include/bx/typetraits.h new file mode 100644 index 0000000..979dbb4 --- /dev/null +++ b/include/bx/typetraits.h @@ -0,0 +1,280 @@ +/* + * Copyright 2010-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx/blob/master/LICENSE + */ + +#ifndef BX_TYPETRAITS_H_HEADER_GUARD +#define BX_TYPETRAITS_H_HEADER_GUARD + +namespace bx +{ + /// Returns true if type `Ty` is array type with known bound, otherwise returns false. + template + constexpr bool isBoundedArray(); + + /// Returns true if type `Ty` is array type with unknown bound, otherwise returns false. + template + constexpr bool isUnboundedArray(); + + /// Returns true if type `Ty` is array type (bounded, or unbounded array), otherwise returns false. + template + constexpr bool isArray(); + + /// Returns true if type `Ty` is enumeration type, otherwise returns false. + template + constexpr bool isEnum(); + + /// Returns true if type `Ty` is union type, otherwise returns false. + template + constexpr bool isUnion(); + + /// Returns true if type `Ty` is non-union class type, otherwise returns false. + template + constexpr bool isClass(); + + /// Returns true if type `Ty` is abstract class type, otherwise returns false. + template + constexpr bool isAbstract(); + + /// Returns true if type `Ty` is aggregate class type, otherwise returns false. + template + constexpr bool isAggregate(); + + /// Returns true if type `DerivedT` is derived from `BaseT` type, or if both are the same + /// non-union type, otherwise returns false. + template + constexpr bool isBaseOf(); + + /// Returns true if type `Ty` is polymorphic class (if it has virtual function table) type, + /// otherwise returns false. + template + constexpr bool isPolymorphic(); + + /// Returns true if type `Ty` has virtual destructor, otherwise returns false. + template + constexpr bool isDestructorVirtual(); + + /// Returns true if type `Ty` is class type with final specifier, otherwise returns false. + template + constexpr bool isFinal(); + + /// Returns true if type `Ty` is non-union class type with no non-static + /// members (a.k.a. sizeof(Ty) is zero), otherwise returns false. + template + constexpr bool isEmpty(); + + /// Returns true if type `Ty` is standard-layout type, otherwise returns false. + template + constexpr bool isStandardLayout(); + + /// Returns true if type `Ty` is trivial type, otherwise returns false. + template + constexpr bool isTrivial(); + + /// Returns true if type `Ty` is POD (standard-layout, and trivial type), otherwise returns false. + template + constexpr bool isPod(); + + /// Returns true if type `FromT` can be assigned to type `Ty`, otherwise returns false. + template + constexpr bool isAssignable(); + + /// Returns true if type `Ty` has copy assignment operator, otherwise returns false. + template + constexpr bool isCopyAssignable(); + + /// Returns true if type `Ty` has move assignment operator, otherwise returns false. + template + constexpr bool isMoveAssignable(); + + /// Returns true if type `FromT` can be trivially assigned to type `Ty`, otherwise returns false. + template + constexpr bool isTriviallyAssignable(); + + /// Returns true if type `Ty` is trivially copy-assignable type, otherwise returns false. + template + constexpr bool isTriviallyCopyAssignable(); + + /// Returns true if type `Ty` is trivially move-assignable type, otherwise returns false. + template + constexpr bool isTriviallyMoveAssignable(); + + /// Returns true if type `Ty` is constructible when the specified argument types are used, + /// otherwise returns false. + template + constexpr bool isConstructible(); + + /// Returns true if type `Ty` has copy constructor, otherwise returns false. + template + constexpr bool isCopyConstructible(); + + /// Returns true if type `Ty` has move constructor, otherwise returns false. + template + constexpr bool isMoveConstructible(); + + /// Returns true if type `Ty` is trivially constructible when the specified argument types are used, + /// otherwise returns false. + template + constexpr bool isTriviallyConstructible(); + + /// Returns true if type `Ty` has trivial copy constructor, otherwise returns false. + template + constexpr bool isTriviallyCopyConstructible(); + + /// Returns true if type `Ty` has trivial move constructor, otherwise returns false. + template + constexpr bool isTriviallyMoveConstructible(); + + /// Returns true if type `Ty` is trivially copyable / POD type, otherwise returns false. + template + constexpr bool isTriviallyCopyable(); + + /// Returns true if type `Ty` has trivial destructor, otherwise returns false. + template + constexpr bool isTriviallyDestructible(); + + /// Returns true if type `Ty` is const-qualified type, otherwise returns false. + template + constexpr bool isConst(); + + /// Returns true if type `Ty` is volatile-qualified type, otherwise returns false. + template + constexpr bool isVolatile(); + + /// Returns true if type `Ty` is an reference type, otherwise returns false. + template + constexpr bool isReference(); + + /// Returns true if type `Ty` is an Lvalue reference type, otherwise returns false. + template + constexpr bool isLvalueReference(); + + /// Returns true if type `Ty` is an Rvalue reference type, otherwise returns false. + template + constexpr bool isRvalueReference(); + + /// Returns true if type `Ty` is an pointer type, otherwise returns false. + template + constexpr bool isPointer(); + + /// Returns true if type `Ty` is signed integer or floating-point type, otherwise returns false. + template + constexpr bool isSigned(); + + /// Returns true if type `Ty` is unsigned integer type, otherwise returns false. + template + constexpr bool isUnsigned(); + + /// Returns true if type `Ty` is integer type, otherwise returns false. + template + constexpr bool isInteger(); + + /// Returns true if type `Ty` is floating-point type, otherwise returns false. + template + constexpr bool isFloatingPoint(); + + /// Returns true if type `Ty` is arithmetic type, otherwise returns false. + template + constexpr bool isArithmetic(); + + /// Returns true if type `Ty` and type `Uy` are the same type, otherwise returns false. + template + constexpr bool isSame(); + +} // namespace bx + +#include "inline/typetraits.inl" + +namespace bx +{ + /// Compile-time constant of specified type `Ty` with specified value `ValueT`. + template + struct IntegralConstantT; + + /// Alias of IntegralConstantT. + template + using BoolConstantT = IntegralConstantT; + + /// Alias of BoolConstantT. + using FalseConstant = BoolConstantT; + + /// Alias of BoolConstantT. + using TrueConstant = BoolConstantT; + + /// Provides the member `Type` that names `Ty`. + template + using TypeIdentityType = typename TypeIdentityT::Type; + + /// Conditionally selects `Ty` if `BoolT` is true, otherwise selects `Uy` type. + template + using ConditionalType = typename ConditionalT::Type; + + /// If `BoolT` condition is true it provides `Ty` as `Type`, otherwise `Type` is undefined. + template + using EnableIfType = typename EnableIfT::Type; + + /// If `Ty` is an object type or a function type that has no cv- or ref- qualifier, provides + /// a member `Type` which is `Ty&`. If `Ty` is an Rvalue reference to some type `Uy`, then + /// type is `Uy&`, otherwise type is `Ty`. + template + using AddLvalueReferenceType = typename AddLvalueReferenceT::Type; + + /// If `Ty` is an object type or a function type that has no cv- or ref- qualifier, provides + /// a member `Type` which is `Ty&&`, otherwise type is `Ty`. + template + using AddRvalueReferenceType = typename AddRvalueReferenceT::Type; + + /// If the type `Ty` is a reference type, provides the member typedef `Type` + /// which is the type referred to by `Ty`, otherwise type is `Ty`. + template + using RemoveReferenceType = typename RemoveReferenceT::Type; + + /// If the type `Ty` is a reference type, provides the member typedef `Type` + /// which is a pointer to the referred type. + template + using AddPointerType = typename AddPointerT::Type; + + /// If the type `Ty` is a pointer type, provides the member typedef `Type` + /// which is the type pointed to by `Ty`, otherwise type is `Ty`. + template + using RemovePointerType = typename RemovePointerT::Type; + + /// Adds both `const`, and `volatile` to type `Ty`. + template + using AddCvType = typename AddCvT::Type; + + /// Removes the topmost `const`, or the topmost `volatile`, or both, from type `Ty` if present. + template + using RemoveCvType = typename RemoveCvT::Type; + + /// Adds `const` to type `Ty`. + template + using AddConstType = typename AddConstT::Type; + + /// Removes the topmost `const` from type `Ty` if present. + template + using RemoveConstType = typename RemoveConstT::Type; + + /// Adds `volatile` to type `Ty`. + template + using AddVolatileType = typename AddVolatileT::Type; + + /// Removes the topmost `volatile` from type `Ty` if present. + template + using RemoveVolatileType = typename RemoveVolatileT::Type; + + /// Removes reference from type `Ty` if present. + template + constexpr RemoveReferenceType&& move(Ty&& _a); + + /// Forwards Lvalues as either Lvalues or as Rvalues. + template + constexpr Ty&& forward(RemoveReferenceType& _type); + + /// Forwards Rvalues as Rvalues and prohibits forwarding of Rvalues as Lvalues. + template + constexpr Ty&& forward(RemoveReferenceT&& _type); + +} // namespace bx + +#endif // BX_TYPETRAITS_H_HEADER_GUARD diff --git a/tests/typetraits_test.cpp b/tests/typetraits_test.cpp new file mode 100644 index 0000000..d4bc0e8 --- /dev/null +++ b/tests/typetraits_test.cpp @@ -0,0 +1,657 @@ +/* + * Copyright 2010-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx/blob/master/LICENSE + */ + +#include "test.h" +#include + +struct TestClass { }; +struct TestClassFinal final { }; +struct TestClassMember { int32_t x; }; +struct TestClassMemberPrivate { int32_t x; private: int32_t y; }; +struct TestClassStaticOnly { static int32_t x; }; +struct TestClassCtor { TestClassCtor (const TestClassCtor&) {} }; +struct TestClassDefaultCtor { TestClassDefaultCtor (const TestClassDefaultCtor&) = default; }; +struct TestClassDefaultDtor { ~TestClassDefaultDtor () = default; }; +struct TestClassVirtualDtor { virtual ~TestClassVirtualDtor () = default; }; +struct TestClassAbstractBase { virtual ~TestClassAbstractBase() = 0; }; +struct TestClassPolymorphic { virtual int32_t x() { return 1389; } }; +struct TestClassDerivedA /* */ + : TestClass { }; +struct TestClassDerivedB /* */ + : TestClassDerivedA { }; +struct TestClassDerivedX /* */ + : TestClassVirtualDtor { }; +union TestUnionEmpty { }; +union TestUnion { int32_t x; float y; }; +enum TestEnumEmpty { }; +enum TestEnum { Enum }; + +TEST_CASE("type-traits isReference", "") +{ + STATIC_REQUIRE(!bx::isReference() ); + STATIC_REQUIRE( bx::isReference() ); + STATIC_REQUIRE( bx::isReference() ); + STATIC_REQUIRE(!bx::isReference() ); + STATIC_REQUIRE( bx::isReference() ); + STATIC_REQUIRE( bx::isReference() ); + STATIC_REQUIRE(!bx::isReference() ); + STATIC_REQUIRE( bx::isReference() ); + STATIC_REQUIRE( bx::isReference() );; +} + +TEST_CASE("type-traits isLvalueReference", "") +{ + STATIC_REQUIRE(!bx::isLvalueReference() ); + STATIC_REQUIRE( bx::isLvalueReference() ); + STATIC_REQUIRE(!bx::isLvalueReference() ); + STATIC_REQUIRE(!bx::isLvalueReference() ); + STATIC_REQUIRE( bx::isLvalueReference() ); + STATIC_REQUIRE(!bx::isLvalueReference() ); + STATIC_REQUIRE(!bx::isLvalueReference() ); + STATIC_REQUIRE( bx::isLvalueReference() ); + STATIC_REQUIRE(!bx::isLvalueReference() );; +} + +TEST_CASE("type-traits isRvalueReference", "") +{ + STATIC_REQUIRE(!bx::isRvalueReference() ); + STATIC_REQUIRE(!bx::isRvalueReference() ); + STATIC_REQUIRE( bx::isRvalueReference() ); + STATIC_REQUIRE(!bx::isRvalueReference() ); + STATIC_REQUIRE(!bx::isRvalueReference() ); + STATIC_REQUIRE( bx::isRvalueReference() ); + STATIC_REQUIRE(!bx::isRvalueReference() ); + STATIC_REQUIRE(!bx::isRvalueReference() ); + STATIC_REQUIRE( bx::isRvalueReference() );; +} + +TEST_CASE("type-traits isPointer", "") +{ + STATIC_REQUIRE(!bx::isPointer() ); + STATIC_REQUIRE(!bx::isPointer() ); + STATIC_REQUIRE( bx::isPointer() ); + STATIC_REQUIRE( bx::isPointer() ); + STATIC_REQUIRE(!bx::isPointer() ); + STATIC_REQUIRE( bx::isPointer() ); + STATIC_REQUIRE(!bx::isPointer() ); +} + +TEST_CASE("type-traits AddLvalueReferenceT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass& >() ); + STATIC_REQUIRE( bx::isSame, TestClass& >() ); + STATIC_REQUIRE( bx::isSame, TestClass& >() ); + + STATIC_REQUIRE( bx::isLvalueReference >() ); + STATIC_REQUIRE( bx::isLvalueReference >() ); + STATIC_REQUIRE( bx::isLvalueReference >() ); +} + +TEST_CASE("type-traits AddRvalueReferenceT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass&& >() ); + STATIC_REQUIRE( bx::isSame, TestClass& >() ); + STATIC_REQUIRE( bx::isSame, TestClass&& >() ); + + STATIC_REQUIRE( bx::isRvalueReference >() ); + STATIC_REQUIRE(!bx::isRvalueReference >() ); + STATIC_REQUIRE( bx::isRvalueReference >() ); +} + +TEST_CASE("type-traits RemoveReferenceT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + + STATIC_REQUIRE(!bx::isReference >() ); + STATIC_REQUIRE(!bx::isReference >() ); + STATIC_REQUIRE(!bx::isReference >() ); +} + +TEST_CASE("type-traits AddPointerT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass* >() ); + STATIC_REQUIRE( bx::isSame, TestClass** >() ); + STATIC_REQUIRE( bx::isSame, TestClass* >() ); + STATIC_REQUIRE( bx::isSame, TestClass*** >() ); + + STATIC_REQUIRE( bx::isPointer >() ); + STATIC_REQUIRE( bx::isPointer >() ); + STATIC_REQUIRE( bx::isPointer >() ); + STATIC_REQUIRE( bx::isPointer >() ); +} + +TEST_CASE("type-traits RemovePointerT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass* >() ); + STATIC_REQUIRE( bx::isSame>, TestClass >() ); + + STATIC_REQUIRE(!bx::isPointer >() ); + STATIC_REQUIRE(!bx::isPointer >() ); + STATIC_REQUIRE( bx::isPointer >() ); + STATIC_REQUIRE(!bx::isPointer> >() ); +} + +TEST_CASE("type-traits AddConstT", "") +{ + STATIC_REQUIRE( bx::isSame, const TestClass >() ); + STATIC_REQUIRE( bx::isSame, const TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass* const >() ); + STATIC_REQUIRE( bx::isSame, TestClass* const volatile >() ); +} + +TEST_CASE("type-traits RemoveConstT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, volatile TestClass >() ); + STATIC_REQUIRE(!bx::isSame, volatile TestClass*>() ); + STATIC_REQUIRE( bx::isSame, TestClass* volatile>() ); +} + +TEST_CASE("type-traits AddVolatileT", "") +{ + STATIC_REQUIRE( bx::isSame, volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass* volatile >() ); + STATIC_REQUIRE( bx::isSame, TestClass* const volatile >() ); +} + +TEST_CASE("type-traits RemoveVolatileT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, const TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, const TestClass >() ); + STATIC_REQUIRE(!bx::isSame, const TestClass* >() ); + STATIC_REQUIRE( bx::isSame, TestClass* const >() ); +} + +TEST_CASE("type-traits AddCvT", "") +{ + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass >() ); + STATIC_REQUIRE( bx::isSame, const volatile TestClass* const volatile >() ); + STATIC_REQUIRE( bx::isSame, TestClass* const volatile >() ); +} + +TEST_CASE("type-traits RemoveCvT", "") +{ + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE( bx::isSame, TestClass >() ); + STATIC_REQUIRE(!bx::isSame, TestClass* >() ); + STATIC_REQUIRE( bx::isSame, TestClass* >() ); +} + +TEST_CASE("type-traits isTriviallyCopyable", "") +{ + STATIC_REQUIRE( bx::isTriviallyCopyable() ); + STATIC_REQUIRE( bx::isTriviallyCopyable() ); + STATIC_REQUIRE(!bx::isTriviallyCopyable() ); + STATIC_REQUIRE( bx::isTriviallyCopyable() ); + STATIC_REQUIRE( bx::isTriviallyCopyable() ); + STATIC_REQUIRE(!bx::isTriviallyCopyable() ); +} + +TEST_CASE("type-traits isTriviallyConstructible", "") +{ + STATIC_REQUIRE( bx::isTriviallyConstructible() ); + STATIC_REQUIRE( bx::isTriviallyConstructible() ); + STATIC_REQUIRE(!bx::isTriviallyConstructible() ); + STATIC_REQUIRE(!bx::isTriviallyConstructible() ); + STATIC_REQUIRE( bx::isTriviallyConstructible() ); + STATIC_REQUIRE(!bx::isTriviallyConstructible() ); +} + +TEST_CASE("type-traits isTriviallyDestructible", "") +{ + STATIC_REQUIRE( bx::isTriviallyDestructible() ); + STATIC_REQUIRE( bx::isTriviallyDestructible() ); + STATIC_REQUIRE( bx::isTriviallyDestructible() ); + STATIC_REQUIRE( bx::isTriviallyDestructible() ); + STATIC_REQUIRE( bx::isTriviallyDestructible() ); + STATIC_REQUIRE(!bx::isTriviallyDestructible() ); +} + +TEST_CASE("type-traits isSigned", "") +{ + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE(!bx::isSigned() ); + + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); + STATIC_REQUIRE( bx::isSigned() ); +} + +TEST_CASE("type-traits isUnsigned", "") +{ + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE( bx::isUnsigned() ); + + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); + STATIC_REQUIRE(!bx::isUnsigned() ); +} + +TEST_CASE("type-traits isInteger", "") +{ + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + STATIC_REQUIRE( bx::isInteger() ); + + STATIC_REQUIRE(!bx::isInteger() ); + STATIC_REQUIRE(!bx::isInteger() ); + STATIC_REQUIRE(!bx::isInteger() ); + + STATIC_REQUIRE(!bx::isInteger() ); + STATIC_REQUIRE(!bx::isInteger() ); + STATIC_REQUIRE(!bx::isInteger() ); + STATIC_REQUIRE(!bx::isInteger() ); + STATIC_REQUIRE(!bx::isInteger() ); +} + +TEST_CASE("type-traits isFloatingPoint", "") +{ + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + + STATIC_REQUIRE( bx::isFloatingPoint() ); + STATIC_REQUIRE( bx::isFloatingPoint() ); + STATIC_REQUIRE( bx::isFloatingPoint() ); + + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); + STATIC_REQUIRE(!bx::isFloatingPoint() ); +} + +TEST_CASE("type-traits isArithmetic", "") +{ + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + STATIC_REQUIRE( bx::isArithmetic() ); + + STATIC_REQUIRE(!bx::isArithmetic() ); + STATIC_REQUIRE(!bx::isArithmetic() ); + STATIC_REQUIRE(!bx::isArithmetic() ); + STATIC_REQUIRE(!bx::isArithmetic() ); + STATIC_REQUIRE(!bx::isArithmetic() ); +} + +TEST_CASE("type-traits isBoundedArray", "") +{ + STATIC_REQUIRE(!bx::isBoundedArray() ); + STATIC_REQUIRE(!bx::isBoundedArray() ); + STATIC_REQUIRE( bx::isBoundedArray() ); + STATIC_REQUIRE(!bx::isBoundedArray() ); + STATIC_REQUIRE(!bx::isBoundedArray() ); + STATIC_REQUIRE(!bx::isBoundedArray() ); + STATIC_REQUIRE( bx::isBoundedArray() ); +} + +TEST_CASE("type-traits isUnboundedArray", "") +{ + STATIC_REQUIRE(!bx::isUnboundedArray() ); + STATIC_REQUIRE( bx::isUnboundedArray() ); + STATIC_REQUIRE(!bx::isUnboundedArray() ); + STATIC_REQUIRE(!bx::isUnboundedArray() ); + STATIC_REQUIRE(!bx::isUnboundedArray() ); + STATIC_REQUIRE( bx::isUnboundedArray() ); + STATIC_REQUIRE(!bx::isUnboundedArray() ); +} + +TEST_CASE("type-traits isArray", "") +{ + STATIC_REQUIRE(!bx::isArray() ); + STATIC_REQUIRE( bx::isArray() ); + STATIC_REQUIRE( bx::isArray() ); + STATIC_REQUIRE(!bx::isArray() ); + STATIC_REQUIRE(!bx::isArray() ); + STATIC_REQUIRE( bx::isArray() ); + STATIC_REQUIRE( bx::isArray() ); + STATIC_REQUIRE( bx::isArray() ); +} + +TEST_CASE("type-traits isEnum", "") +{ + STATIC_REQUIRE(!bx::isEnum() ); + STATIC_REQUIRE(!bx::isEnum() ); + STATIC_REQUIRE(!bx::isEnum() ); + STATIC_REQUIRE(!bx::isEnum() ); + STATIC_REQUIRE(!bx::isEnum() ); + STATIC_REQUIRE( bx::isEnum() ); + STATIC_REQUIRE( bx::isEnum() ); +} + +TEST_CASE("type-traits isUnion", "") +{ + STATIC_REQUIRE(!bx::isUnion() ); + STATIC_REQUIRE( bx::isUnion() ); + STATIC_REQUIRE( bx::isUnion() ); + STATIC_REQUIRE(!bx::isUnion() ); + STATIC_REQUIRE(!bx::isUnion() ); + STATIC_REQUIRE(!bx::isUnion() ); + STATIC_REQUIRE(!bx::isUnion() ); +} + +TEST_CASE("type-traits isClass", "") +{ + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE( bx::isClass() ); + STATIC_REQUIRE(!bx::isClass() ); + STATIC_REQUIRE(!bx::isClass() ); + STATIC_REQUIRE(!bx::isClass() ); +} + +TEST_CASE("type-traits isFinal", "") +{ + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE( bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); + STATIC_REQUIRE(!bx::isFinal() ); +} + +TEST_CASE("type-traits isEmpty", "") +{ + STATIC_REQUIRE( bx::isEmpty() ); + STATIC_REQUIRE( bx::isEmpty() ); + STATIC_REQUIRE( bx::isEmpty() ); + STATIC_REQUIRE( bx::isEmpty() ); + STATIC_REQUIRE( bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); + STATIC_REQUIRE(!bx::isEmpty() ); +} + +TEST_CASE("type-traits isStandardLayout", "") +{ + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE(!bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE(!bx::isStandardLayout() ); + STATIC_REQUIRE(!bx::isStandardLayout() ); + STATIC_REQUIRE(!bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); + STATIC_REQUIRE( bx::isStandardLayout() ); +} + +TEST_CASE("type-traits isTrivial", "") +{ + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE(!bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE(!bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE(!bx::isTrivial() ); + STATIC_REQUIRE(!bx::isTrivial() ); + STATIC_REQUIRE(!bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); + STATIC_REQUIRE( bx::isTrivial() ); +} + +TEST_CASE("type-traits isPod", "") +{ + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE(!bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE(!bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE(!bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE(!bx::isPod() ); + STATIC_REQUIRE(!bx::isPod() ); + STATIC_REQUIRE(!bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); + STATIC_REQUIRE( bx::isPod() ); +} + +TEST_CASE("type-traits isPolymorphic", "") +{ + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE( bx::isPolymorphic() ); + STATIC_REQUIRE( bx::isPolymorphic() ); + STATIC_REQUIRE( bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE( bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); + STATIC_REQUIRE(!bx::isPolymorphic() ); +} + +TEST_CASE("type-traits isDestructorVirtual", "") +{ + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE( bx::isDestructorVirtual() ); + STATIC_REQUIRE( bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE( bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); + STATIC_REQUIRE(!bx::isDestructorVirtual() ); +} + +TEST_CASE("type-traits isBaseOf", "") +{ + STATIC_REQUIRE( bx::isBaseOf() ); + STATIC_REQUIRE( bx::isBaseOf() ); + STATIC_REQUIRE( bx::isBaseOf() ); + STATIC_REQUIRE(!bx::isBaseOf() ); + STATIC_REQUIRE(!bx::isBaseOf() ); + STATIC_REQUIRE(!bx::isBaseOf() ); + STATIC_REQUIRE(!bx::isBaseOf() ); +}