#pragma once #include "IsEnum.h" #include "IsPointer.h" #include "IsArithmetic.h" #include "AndOrNot.h" #include "IsPODType.h" #include "IsTriviallyCopyConstructible.h" template struct TCallTraitsParamTypeHelper { typedef const T& ParamType; typedef const T& ConstParamType; }; template struct TCallTraitsParamTypeHelper { typedef const T ParamType; typedef const T ConstParamType; }; template struct TCallTraitsParamTypeHelper { typedef T* ParamType; typedef const T* ConstParamType; }; template struct TCallTraitsBase { private: enum { PassByValue = TOr>, TIsArithmetic, TIsPointer>::Value }; public: typedef T ValueType; typedef T& Reference; typedef const T& ConstReference; typedef typename TCallTraitsParamTypeHelper::ParamType ParamType; typedef typename TCallTraitsParamTypeHelper::ConstParamType ConstPointerType; }; /** * TCallTraits */ template struct TCallTraits : public TCallTraitsBase {}; // Fix reference-to-reference problems. template struct TCallTraits { typedef T& ValueType; typedef T& Reference; typedef const T& ConstReference; typedef T& ParamType; typedef T& ConstPointerType; }; // Array types template struct TCallTraits { private: typedef T ArrayType[N]; public: typedef const T* ValueType; typedef ArrayType& Reference; typedef const ArrayType& ConstReference; typedef const T* const ParamType; typedef const T* const ConstPointerType; }; // const array types template struct TCallTraits { private: typedef const T ArrayType[N]; public: typedef const T* ValueType; typedef ArrayType& Reference; typedef const ArrayType& ConstReference; typedef const T* const ParamType; typedef const T* const ConstPointerType; }; /*----------------------------------------------------------------------------- Traits for our particular container classes -----------------------------------------------------------------------------*/ /** * Helper for array traits. Provides a common base to more easily refine a portion of the traits * when specializing. Mainly used by MemoryOps.h which is used by the contiguous storage containers like TArray. */ template struct TTypeTraitsBase { typedef typename TCallTraits::ParamType ConstInitType; typedef typename TCallTraits::ConstPointerType ConstPointerType; // There's no good way of detecting this so we'll just assume it to be true for certain known types and expect // users to customize it for their custom types. enum { IsBytewiseComparable = TOr, TIsArithmetic, TIsPointer>::Value }; }; /** * Traits for types. */ template struct TTypeTraits : public TTypeTraitsBase {}; template struct TIsBitwiseConstructible { // Assume no bitwise construction in general enum { Value = false }; }; template struct TIsBitwiseConstructible { // Ts can always be bitwise constructed from itself if it is trivially copyable. enum { Value = TIsTriviallyCopyConstructible::Value }; }; template struct TIsBitwiseConstructible : TIsBitwiseConstructible { // Constructing a const T is the same as constructing a T }; // Const pointers can be bitwise constructed from non-const pointers. // This is not true for pointer conversions in general, e.g. where an offset may need to be applied in the case // of multiple inheritance, but there is no way of detecting that at compile-time. template struct TIsBitwiseConstructible { // Constructing a const T is the same as constructing a T enum { Value = true }; }; // Unsigned types can be bitwise converted to their signed equivalents, and vice versa. // (assuming two's-complement, which we are) template <> struct TIsBitwiseConstructible { enum { Value = true }; }; template <> struct TIsBitwiseConstructible< char, uint8> { enum { Value = true }; }; template <> struct TIsBitwiseConstructible { enum { Value = true }; }; template <> struct TIsBitwiseConstructible< short, uint16> { enum { Value = true }; }; template <> struct TIsBitwiseConstructible { enum { Value = true }; }; template <> struct TIsBitwiseConstructible< int32, uint32> { enum { Value = true }; }; template <> struct TIsBitwiseConstructible { enum { Value = true }; }; template <> struct TIsBitwiseConstructible< int64, uint64> { enum { Value = true }; };