mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 10:52:22 +01:00
160 lines
4.9 KiB
C++
160 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include "IsEnum.h"
|
|
#include "IsPointer.h"
|
|
#include "IsArithmetic.h"
|
|
#include "AndOrNot.h"
|
|
#include "IsPODType.h"
|
|
#include "IsTriviallyCopyConstructible.h"
|
|
|
|
template <typename T, bool TypeIsSmall>
|
|
struct TCallTraitsParamTypeHelper
|
|
{
|
|
typedef const T& ParamType;
|
|
typedef const T& ConstParamType;
|
|
};
|
|
template <typename T>
|
|
struct TCallTraitsParamTypeHelper<T, true>
|
|
{
|
|
typedef const T ParamType;
|
|
typedef const T ConstParamType;
|
|
};
|
|
template <typename T>
|
|
struct TCallTraitsParamTypeHelper<T*, true>
|
|
{
|
|
typedef T* ParamType;
|
|
typedef const T* ConstParamType;
|
|
};
|
|
|
|
template<typename T> struct TContainerTraitsBase
|
|
{
|
|
// This should be overridden by every container that supports emptying its contents via a move operation.
|
|
enum { MoveWillEmptyContainer = false };
|
|
};
|
|
|
|
template<typename T> struct TContainerTraits : public TContainerTraitsBase<T> {};
|
|
|
|
template <typename T>
|
|
struct TCallTraitsBase
|
|
{
|
|
private:
|
|
enum { PassByValue = TOr<TAndValue<(sizeof(T) <= sizeof(void*)), TIsPODType<T>>, TIsArithmetic<T>, TIsPointer<T>>::Value };
|
|
public:
|
|
typedef T ValueType;
|
|
typedef T& Reference;
|
|
typedef const T& ConstReference;
|
|
typedef typename TCallTraitsParamTypeHelper<T, PassByValue>::ParamType ParamType;
|
|
typedef typename TCallTraitsParamTypeHelper<T, PassByValue>::ConstParamType ConstPointerType;
|
|
};
|
|
|
|
/**
|
|
* TCallTraits
|
|
*/
|
|
template <typename T>
|
|
struct TCallTraits : public TCallTraitsBase<T> {};
|
|
|
|
// Fix reference-to-reference problems.
|
|
template <typename T>
|
|
struct TCallTraits<T&>
|
|
{
|
|
typedef T& ValueType;
|
|
typedef T& Reference;
|
|
typedef const T& ConstReference;
|
|
typedef T& ParamType;
|
|
typedef T& ConstPointerType;
|
|
};
|
|
|
|
// Array types
|
|
template <typename T, size_t N>
|
|
struct TCallTraits<T[N]>
|
|
{
|
|
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 <typename T, size_t N>
|
|
struct TCallTraits<const T[N]>
|
|
{
|
|
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<typename T>
|
|
struct TTypeTraitsBase
|
|
{
|
|
typedef typename TCallTraits<T>::ParamType ConstInitType;
|
|
typedef typename TCallTraits<T>::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<TIsEnum<T>, TIsArithmetic<T>, TIsPointer<T>>::Value };
|
|
};
|
|
|
|
/**
|
|
* Traits for types.
|
|
*/
|
|
template<typename T> struct TTypeTraits : public TTypeTraitsBase<T> {};
|
|
|
|
template <typename T, typename Arg>
|
|
struct TIsBitwiseConstructible
|
|
{
|
|
// Assume no bitwise construction in general
|
|
enum { Value = false };
|
|
};
|
|
|
|
template <typename T>
|
|
struct TIsBitwiseConstructible<T, T>
|
|
{
|
|
// Ts can always be bitwise constructed from itself if it is trivially copyable.
|
|
enum { Value = TIsTriviallyCopyConstructible<T>::Value };
|
|
};
|
|
|
|
template <typename T, typename U>
|
|
struct TIsBitwiseConstructible<const T, U> : TIsBitwiseConstructible<T, U>
|
|
{
|
|
// 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 <typename T>
|
|
struct TIsBitwiseConstructible<const T*, T*>
|
|
{
|
|
// 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<uint8, char> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible< char, uint8> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible<uint16, short> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible< short, uint16> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible<uint32, int32> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible< int32, uint32> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible<uint64, int64> { enum { Value = true }; };
|
|
template <> struct TIsBitwiseConstructible< int64, uint64> { enum { Value = true }; };
|