Fix type constraints

This commit is contained in:
Mateusz Karbowiak
2024-10-06 02:23:21 +02:00
parent c9b1f6f516
commit 23624aa7f8

View File

@@ -7,13 +7,19 @@
/// <summary>
/// Wrapper for a value type that can be assigned null, controlling the lifetime of the wrapped value.
/// </summary>
/// <typeparam name="T">
/// The type of the wrapped value. It must be move-constructible but does not have to be copy-constructible. Value is never reassigned.
/// </typeparam>
template<typename T>
struct Nullable
{
private:
struct Dummy { Dummy() {} };
union
{
T _value;
T _value;
Dummy _dummy;
};
bool _hasValue;
@@ -28,12 +34,18 @@ private:
}
}
/// <summary>
/// <c>true</c> if the wrapped type is copy constructible.
/// </summary>
constexpr static bool IsCopyConstructible = TIsCopyConstructible<T>::Value;
public:
/// <summary>
/// Initializes <see cref="Nullable{T}"/> by setting the wrapped value to null.
/// </summary>
Nullable()
: _hasValue(false)
: _dummy()
, _hasValue(false)
{
// Value is not initialized.
}
@@ -47,6 +59,7 @@ public:
/// Initializes <see cref="Nullable{T}"/> by copying the wrapped value.
/// </summary>
/// <NullableBase name="value">The initial wrapped value to be copied.</param>
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
Nullable(const T& value)
: _value(value)
, _hasValue(true)
@@ -67,6 +80,7 @@ public:
/// Initializes <see cref="Nullable{T}"/> by copying another <see cref="Nullable{T}"/>.
/// </summary>
/// <param name="other">The wrapped value to be copied.</param>
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
Nullable(const Nullable& other)
: _value(other._value)
, _hasValue(other._hasValue)
@@ -91,6 +105,7 @@ public:
/// <summary>
/// Reassigns the wrapped value by copying.
/// </summary>
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
auto operator=(const T& value) -> Nullable&
{
KillOld();
@@ -117,6 +132,7 @@ public:
/// <summary>
/// Reassigns the wrapped value by copying another <see cref="Nullable{T}"/>.
/// </summary>
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
auto operator=(const Nullable& other) -> Nullable&
{
KillOld();
@@ -205,6 +221,7 @@ public:
/// Sets the wrapped value by copying.
/// </summary>
/// <param name="value">The value to be copied.</param>
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::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.
/// </summary>
/// <returns>True if the wrapped value was changed, otherwise false.</returns>
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
FORCE_INLINE bool TrySet(const T& value)
{
if (_hasValue)