diff --git a/Redcraft.Utility/Source/Public/Templates/Function.h b/Redcraft.Utility/Source/Public/Templates/Function.h index 6a9e594..049d629 100644 --- a/Redcraft.Utility/Source/Public/Templates/Function.h +++ b/Redcraft.Utility/Source/Public/Templates/Function.h @@ -272,17 +272,17 @@ public: static constexpr const FRTTI SelectedRTTI(InPlaceType); RTTI = reinterpret_cast(&SelectedRTTI); - if constexpr (CEmpty) return; + if constexpr (CEmpty && CTrivial) return; // ERepresentation::Empty - constexpr bool bIsInlineStorable = sizeof(DecayedType) <= sizeof(InternalStorage) && alignof(DecayedType) <= alignof(TFunctionStorage); - constexpr bool bIsTriviallyStorable = bIsInlineStorable && CTrivial && CTriviallyCopyable; + constexpr bool bIsTriviallyStorable = sizeof(DecayedType) <= sizeof(InternalStorage) && alignof(DecayedType) <= alignof(TFunctionStorage) && CTriviallyCopyable; + constexpr bool bIsSmallStorable = sizeof(DecayedType) <= sizeof(InternalStorage) && alignof(DecayedType) <= alignof(TFunctionStorage); if constexpr (bIsTriviallyStorable) { new (&InternalStorage) DecayedType(Forward(Args)...); RTTI |= static_cast(ERepresentation::Trivial); } - else if constexpr (bIsInlineStorable) + else if constexpr (bIsSmallStorable) { new (&InternalStorage) DecayedType(Forward(Args)...); RTTI |= static_cast(ERepresentation::Small); @@ -393,10 +393,30 @@ private: FORCEINLINE constexpr ERepresentation GetRepresentation() const { return static_cast(RTTI & RepresentationMask); } FORCEINLINE constexpr const FRTTI& GetRTTI() const { return *reinterpret_cast(RTTI & ~RepresentationMask); } - - FORCEINLINE constexpr void* GetStorage() { return GetRepresentation() == ERepresentation::Trivial || GetRepresentation() == ERepresentation::Small ? InternalStorage : ExternalStorage; } - FORCEINLINE constexpr const void* GetStorage() const { return GetRepresentation() == ERepresentation::Trivial || GetRepresentation() == ERepresentation::Small ? InternalStorage : ExternalStorage; } + FORCEINLINE constexpr void* GetStorage() + { + switch (GetRepresentation()) + { + case ERepresentation::Empty: return nullptr; + case ERepresentation::Trivial: return &InternalStorage; + case ERepresentation::Small: return &InternalStorage; + case ERepresentation::Big: return ExternalStorage; + default: check_no_entry(); return nullptr; + } + } + + FORCEINLINE constexpr const void* GetStorage() const + { + switch (GetRepresentation()) + { + case ERepresentation::Empty: return nullptr; + case ERepresentation::Trivial: return &InternalStorage; + case ERepresentation::Small: return &InternalStorage; + case ERepresentation::Big: return ExternalStorage; + default: check_no_entry(); return nullptr; + } + } }; template