#pragma once #include "CoreTypes.h" #include "TypeTraits/CompositeType.h" #include "TypeTraits/Miscellaneous.h" #include "TypeTraits/SupportedOperations.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template FORCEINLINE constexpr const T& AsConst(T& Ref) { return Ref; } template void AsConst(const T&& Ref) = delete; template FORCEINLINE constexpr TRemoveReference&& MoveTemp(T&& Obj) { using CastType = TRemoveReference; return static_cast(Obj); } template FORCEINLINE constexpr T CopyTemp(T& Obj) { return const_cast(Obj); } template FORCEINLINE constexpr T CopyTemp(const T& Obj) { return Obj; } template FORCEINLINE constexpr T&& CopyTemp(T&& Obj) { return MoveTemp(Obj); } template FORCEINLINE constexpr T&& Forward(TRemoveReference& Obj) { return static_cast(Obj); } template FORCEINLINE constexpr T&& Forward(TRemoveReference&& Obj) { return static_cast(Obj); } template requires (requires(T& A, T& B) { A.Swap(B); } || (CMoveConstructible && CMoveAssignable)) FORCEINLINE constexpr void Swap(T& A, T& B) { if constexpr (requires(T& A, T& B) { A.Swap(B); }) { A.Swap(B); } else { T Temp = MoveTemp(A); A = MoveTemp(B); B = MoveTemp(Temp); } } template requires (CMoveConstructible && CAssignableFrom) FORCEINLINE constexpr T Exchange(T& A, U&& B) { T Temp = MoveTemp(A); A = Forward(B); return Temp; } template TAddRValueReference DeclVal(); template requires (CObject) FORCEINLINE constexpr T* AddressOf(T& Object) { return reinterpret_cast(&const_cast(reinterpret_cast(Object))); } template requires (!CObject) FORCEINLINE constexpr T* AddressOf(T& Object) { return &Object; } struct FIgnore { template FORCEINLINE constexpr void operator=(T&&) const { } }; inline constexpr FIgnore Ignore; // This macro is used in place of using type aliases, see Atomic.h, etc #define STRONG_INHERIT(...) /* BaseClass */ \ /* struct DerivedClass : */ public __VA_ARGS__ \ { \ private: \ \ using BaseClassTypedef = __VA_ARGS__; \ \ public: \ \ using BaseClassTypedef::BaseClassTypedef; \ using BaseClassTypedef::operator=; \ \ } // TOverloaded Usage Example // // Visit(TOverloaded { // [](auto A) { ... }, // [](double A) { ... }, // [](const FString& A) { ... }, // }, Target); // template struct TOverloaded : Ts... { using Ts::operator()...; }; template TOverloaded(Ts...) -> TOverloaded; NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END