diff --git a/Source/Engine/Core/Types/Nullable.h b/Source/Engine/Core/Types/Nullable.h index 0cf4b4361..9d8f3f65b 100644 --- a/Source/Engine/Core/Types/Nullable.h +++ b/Source/Engine/Core/Types/Nullable.h @@ -7,13 +7,19 @@ /// /// Wrapper for a value type that can be assigned null, controlling the lifetime of the wrapped value. /// +/// +/// The type of the wrapped value. It must be move-constructible but does not have to be copy-constructible. Value is never reassigned. +/// template struct Nullable { private: + struct Dummy { Dummy() {} }; + union { - T _value; + T _value; + Dummy _dummy; }; bool _hasValue; @@ -28,12 +34,18 @@ private: } } + /// + /// true if the wrapped type is copy constructible. + /// + constexpr static bool IsCopyConstructible = TIsCopyConstructible::Value; + public: /// /// Initializes by setting the wrapped value to null. /// Nullable() - : _hasValue(false) + : _dummy() + , _hasValue(false) { // Value is not initialized. } @@ -47,6 +59,7 @@ public: /// Initializes by copying the wrapped value. /// /// The initial wrapped value to be copied. + template::Type> Nullable(const T& value) : _value(value) , _hasValue(true) @@ -67,6 +80,7 @@ public: /// Initializes by copying another . /// /// The wrapped value to be copied. + template::Type> Nullable(const Nullable& other) : _value(other._value) , _hasValue(other._hasValue) @@ -91,6 +105,7 @@ public: /// /// Reassigns the wrapped value by copying. /// + template::Type> auto operator=(const T& value) -> Nullable& { KillOld(); @@ -117,6 +132,7 @@ public: /// /// Reassigns the wrapped value by copying another . /// + template::Type> auto operator=(const Nullable& other) -> Nullable& { KillOld(); @@ -205,6 +221,7 @@ public: /// Sets the wrapped value by copying. /// /// The value to be copied. + template::Type> FORCE_INLINE void SetValue(const T& value) { if (_hasValue) @@ -232,6 +249,7 @@ public: /// If the wrapped value is not valid, sets it by copying. Otherwise, does nothing. /// /// True if the wrapped value was changed, otherwise false. + template::Type> FORCE_INLINE bool TrySet(const T& value) { if (_hasValue)