Fix type constraints
This commit is contained in:
@@ -7,13 +7,19 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wrapper for a value type that can be assigned null, controlling the lifetime of the wrapped value.
|
/// Wrapper for a value type that can be assigned null, controlling the lifetime of the wrapped value.
|
||||||
/// </summary>
|
/// </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>
|
template<typename T>
|
||||||
struct Nullable
|
struct Nullable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
struct Dummy { Dummy() {} };
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
T _value;
|
T _value;
|
||||||
|
Dummy _dummy;
|
||||||
};
|
};
|
||||||
bool _hasValue;
|
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:
|
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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Nullable()
|
Nullable()
|
||||||
: _hasValue(false)
|
: _dummy()
|
||||||
|
, _hasValue(false)
|
||||||
{
|
{
|
||||||
// Value is not initialized.
|
// Value is not initialized.
|
||||||
}
|
}
|
||||||
@@ -47,6 +59,7 @@ public:
|
|||||||
/// Initializes <see cref="Nullable{T}"/> by copying the wrapped value.
|
/// Initializes <see cref="Nullable{T}"/> by copying the wrapped value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <NullableBase name="value">The initial wrapped value to be copied.</param>
|
/// <NullableBase name="value">The initial wrapped value to be copied.</param>
|
||||||
|
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
|
||||||
Nullable(const T& value)
|
Nullable(const T& value)
|
||||||
: _value(value)
|
: _value(value)
|
||||||
, _hasValue(true)
|
, _hasValue(true)
|
||||||
@@ -67,6 +80,7 @@ public:
|
|||||||
/// Initializes <see cref="Nullable{T}"/> by copying another <see cref="Nullable{T}"/>.
|
/// Initializes <see cref="Nullable{T}"/> by copying another <see cref="Nullable{T}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The wrapped value to be copied.</param>
|
/// <param name="other">The wrapped value to be copied.</param>
|
||||||
|
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
|
||||||
Nullable(const Nullable& other)
|
Nullable(const Nullable& other)
|
||||||
: _value(other._value)
|
: _value(other._value)
|
||||||
, _hasValue(other._hasValue)
|
, _hasValue(other._hasValue)
|
||||||
@@ -91,6 +105,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reassigns the wrapped value by copying.
|
/// Reassigns the wrapped value by copying.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
|
||||||
auto operator=(const T& value) -> Nullable&
|
auto operator=(const T& value) -> Nullable&
|
||||||
{
|
{
|
||||||
KillOld();
|
KillOld();
|
||||||
@@ -117,6 +132,7 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reassigns the wrapped value by copying another <see cref="Nullable{T}"/>.
|
/// Reassigns the wrapped value by copying another <see cref="Nullable{T}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
template<typename U = T, typename = typename TEnableIf<IsCopyConstructible>::Type>
|
||||||
auto operator=(const Nullable& other) -> Nullable&
|
auto operator=(const Nullable& other) -> Nullable&
|
||||||
{
|
{
|
||||||
KillOld();
|
KillOld();
|
||||||
@@ -205,6 +221,7 @@ public:
|
|||||||
/// Sets the wrapped value by copying.
|
/// Sets the wrapped value by copying.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value to be copied.</param>
|
/// <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)
|
FORCE_INLINE void SetValue(const T& value)
|
||||||
{
|
{
|
||||||
if (_hasValue)
|
if (_hasValue)
|
||||||
@@ -232,6 +249,7 @@ public:
|
|||||||
/// If the wrapped value is not valid, sets it by copying. Otherwise, does nothing.
|
/// If the wrapped value is not valid, sets it by copying. Otherwise, does nothing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if the wrapped value was changed, otherwise false.</returns>
|
/// <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)
|
FORCE_INLINE bool TrySet(const T& value)
|
||||||
{
|
{
|
||||||
if (_hasValue)
|
if (_hasValue)
|
||||||
|
|||||||
Reference in New Issue
Block a user