diff --git a/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h b/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h index 619b564..07083e0 100644 --- a/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h +++ b/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h @@ -65,10 +65,6 @@ private: template requires (CObject || CFunction) friend class TReferenceWrapper; - // Optimize TOptional with these hacking - FORCEINLINE constexpr TReferenceWrapper(FInvalid) : Pointer(nullptr) { }; - template requires (CDestructible) friend class TOptional; - }; template @@ -122,128 +118,6 @@ using TUnwrapReference = typename NAMESPACE_PRIVATE::TUnwrapReferenceImpl::Ty template using TUnwrapRefDecay = typename NAMESPACE_PRIVATE::TUnwrapRefDecayImpl::Type; -NAMESPACE_PRIVATE_BEGIN - -template -concept CTOptionalRefAllowUnwrappable = - !(CConstructibleFrom& > - || CConstructibleFrom& > - || CConstructibleFrom&&> - || CConstructibleFrom&&> - || CConvertibleTo< TOptional&, U> - || CConvertibleTo&, U> - || CConvertibleTo< TOptional&&, U> - || CConvertibleTo&&, U> - || CAssignableFrom& > - || CAssignableFrom& > - || CAssignableFrom&&> - || CAssignableFrom&&>); - -NAMESPACE_PRIVATE_END - -template -class TOptional> -{ -private: - - using OptionalType = TReferenceWrapper; - -public: - - using ValueType = OptionalType; - - FORCEINLINE constexpr TOptional() : Reference(Invalid) { } - - FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { } - - template requires (CConstructibleFrom) - FORCEINLINE constexpr explicit TOptional(FInPlace, Ts&&... Args) - : Reference(Forward(Args)...) - { } - - template requires (CConstructibleFrom - && !CSameAs, FInPlace> && !CBaseOf>) - FORCEINLINE constexpr explicit (!CConvertibleTo) TOptional(T&& InValue) - : TOptional(InPlace, Forward(InValue)) - { } - - FORCEINLINE TOptional(const TOptional& InValue) = default; - FORCEINLINE TOptional(TOptional&& InValue) = default; - - template requires (CConstructibleFrom && NAMESPACE_PRIVATE::CTOptionalRefAllowUnwrappable) - FORCEINLINE constexpr explicit (!CConvertibleTo) TOptional(const TOptional& InValue) - : Reference(InValue.Reference) - { } - - FORCEINLINE ~TOptional() = default; - - FORCEINLINE TOptional& operator=(const TOptional& InValue) = default; - FORCEINLINE TOptional& operator=(TOptional&& InValue) = default; - - template requires (CConstructibleFrom - && CAssignableFrom && NAMESPACE_PRIVATE::CTOptionalRefAllowUnwrappable) - FORCEINLINE constexpr TOptional& operator=(const TOptional& InValue) - { - Reference = InValue.Reference; - return *this; - } - - template requires (CConstructibleFrom && CAssignableFrom) - FORCEINLINE constexpr TOptional& operator=(T&& InValue) - { - Reference = InValue; - return *this; - } - - template requires (CConstructibleFrom) - FORCEINLINE constexpr OptionalType& Emplace(ArgTypes&&... Args) - { - Reference = TReferenceWrapper(Forward(Args)...); - return Reference; - } - - FORCEINLINE constexpr bool IsValid() const { return Reference.Pointer != nullptr; } - FORCEINLINE constexpr explicit operator bool() const { return Reference.Pointer != nullptr; } - - FORCEINLINE constexpr OptionalType& GetValue() & { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } - FORCEINLINE constexpr OptionalType&& GetValue() && { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } - FORCEINLINE constexpr const OptionalType& GetValue() const& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } - FORCEINLINE constexpr const OptionalType&& GetValue() const&& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } - - FORCEINLINE constexpr const OptionalType* operator->() const { return &GetValue(); } - FORCEINLINE constexpr OptionalType* operator->() { return &GetValue(); } - - FORCEINLINE constexpr OptionalType& operator*() & { return GetValue(); } - FORCEINLINE constexpr OptionalType&& operator*() && { return GetValue(); } - FORCEINLINE constexpr const OptionalType& operator*() const& { return GetValue(); } - FORCEINLINE constexpr const OptionalType&& operator*() const&& { return GetValue(); } - - FORCEINLINE constexpr OptionalType& Get( OptionalType& DefaultValue) & { return IsValid() ? GetValue() : DefaultValue; } - FORCEINLINE constexpr const OptionalType& Get(const OptionalType& DefaultValue) const& { return IsValid() ? GetValue() : DefaultValue; } - - FORCEINLINE constexpr void Reset() - { - Reference = Invalid; - } - - FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable) - { - if (!IsValid()) return 2824517378; - return Reference.GetTypeHash(); - } - - FORCEINLINE constexpr void Swap(TOptional& InValue) - { - Reference.Swap(InValue.Reference); - } - -private: - - TReferenceWrapper Reference; - template requires (CDestructible) friend class TOptional; - -}; - NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END