diff --git a/include/etl/alignment.h b/include/etl/alignment.h index 75439280..75f10683 100644 --- a/include/etl/alignment.h +++ b/include/etl/alignment.h @@ -386,6 +386,7 @@ namespace etl //*************************************************************************** /// Constructs the instance of T with type T1 //*************************************************************************** + template typed_storage(const T1& t1) : valid(false) { @@ -395,6 +396,7 @@ namespace etl //*************************************************************************** /// Constructs the instance of T with types T1, T2 //*************************************************************************** + template 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 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 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 typed_storage_ext(void* pbuffer_) ETL_NOEXCEPT_IF_NO_THROW : pbuffer(reinterpret_cast(pbuffer_)), valid(false) @@ -659,10 +662,23 @@ namespace etl ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of::value), ETL_ERROR(etl::alignment_error)); create(etl::forward(args)...); } + + //*************************************************************************** + /// Move constructor. + /// Transfers ownership of the buffer from \p other to this. + //*************************************************************************** + typed_storage_ext(typed_storage_ext&& 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 typed_storage_ext(void* pbuffer_, const T1& t1) : pbuffer(reinterpret_cast(pbuffer_)) , valid(false) @@ -670,20 +686,10 @@ namespace etl ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of::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(pbuffer_)) - , valid(false) - { - ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of::value), ETL_ERROR(etl::alignment_error)); - create(t1); - } - //*************************************************************************** /// Constructs the instance of T with types T1, T2 //*************************************************************************** + template typed_storage_ext(void* pbuffer_, const T1& t1, const T2& t2) : pbuffer(reinterpret_cast(pbuffer_)) , valid(false) @@ -695,6 +701,7 @@ namespace etl //*************************************************************************** /// Constructs the instance of T with types T1, T2, T3 //*************************************************************************** + template typed_storage_ext(void* pbuffer_, const T1& t1, const T2& t2, const T3& t3) : pbuffer(reinterpret_cast(pbuffer_)) , valid(false) @@ -706,6 +713,7 @@ namespace etl //*************************************************************************** /// Constructs the instance of T with types T1, T2, T3, T4 //*************************************************************************** + template typed_storage_ext(void* pbuffer_, const T1& t1, const T2& t2, const T3& t3, const T4& t4) : pbuffer(reinterpret_cast(pbuffer_)) , valid(false) @@ -848,7 +856,7 @@ namespace etl typed_storage_ext(etl::typed_storage_ext&) ETL_DELETE; typed_storage_ext& operator =(etl::typed_storage_ext&) ETL_DELETE; - T* pbuffer; + pointer pbuffer; bool valid; }; diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index b9d3b5d2..c38acedb 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -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; CHECK_FALSE(a.has_value()); - etl::typed_storage b(789, 10); // Construct in place. + // Construct in place. + etl::typed_storage 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(buffer1); CHECK_FALSE(a.has_value()); - etl::typed_storage_ext b(buffer2, 789, 10); // Construct in place. + // Construct in place. + etl::typed_storage_ext 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 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()); } }; } diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 7e7037be..34d11b62 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -3701,6 +3701,18 @@ Tests\Misc + + Tests\Syntax Checks\Source + + + Tests\Syntax Checks\Source + + + Tests\Syntax Checks\Source + + + Tests\Syntax Checks\Source +