#pragma once #include "CoreTypes.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template constexpr const T& AsConst(T& Ref) { return Ref; } template void AsConst(const T&& Ref) = delete; template constexpr const T(&AsConst(T(&Array)[N]))[N] { return Array; } template FORCEINLINE typename TRemoveReference::Type&& MoveTemp(T&& Obj) { typedef typename TRemoveReference::Type CastType; static_assert(TIsLValueReference::Value, "MoveTemp called on an rvalue."); static_assert(!TIsConst::Value, "MoveTemp called on a const object."); return (CastType&&)Obj; } template FORCEINLINE T CopyTemp(T& Val) { return const_cast(Val); } template FORCEINLINE T CopyTemp(const T& Val) { return Val; } template FORCEINLINE T&& CopyTemp(T&& Val) { return MoveTemp(Val); } template FORCEINLINE T&& Forward(typename TRemoveReference::Type& Obj) { return (T&&)Obj; } template FORCEINLINE T&& Forward(typename TRemoveReference::Type&& Obj) { return (T&&)Obj; } template requires TIsMoveConstructible::Value && TIsMoveAssignable::Value constexpr void Swap(T& A, T& B) { T Temp = MoveTemp(A); A = MoveTemp(B); B = MoveTemp(Temp); } template requires TIsMoveConstructible::Value && TIsAssignable::Value constexpr T Exchange(T& A, U&& B) { T Temp = MoveTemp(A); A = Forward(B); return Temp; } template T&& DeclVal(); template requires TIsObject::Value constexpr T* AddressOf(T& Object) { return reinterpret_cast(&const_cast(reinterpret_cast(Object))); } template requires !TIsObject::Value constexpr T* AddressOf(T& Object) { return &Object; } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END