feat(typetraits): add TypeTraits/PrimaryType.h and the corresponding testing

This commit is contained in:
_Redstone_c_ 2021-12-10 21:43:57 +08:00
parent cfb53c21e0
commit 60b4ec6f58
4 changed files with 222 additions and 0 deletions

View File

@ -0,0 +1,113 @@
#include "Testing/TypeTraitsTesting.h"
#include "Misc/AssertionMacros.h"
#include "TypeTraits/HelperClasses.h"
#include "TypeTraits/PrimaryType.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
// Warning: The test here is not a complete test, it is only used to determine whether the environment supports the traits
int32 TestObject;
void TestFunction() { }
struct FTestStruct { };
enum ETestEnum { };
enum class ETestEnumClass { };
union FTestUnion { };
void TestTypeTraits()
{
// HelperClasses.h
always_check(TypeTraits::TIntegralConstant<1>::Value == 1);
always_check(static_cast<int32>(TypeTraits::TIntegralConstant<2>::Value) == 2);
always_check(TypeTraits::TIntegralConstant<3>() == 3);
always_check(!TypeTraits::FFalse::Value);
always_check(TypeTraits::FTrue::Value);
always_check(TypeTraits::TAnd<TypeTraits::FTrue>::Value);
always_check(!TypeTraits::TAnd<TypeTraits::FFalse>::Value);
always_check((TypeTraits::TAnd<TypeTraits::FTrue, TypeTraits::FTrue>::Value));
always_check(!(TypeTraits::TAnd<TypeTraits::FFalse, TypeTraits::FTrue>::Value));
always_check(!(TypeTraits::TAnd<TypeTraits::FTrue, TypeTraits::FFalse>::Value));
always_check(!(TypeTraits::TAnd<TypeTraits::FFalse, TypeTraits::FFalse>::Value));
always_check(TypeTraits::TOr<TypeTraits::FTrue>::Value);
always_check(!TypeTraits::TOr<TypeTraits::FFalse>::Value);
always_check((TypeTraits::TOr<TypeTraits::FTrue, TypeTraits::FTrue>::Value));
always_check((TypeTraits::TOr<TypeTraits::FFalse, TypeTraits::FTrue>::Value));
always_check((TypeTraits::TOr<TypeTraits::FTrue, TypeTraits::FFalse>::Value));
always_check(!(TypeTraits::TOr<TypeTraits::FFalse, TypeTraits::FFalse>::Value));
always_check(!TypeTraits::TNot<TypeTraits::FTrue>::Value);
always_check(TypeTraits::TNot<TypeTraits::FFalse>::Value);
// PrimaryType.h
always_check(!TypeTraits::TIsVoid<int32>::Value);
always_check(TypeTraits::TIsVoid<void>::Value);
always_check(TypeTraits::TIsVoid<const void>::Value);
always_check(TypeTraits::TIsVoid<const volatile void>::Value);
always_check(TypeTraits::TIsVoid<volatile void>::Value);
always_check(!TypeTraits::TIsNullPointer<int32>::Value);
always_check(TypeTraits::TIsNullPointer<nullptr_t>::Value);
always_check(TypeTraits::TIsIntegral<int32>::Value);
always_check(!TypeTraits::TIsIntegral<float>::Value);
always_check(!TypeTraits::TIsFloatingPoint<int32>::Value);
always_check(TypeTraits::TIsFloatingPoint<float>::Value);
always_check(!TypeTraits::TIsArray<int32>::Value);
always_check(TypeTraits::TIsArray<int32[]>::Value);
always_check(TypeTraits::TIsArray<int32[10]>::Value);
always_check(!TypeTraits::TIsPointer<int32>::Value);
always_check(TypeTraits::TIsPointer<int32*>::Value);
always_check(!TypeTraits::TIsLValueReference<int32>::Value);
always_check(TypeTraits::TIsLValueReference<int32&>::Value);
always_check(!TypeTraits::TIsLValueReference<int32&&>::Value);
always_check(!TypeTraits::TIsRValueReference<int32>::Value);
always_check(!TypeTraits::TIsRValueReference<int32&>::Value);
always_check(TypeTraits::TIsRValueReference<int32&&>::Value);
always_check(TypeTraits::TIsMemberObjectPointer<int32(FTestStruct::*)>::Value);
always_check(!TypeTraits::TIsMemberObjectPointer<int32(FTestStruct::*)()>::Value);
always_check(!TypeTraits::TIsMemberFunctionPointer<int32(FTestStruct::*)>::Value);
always_check(TypeTraits::TIsMemberFunctionPointer<int32(FTestStruct::*)()>::Value);
always_check(!TypeTraits::TIsEnum<int32>::Value);
always_check(!TypeTraits::TIsEnum<FTestStruct>::Value);
always_check(TypeTraits::TIsEnum<ETestEnum>::Value);
always_check(TypeTraits::TIsEnum<ETestEnumClass>::Value);
always_check(!TypeTraits::TIsUnion<int32>::Value);
always_check(!TypeTraits::TIsUnion<FTestStruct>::Value);
always_check(TypeTraits::TIsUnion<FTestUnion>::Value);
always_check(!TypeTraits::TIsUnion<int32>::Value);
always_check(!TypeTraits::TIsUnion<FTestStruct>::Value);
always_check(TypeTraits::TIsUnion<FTestUnion>::Value);
always_check(!TypeTraits::TIsFunction<int32>::Value);
always_check(!TypeTraits::TIsFunction<FTestStruct>::Value);
always_check(!TypeTraits::TIsFunction<FTestUnion>::Value);
always_check(TypeTraits::TIsFunction<int32(int32)>::Value);
always_check(!TypeTraits::TIsEnumClass<ETestEnum>::Value);
always_check(TypeTraits::TIsEnumClass<ETestEnumClass>::Value);
}
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,13 @@
#pragma once
#include "CoreTypes.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
void REDCRAFTUTILITY_API TestTypeTraits();
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,52 @@
#pragma once
#include "CoreTypes.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(TypeTraits)
template <typename InType, InType InValue>
struct TConstant
{
using Type = InType;
static constexpr Type Value = InValue;
constexpr operator Type() const { return Value; }
constexpr Type operator()() const { return Value; }
};
template <bool InValue>
using TBoolConstant = TConstant<bool, InValue>;
template <int32 InValue>
using TIntegralConstant = TConstant<int32, InValue>;
using FTrue = TBoolConstant<true>;
using FFalse = TBoolConstant<false>;
template <typename... Types>
struct TAnd;
template <typename LHS, typename... RHS>
struct TAnd<LHS, RHS...> : TBoolConstant<LHS::Value&& TAnd<RHS...>::Value> { };
template <>
struct TAnd<> : FTrue { };
template <typename... Types>
struct TOr;
template <typename LHS, typename... RHS>
struct TOr<LHS, RHS...> : TBoolConstant<LHS::Value || TOr<RHS...>::Value> { };
template <>
struct TOr<> : FFalse { };
template <typename Type>
struct TNot : TBoolConstant<!Type::Value> { };
NAMESPACE_END(TypeTraits)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,44 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/HelperClasses.h"
#include <type_traits>
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(TypeTraits)
template <typename T> struct TIsVoid : TBoolConstant<NAMESPACE_STD::is_void_v<T>> { };
template <typename T> struct TIsNullPointer : TBoolConstant<NAMESPACE_STD::is_null_pointer_v<T>> { };
template <typename T> struct TIsIntegral : TBoolConstant<NAMESPACE_STD::is_integral_v<T>> { };
template <typename T> struct TIsFloatingPoint : TBoolConstant<NAMESPACE_STD::is_floating_point_v<T>> { };
template <typename T> struct TIsArray : TBoolConstant<NAMESPACE_STD::is_array_v<T>> { };
template <typename T> struct TIsPointer : TBoolConstant<NAMESPACE_STD::is_pointer_v<T>> { };
template <typename T> struct TIsLValueReference : TBoolConstant<NAMESPACE_STD::is_lvalue_reference_v<T>> { };
template <typename T> struct TIsRValueReference : TBoolConstant<NAMESPACE_STD::is_rvalue_reference_v<T>> { };
template <typename T> struct TIsMemberObjectPointer : TBoolConstant<NAMESPACE_STD::is_member_object_pointer_v<T>> { };
template <typename T> struct TIsMemberFunctionPointer : TBoolConstant<NAMESPACE_STD::is_member_function_pointer_v<T>> { };
template <typename T> struct TIsEnum : TBoolConstant<NAMESPACE_STD::is_enum_v<T>> { };
template <typename T> struct TIsUnion : TBoolConstant<NAMESPACE_STD::is_union_v<T>> { };
template <typename T> struct TIsClass : TBoolConstant<NAMESPACE_STD::is_class_v<T>> { };
template <typename T> struct TIsFunction : TBoolConstant<NAMESPACE_STD::is_function_v<T>> { };
NAMESPACE_PRIVATE_BEGIN
static char(&Resolve(int))[2];
static char Resolve(...);
template <typename T>
struct TIsEnumConvertibleToInt : TBoolConstant<sizeof(Resolve(T())) - 1> { };
NAMESPACE_PRIVATE_END
template <typename T>
struct TIsEnumClass : TBoolConstant<TAnd<TIsEnum<T>, TNot<NAMESPACE_PRIVATE::TIsEnumConvertibleToInt<T>>>::Value> { };
NAMESPACE_END(TypeTraits)
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END