#pragma once #include "CoreTypes.h" #include "Templates/Invoke.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template class TReferenceWrapper { public: using Type = T; template requires (!TIsSame::Type>::Value) constexpr TReferenceWrapper(U&& Object) : Ptr(AddressOf(Forward(Object))) { } TReferenceWrapper(const TReferenceWrapper&) = default; TReferenceWrapper& operator=(const TReferenceWrapper& x) = default; constexpr operator T&() const { return *Ptr; } constexpr T& Get() const { return *Ptr; } template constexpr TInvokeResult::Type operator()(Types&&... Args) const { return Invoke(Get(), Forward(Args)...); } private: T* Ptr; }; template TReferenceWrapper(T&) -> TReferenceWrapper; template void Ref(const T&&) = delete; template constexpr TReferenceWrapper Ref(T& InValue) { return TReferenceWrapper(InValue); } template constexpr TReferenceWrapper Ref(TReferenceWrapper InValue) { return Ref(InValue.Get()); } template constexpr TReferenceWrapper Ref(const T& InValue) { return TReferenceWrapper(InValue); } template constexpr TReferenceWrapper Ref(TReferenceWrapper InValue) { return Ref(InValue.Get()); } template struct TIsTReferenceWrapper : FFalse { }; template struct TIsTReferenceWrapper> : FTrue { }; template struct TUnwrapReference { using Type = T; }; template struct TUnwrapReference> { using Type = T&; }; template struct TUnwrapRefDecay { using Type = typename TUnwrapReference::Type>::Type; }; NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END