Nullable.Reset fix, killing inlining
This commit is contained in:
@@ -24,17 +24,6 @@ private:
|
|||||||
};
|
};
|
||||||
bool _hasValue;
|
bool _hasValue;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ends the lifetime of the wrapped value by calling its destructor, if the lifetime has not ended yet. Otherwise, does nothing.
|
|
||||||
/// </summary>
|
|
||||||
FORCE_INLINE void KillOld()
|
|
||||||
{
|
|
||||||
if (_hasValue)
|
|
||||||
{
|
|
||||||
_value.~T();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes <see cref="Nullable{T}"/> by setting the wrapped value to null.
|
/// Initializes <see cref="Nullable{T}"/> by setting the wrapped value to null.
|
||||||
@@ -48,7 +37,10 @@ public:
|
|||||||
|
|
||||||
~Nullable()
|
~Nullable()
|
||||||
{
|
{
|
||||||
KillOld();
|
if (_hasValue)
|
||||||
|
{
|
||||||
|
_value.~T();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -104,7 +96,10 @@ public:
|
|||||||
template<typename U = T, typename = typename TEnableIf<TIsCopyConstructible<U>::Value>::Type>
|
template<typename U = T, typename = typename TEnableIf<TIsCopyConstructible<U>::Value>::Type>
|
||||||
auto operator=(const T& value) -> Nullable&
|
auto operator=(const T& value) -> Nullable&
|
||||||
{
|
{
|
||||||
KillOld();
|
if (_hasValue)
|
||||||
|
{
|
||||||
|
_value.~T();
|
||||||
|
}
|
||||||
|
|
||||||
new (&_value) T(value); // Placement new (copy constructor)
|
new (&_value) T(value); // Placement new (copy constructor)
|
||||||
_hasValue = true;
|
_hasValue = true;
|
||||||
@@ -117,7 +112,10 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
auto operator=(T&& value) noexcept -> Nullable&
|
auto operator=(T&& value) noexcept -> Nullable&
|
||||||
{
|
{
|
||||||
KillOld();
|
if (_hasValue)
|
||||||
|
{
|
||||||
|
_value.~T();
|
||||||
|
}
|
||||||
|
|
||||||
new (&_value) T(MoveTemp(value)); // Placement new (move constructor)
|
new (&_value) T(MoveTemp(value)); // Placement new (move constructor)
|
||||||
_hasValue = true;
|
_hasValue = true;
|
||||||
@@ -131,12 +129,16 @@ public:
|
|||||||
template<typename U = T, typename = typename TEnableIf<TIsCopyConstructible<U>::Value>::Type>
|
template<typename U = T, typename = typename TEnableIf<TIsCopyConstructible<U>::Value>::Type>
|
||||||
auto operator=(const Nullable& other) -> Nullable&
|
auto operator=(const Nullable& other) -> Nullable&
|
||||||
{
|
{
|
||||||
KillOld();
|
if (_hasValue)
|
||||||
|
{
|
||||||
|
_value.~T();
|
||||||
|
}
|
||||||
|
|
||||||
if (other._hasValue)
|
if (other._hasValue)
|
||||||
{
|
{
|
||||||
new (&_value) T(other._value); // Placement new (copy constructor)
|
new (&_value) T(other._value); // Placement new (copy constructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasValue = other._hasValue; // Set the flag AFTER the value is copied.
|
_hasValue = other._hasValue; // Set the flag AFTER the value is copied.
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -152,14 +154,19 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
KillOld();
|
|
||||||
|
|
||||||
if (_hasValue)
|
if (_hasValue)
|
||||||
|
{
|
||||||
|
_value.~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other._hasValue)
|
||||||
{
|
{
|
||||||
new (&_value) T(MoveTemp(other._value)); // Placement new (move constructor)
|
new (&_value) T(MoveTemp(other._value)); // Placement new (move constructor)
|
||||||
|
|
||||||
other.Reset();
|
other._value.~T(); // Kill the old value in the source object.
|
||||||
|
other._hasValue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasValue = other._hasValue; // Set the flag AFTER the value is moved.
|
_hasValue = other._hasValue; // Set the flag AFTER the value is moved.
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -235,7 +242,10 @@ public:
|
|||||||
/// <param name="value">The value to be moved.</param>
|
/// <param name="value">The value to be moved.</param>
|
||||||
FORCE_INLINE void SetValue(T&& value) noexcept
|
FORCE_INLINE void SetValue(T&& value) noexcept
|
||||||
{
|
{
|
||||||
KillOld();
|
if (_hasValue)
|
||||||
|
{
|
||||||
|
_value.~T();
|
||||||
|
}
|
||||||
|
|
||||||
new (&_value) T(MoveTemp(value)); // Placement new (move constructor)
|
new (&_value) T(MoveTemp(value)); // Placement new (move constructor)
|
||||||
_hasValue = true; // Set the flag AFTER the value is moved.
|
_hasValue = true; // Set the flag AFTER the value is moved.
|
||||||
@@ -279,8 +289,13 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
FORCE_INLINE void Reset()
|
FORCE_INLINE void Reset()
|
||||||
{
|
{
|
||||||
|
if (!_hasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_hasValue = false; // Reset the flag BEFORE the value is (potentially) destructed.
|
_hasValue = false; // Reset the flag BEFORE the value is (potentially) destructed.
|
||||||
KillOld();
|
_value.~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user