// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/BaseTypes.h" #ifndef DOXYGEN // @formatter:off //////////////////////////////////////////////////////////////////////////////////// namespace THelpers { template struct TIsTriviallyDestructibleImpl { enum { Value = true }; }; template struct TIsTriviallyDestructibleImpl { #if defined(__clang__) && __clang_major__ >= 15 enum { Value = __is_trivially_destructible(T) }; #else enum { Value = __has_trivial_destructor(T) }; #endif }; } //////////////////////////////////////////////////////////////////////////////////// // Performs boolean AND operation. template struct TAnd; template struct TAndValue { enum { Value = TAnd::Value }; }; template struct TAndValue { enum { Value = false }; }; template struct TAnd : TAndValue { }; template<> struct TAnd<> { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// // Performs boolean OR operation. template struct TOr; template struct TOrValue { enum { Value = TOr::Value }; }; template struct TOrValue { enum { Value = true }; }; template struct TOr : TOrValue { }; template<> struct TOr<> { enum { Value = false }; }; //////////////////////////////////////////////////////////////////////////////////// // Performs boolean NOT operation. template struct TNot { enum { Value = !Type::Value }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsTheSame { enum { Value = false }; }; template struct TIsTheSame { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsLValueReference { enum { Value = false }; }; template struct TIsLValueReference { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsRValueReferenceType { enum { Value = false }; }; template struct TIsRValueReferenceType { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsReferenceType { enum { Value = false }; }; template struct TIsReferenceType { enum { Value = true }; }; template struct TIsReferenceType { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsVoidType { enum { Value = false }; }; template<> struct TIsVoidType { enum { Value = true }; }; template<> struct TIsVoidType { enum { Value = true }; }; template<> struct TIsVoidType { enum { Value = true }; }; template<> struct TIsVoidType { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// // Checks if a type is a pointer. template struct TIsPointer { enum { Value = false }; }; template struct TIsPointer { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// // Checks if a type is an enum. template struct TIsEnum { enum { Value = __is_enum(T) }; }; //////////////////////////////////////////////////////////////////////////////////// // Checks if a type is POD (plain old data type). template struct TIsPODType { enum { Value = TOrValue<__is_pod(T) || __is_enum(T), TIsPointer>::Value }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsBaseOf { enum { Value = __is_base_of(Base, Derived) }; }; //////////////////////////////////////////////////////////////////////////////////// // Removes any const or volatile qualifiers from a type. template struct TRemoveCV { typedef T Type; }; template struct TRemoveCV { typedef T Type; }; template struct TRemoveCV { typedef T Type; }; template struct TRemoveCV { typedef T Type; }; //////////////////////////////////////////////////////////////////////////////////// // Removes any reference qualifiers from a type. template struct TRemoveReference { typedef T Type; }; template struct TRemoveReference { typedef T Type; }; template struct TRemoveReference { typedef T Type; }; //////////////////////////////////////////////////////////////////////////////////// // Removes any const qualifiers from a type. template struct TRemoveConst { typedef T Type; }; template struct TRemoveConst { typedef T Type; }; //////////////////////////////////////////////////////////////////////////////////// // Adds qualifiers to a type. template struct TAddCV { typedef const volatile T Type; }; template struct TAddConst { typedef const T Type; }; //////////////////////////////////////////////////////////////////////////////////// // Creates a lvalue or rvalue reference type. namespace THelpers { template struct TTtypeIdentity { using Type = T; }; template auto TTryAddLValueReference(int) -> TTtypeIdentity; template auto TTryAddLValueReference(...) -> TTtypeIdentity; template auto TTryAddRValueReference(int) -> TTtypeIdentity; template auto TTryAddRValueReference(...) -> TTtypeIdentity; } template struct TAddLValueReference : decltype(THelpers::TTryAddLValueReference(0)) { }; template struct TAddRValueReference : decltype(THelpers::TTryAddRValueReference(0)) { }; //////////////////////////////////////////////////////////////////////////////////// // Checks if a type has a copy constructor. template struct TIsCopyConstructible { enum { Value = __is_constructible(T, typename TAddLValueReference::Type>::Type) }; }; //////////////////////////////////////////////////////////////////////////////////// // Checks if a type has a trivial copy constructor. template struct TIsTriviallyCopyConstructible { #if defined(__clang__) && __clang_major__ >= 15 enum { Value = TOrValue<__is_trivially_copyable(T), TIsPODType>::Value }; #else enum { Value = TOrValue<__has_trivial_copy(T), TIsPODType>::Value }; #endif }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsTriviallyConstructible { enum { Value = TIsPODType::Value }; }; //////////////////////////////////////////////////////////////////////////////////// // Check if a type has a trivial destructor. template struct TIsTriviallyDestructible { enum { Value = THelpers::TIsTriviallyDestructibleImpl::Value }; }; //////////////////////////////////////////////////////////////////////////////////// // Checks if a type has a trivial copy assignment operator. template struct TIsTriviallyCopyAssignable { #if defined(__clang__) && __clang_major__ >= 15 enum { Value = TOrValue<__is_trivially_assignable(T, const T), TIsPODType>::Value }; #else enum { Value = TOrValue<__has_trivial_assign(T), TIsPODType>::Value }; #endif }; //////////////////////////////////////////////////////////////////////////////////// template struct TIsFunction { enum { Value = false }; }; template struct TIsFunction { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// template struct TAreTypesEqual { enum { Value = false }; }; template struct TAreTypesEqual { enum { Value = true }; }; //////////////////////////////////////////////////////////////////////////////////// template inline typename TRemoveReference::Type&& MoveTemp(T&& obj) { return (typename TRemoveReference::Type&&)obj; } //////////////////////////////////////////////////////////////////////////////////// template inline void Swap(T& a, T& b) noexcept { T tmp = MoveTemp(a); a = MoveTemp(b); b = MoveTemp(tmp); } //////////////////////////////////////////////////////////////////////////////////// template inline T&& Forward(typename TRemoveReference::Type& t) noexcept { return static_cast(t); } template inline T&& Forward(typename TRemoveReference::Type&& t) noexcept { static_assert(!TIsLValueReference::Value, "Can not forward an rvalue as an lvalue."); return static_cast(t); } //////////////////////////////////////////////////////////////////////////////////// template struct TStaticIf; template struct TStaticIf { typedef TrueResult Value; }; template struct TStaticIf { typedef FalseResult Value; }; //////////////////////////////////////////////////////////////////////////////////// template struct TRemovePointer { typedef T Type; }; template struct TRemovePointer { typedef typename TRemovePointer::Type Type; }; //////////////////////////////////////////////////////////////////////////////////// // Includes a function in an overload set if the predicate is true. template struct TEnableIf; template struct TEnableIf { typedef Result Type; }; template struct TEnableIf { }; //////////////////////////////////////////////////////////////////////////////////// // Reverses the order of the bits of a value. template inline typename TEnableIf::Value, T>::Type ReverseBits(T bits) { bits = (bits << 16) | (bits >> 16); bits = ((bits & 0x00ff00ff) << 8) | ((bits & 0xff00ff00) >> 8); bits = ((bits & 0x0f0f0f0f) << 4) | ((bits & 0xf0f0f0f0) >> 4); bits = ((bits & 0x33333333) << 2) | ((bits & 0xcccccccc) >> 2); bits = ((bits & 0x55555555) << 1) | ((bits & 0xaaaaaaaa) >> 1); return bits; } //////////////////////////////////////////////////////////////////////////////////// // Checks if a type T is bitwise-constructible from a given argument type U. Can be used to perform a fast memory copy instead of slower constructor invocations. template struct TIsBitwiseConstructible { static_assert(!TIsReferenceType::Value && !TIsReferenceType::Value,"TIsBitwiseConstructible cannot use reference types"); static_assert(TAreTypesEqual::Type>::Value && TAreTypesEqual::Type>::Value, "TIsBitwiseConstructible cannot use qualified types"); enum { Value = false }; }; template struct TIsBitwiseConstructible { enum { Value = TIsTriviallyCopyConstructible::Value }; }; template struct TIsBitwiseConstructible : TIsBitwiseConstructible { }; template struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; template<> struct TIsBitwiseConstructible { enum { Value = true }; }; // @formatter:on //////////////////////////////////////////////////////////////////////////////////// // Utility to select double for float type or float otherwise template struct TOtherFloat { typedef float Type; }; template<> struct TOtherFloat { typedef double Type; }; #endif