Modified the POD specialisation to accept objects that have deleted default constructors

This commit is contained in:
John Wellbelove 2023-06-14 09:14:44 +01:00
parent 8dad4e8efc
commit a0af0f9415
2 changed files with 47 additions and 20 deletions

View File

@ -700,8 +700,8 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 optional(const T& value_)
: valid(true)
, storage(value_)
{
storage.u.value = value_;
}
#if ETL_USING_CPP11
@ -710,8 +710,8 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 optional(T&& value_)
: valid(true)
, storage(etl::move(value_))
{
storage.u.value = etl::move(value_);
}
#endif
@ -731,7 +731,7 @@ namespace etl
{
if (this != &other)
{
storage = other.storage;
storage.u = other.storage.u;
valid = other.valid;
}
@ -746,7 +746,7 @@ namespace etl
{
if (this != &other)
{
storage = etl::move(other.storage);
storage.u = etl::move(other.storage.u);
valid = other.valid;
}
@ -759,7 +759,7 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(const T& value_)
{
storage = value_;
storage.u.value = value_;
valid = true;
return *this;
@ -771,7 +771,7 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 optional& operator =(T&& value_)
{
storage = etl::move(value_);
storage.u.value = etl::move(value_);
valid = true;
return *this;
@ -878,7 +878,7 @@ namespace etl
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return storage;
return storage.u.value;
}
//***************************************************************************
@ -890,7 +890,7 @@ namespace etl
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return storage;
return storage.u.value;
}
//***************************************************************************
@ -911,7 +911,7 @@ namespace etl
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return etl::move(storage);
return etl::move(storage.u.value);
}
//***************************************************************************
@ -923,7 +923,7 @@ namespace etl
ETL_ASSERT(valid, ETL_ERROR(optional_invalid));
#endif
return etl::move(storage);
return etl::move(storage.u.value);
}
//***************************************************************************
@ -961,7 +961,7 @@ namespace etl
template <typename ... Args>
ETL_CONSTEXPR14 void emplace(Args && ... args)
{
storage = T(ETL_OR_STD::forward<Args>(args)...);
storage.u.value = T(ETL_OR_STD::forward<Args>(args)...);
valid = true;
}
#else
@ -972,7 +972,7 @@ namespace etl
template <typename T1>
void emplace(const T1& value1)
{
storage = value1;
storage.u.value = value1;
valid = true;
}
@ -983,7 +983,7 @@ namespace etl
template <typename T1, typename T2>
void emplace(const T1& value1, const T2& value2)
{
storage = T(value1, value2);
storage.u.value = T(value1, value2);
valid = true;
}
@ -994,7 +994,7 @@ namespace etl
template <typename T1, typename T2, typename T3>
void emplace(const T1& value1, const T2& value2, const T3& value3)
{
storage = T(value1, value2, value3);
storage.u.value = T(value1, value2, value3);
valid = true;
}
@ -1005,7 +1005,7 @@ namespace etl
template <typename T1, typename T2, typename T3, typename T4>
void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
storage = T(value1, value2, value3, value4);
storage.u.value = T(value1, value2, value3, value4);
valid = true;
}
#endif
@ -1013,7 +1013,28 @@ namespace etl
private:
bool valid;
T storage;
struct storage_type
{
storage_type()
{
}
union union_type
{
union_type()
: dummy(0)
{
}
char dummy;
T value;
};
union_type u;
};
storage_type storage;
};
#include "etl/private/diagnostic_uninitialized_push.h"

View File

@ -495,12 +495,18 @@ namespace
}
//*************************************************************************
TEST(test_optional_pod_assign_bug_714)
struct MyPODObject
{
etl::optional<int> o = 42;
o = etl::nullopt;
MyPODObject() = delete;
int value;
};
CHECK_EQUAL(false, o.has_value());
TEST(test_optional_pod_emplace_bug_712)
{
etl::optional<MyPODObject> optionalObject; // The Test: Does this compile for an object with a deleted default constructor?
// Make sure it isn't optimised away.
CHECK_FALSE(optionalObject.has_value());
}
};
}