Added etl::typed_storage_ext and swap for same

# Conflicts:
#	include/etl/alignment.h
This commit is contained in:
John Wellbelove 2025-08-28 10:30:24 +01:00
parent 33302790ba
commit ece4b711f5
3 changed files with 62 additions and 23 deletions

View File

@ -386,6 +386,7 @@ namespace etl
//***************************************************************************
/// Constructs the instance of T with type T1
//***************************************************************************
template <typename T1>
typed_storage(const T1& t1)
: valid(false)
{
@ -395,6 +396,7 @@ namespace etl
//***************************************************************************
/// Constructs the instance of T with types T1, T2
//***************************************************************************
template <typename T1, typename T2>
typed_storage(const T1& t1, const T2& t2)
: valid(false)
{
@ -404,6 +406,7 @@ namespace etl
//***************************************************************************
/// Constructs the instance of T with types T1, T2, T3
//***************************************************************************
template <typename T1, typename T2, typename T3>
typed_storage(const T1& t1, const T2& t2, const T3& t3)
: valid(false)
{
@ -413,6 +416,7 @@ namespace etl
//***************************************************************************
/// Constructs the instance of T with types T1, T2, T3, T4
//***************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
typed_storage(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
: valid(false)
{
@ -607,15 +611,15 @@ namespace etl
{
}
dummy_t dummy;
T value;
dummy_t dummy;
value_type value;
} storage;
bool valid;
};
//***************************************************************************
/// Wrapper class that provides a memory area and lets the user create an
/// Wrapper class wraps a supplied memory area and lets the user create an
/// instance of T in this memory at runtime. This class also erases the
/// destructor call of T, i.e. if typed_storage goes out of scope, the
/// destructor if the wrapped type will not be called. This can be done
@ -639,7 +643,6 @@ namespace etl
//***************************************************************************
/// Constructor.
//***************************************************************************
template <typename... TArgs>
typed_storage_ext(void* pbuffer_) ETL_NOEXCEPT_IF_NO_THROW
: pbuffer(reinterpret_cast<T*>(pbuffer_)),
valid(false)
@ -659,10 +662,23 @@ namespace etl
ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of<T>::value), ETL_ERROR(etl::alignment_error));
create(etl::forward<TArgs>(args)...);
}
//***************************************************************************
/// Move constructor.
/// Transfers ownership of the buffer from \p other to this.
//***************************************************************************
typed_storage_ext(typed_storage_ext<T>&& other) ETL_NOEXCEPT_IF_NO_THROW
: pbuffer(other.pbuffer)
, valid(other.valid)
{
other.pbuffer = ETL_NULLPTR;
other.valid = false;
}
#else
//***************************************************************************
/// Constructs the instance of T with type T1
//***************************************************************************
template <typename T1>
typed_storage_ext(void* pbuffer_, const T1& t1)
: pbuffer(reinterpret_cast<T*>(pbuffer_))
, valid(false)
@ -670,20 +686,10 @@ namespace etl
ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of<T>::value), ETL_ERROR(etl::alignment_error));
}
//***************************************************************************
/// Constructs the instance of T with type T1
//***************************************************************************
typed_storage_ext(void* pbuffer_, const T1& t1)
: pbuffer(reinterpret_cast<T*>(pbuffer_))
, valid(false)
{
ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of<T>::value), ETL_ERROR(etl::alignment_error));
create(t1);
}
//***************************************************************************
/// Constructs the instance of T with types T1, T2
//***************************************************************************
template <typename T1, typename T2>
typed_storage_ext(void* pbuffer_, const T1& t1, const T2& t2)
: pbuffer(reinterpret_cast<T*>(pbuffer_))
, valid(false)
@ -695,6 +701,7 @@ namespace etl
//***************************************************************************
/// Constructs the instance of T with types T1, T2, T3
//***************************************************************************
template <typename T1, typename T2, typename T3>
typed_storage_ext(void* pbuffer_, const T1& t1, const T2& t2, const T3& t3)
: pbuffer(reinterpret_cast<T*>(pbuffer_))
, valid(false)
@ -706,6 +713,7 @@ namespace etl
//***************************************************************************
/// Constructs the instance of T with types T1, T2, T3, T4
//***************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
typed_storage_ext(void* pbuffer_, const T1& t1, const T2& t2, const T3& t3, const T4& t4)
: pbuffer(reinterpret_cast<T*>(pbuffer_))
, valid(false)
@ -848,7 +856,7 @@ namespace etl
typed_storage_ext(etl::typed_storage_ext<T>&) ETL_DELETE;
typed_storage_ext& operator =(etl::typed_storage_ext<T>&) ETL_DELETE;
T* pbuffer;
pointer pbuffer;
bool valid;
};

View File

@ -56,6 +56,12 @@ struct A_t
{
}
~A_t()
{
x = 0;
y = 0;
}
bool operator==(A_t& other)
{
return other.x == x && other.y == y;
@ -196,12 +202,14 @@ namespace
etl::typed_storage<A_t> a;
CHECK_FALSE(a.has_value());
etl::typed_storage<A_t> b(789, 10); // Construct in place.
// Construct in place.
etl::typed_storage<A_t> b(789, 10);
CHECK_TRUE(b.has_value());
CHECK_EQUAL(b->x, 789);
CHECK_EQUAL(b->y, 10);
auto& ref = a.create(123, 4); // Create in place.
// Create in place.
auto& ref = a.create(123, 4);
CHECK_TRUE(a.has_value());
CHECK_EQUAL(a->x, 123);
@ -212,6 +220,7 @@ namespace
CHECK_TRUE(*a == ref);
// Destroy
CHECK_TRUE(a.has_value());
a.destroy();
CHECK_FALSE(a.has_value());
@ -223,15 +232,18 @@ namespace
alignas(A_t) char buffer1[sizeof(A_t)] = {0};
alignas(A_t) char buffer2[sizeof(A_t)] = {0};
// Construct.
etl::typed_storage_ext<A_t> a(buffer1);
CHECK_FALSE(a.has_value());
etl::typed_storage_ext<A_t> b(buffer2, 789, 10); // Construct in place.
// Construct in place.
etl::typed_storage_ext<A_t> b(buffer2, 789, 10);
CHECK_TRUE(b.has_value());
CHECK_EQUAL(b->x, 789);
CHECK_EQUAL(b->y, 10);
auto& ref = a.create(123, 4); // Create in place.
// Create in place.
auto& ref = a.create(123, 4);
CHECK_EQUAL(ref.x, 123);
CHECK_EQUAL(ref.y, 4);
@ -250,10 +262,17 @@ namespace
CHECK_EQUAL(b->x, 123);
CHECK_EQUAL(b->y, 4);
// Destroy
CHECK_TRUE(a.has_value());
a.destroy();
// Move contruct
etl::typed_storage_ext<A_t> c(etl::move(a));
CHECK_FALSE(a.has_value());
CHECK_TRUE(c.has_value());
CHECK_EQUAL(c->x, 789);
CHECK_EQUAL(c->y, 10);
// Destroy
CHECK_TRUE(c.has_value());
c.destroy();
CHECK_FALSE(c.has_value());
}
};
}

View File

@ -3701,6 +3701,18 @@
<ClCompile Include="..\test_not_null_pointer_constexpr.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\crc8_opensafety.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\crc16_opensafety_a.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\crc16_opensafety_b.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\delegate_observable.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">