Regression fix: Support zero arguments emplace() in etl::optional (#1183)

* Added coderabbitai configuration

* Added builtin mem function tests

* Modified etl::typed_storage

* Modified etl::typed_storage

# Conflicts:
#	include/etl/alignment.h

* Added ETL_NOEXCEPT and ETL_NOEXCEPT_IF_NO_THROW

* Added etl::typed_storage_ext and swap for same

* Added etl::typed_storage_ext and swap for same

# Conflicts:
#	include/etl/alignment.h

* Added release notes

* Fixes to GCC -O2 errors

* Changed char* parameters to value_type* parameters

* Fixed compilation issues for const containers unit tests

* Added automatic selection of __builtin_memxxx functions for GCC and clang

* Added enhanced coderabbit configuration

* Updated version and release notes

* Disabled constexpr const container tests for C++11

* Attempted fixes for MacOS compilation

* Attempted fixes for MacOS compilation

* Attempted fixes for MacOS compilation

* Attempted fixes for MacOS compilation

* Updated version and release notes

* feat: removed unreachable break statements (#1169)

* Updated version and release notes

* Modified etl::typed_storage

# Conflicts:
#	include/etl/alignment.h

* Support zero arguments emplace() in etl::optional

For non-fundamental types, a recent change in etl::optional was
introduced that doesn't support zero arguments emplace() anymore.

This change fixes it and adds the respective test.

---------

Co-authored-by: John Wellbelove <john.wellbelove@asterconsulting.co.uk>
Co-authored-by: Drew Rife <darife@jlg.com>
This commit is contained in:
Roland Reichwein 2025-09-10 11:37:30 +02:00 committed by GitHub
parent 7301617708
commit 75606fc079
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 81 additions and 18 deletions

View File

@ -450,9 +450,17 @@ namespace etl
template <typename... TArgs>
reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS)
{
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
valid = true;
return *::new (&storage.value) value_type(etl::forward<TArgs>(args)...);
if (has_value())
{
storage.value = T(args...);
}
else
{
valid = true;
::new (&storage.value) value_type(etl::forward<TArgs>(args)...);
}
return storage.value;
}
#else
//***************************************************************************
@ -462,9 +470,17 @@ namespace etl
template <typename T1>
reference create(const T1& t1)
{
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
valid = true;
return *::new (&storage.value) value_type(t1);
if (has_value())
{
storage.value = T(t1);
}
else
{
valid = true;
::new (&storage.value) value_type(t1);
}
return storage.value;
}
//***************************************************************************
@ -474,9 +490,17 @@ namespace etl
template <typename T1, typename T2>
reference create(const T1& t1, const T2& t2)
{
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
valid = true;
return *::new (&storage.value) value_type(t1, t2);
if (has_value())
{
storage.value = T(t1, t2);
}
else
{
valid = true;
::new (&storage.value) value_type(t1, t2);
}
return storage.value;
}
//***************************************************************************
@ -486,9 +510,17 @@ namespace etl
template <typename T1, typename T2, typename T3>
reference create(const T1& t1, const T2& t2, const T3& t3)
{
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
valid = true;
return *::new (&storage.value) value_type(t1, t2, t3);
if (has_value())
{
storage.value = T(t1, t2, t3);
}
else
{
valid = true;
::new (&storage.value) value_type(t1, t2, t3);
}
return storage.value;
}
//***************************************************************************
@ -498,9 +530,17 @@ namespace etl
template <typename T1, typename T2, typename T3, typename T4>
reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
{
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
valid = true;
return *::new (&storage.value) value_type(t1, t2, t3, t4);
if (has_value())
{
storage.value = T(t1, t2, t3, t4);
}
else
{
valid = true;
::new (&storage.value) value_type(t1, t2, t3, t4);
}
return storage.value;
}
#endif
@ -559,7 +599,7 @@ namespace etl
struct dummy_t {};
//*******************************
//*******************************
union union_type
{
union_type() ETL_NOEXCEPT

View File

@ -536,6 +536,17 @@ namespace etl
return storage.u.value;
}
//*************************************************************************
/// Emplaces with zero arguments, i.e. default construct emplace.
//*************************************************************************
ETL_CONSTEXPR20_STL
T& emplace()
{
storage.construct();
return storage.u.value;
}
#else
//*************************************************************************
/// Emplaces a value.

View File

@ -218,15 +218,27 @@ namespace
}
//*************************************************************************
TEST(test_emplace_zero_parameters)
TEST(test_emplace_zero_parameters_fundamental)
{
etl::optional<std::uint8_t> result = 1;
result.emplace();
CHECK_EQUAL(0, static_cast<int>(result.emplace()));
CHECK_TRUE(result.has_value());
CHECK_EQUAL(0, int(result.value()));
}
//*************************************************************************
TEST(test_emplace_zero_parameters_non_fundamental)
{
etl::optional<std::string> result = std::string("abc");
std::string& ref = result.emplace();
CHECK_EQUAL(std::string(), ref);
CHECK_EQUAL(&ref, &result.value());
CHECK_TRUE(result.has_value());
CHECK_EQUAL("", std::string(result.value()));
}
//*************************************************************************
TEST(test_emplace_return)
{