diff --git a/include/etl/alignment.h b/include/etl/alignment.h index c289b4a4..73527765 100644 --- a/include/etl/alignment.h +++ b/include/etl/alignment.h @@ -450,17 +450,10 @@ namespace etl template reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) { - if (has_value()) - { - storage.value = T(args...); - } - else - { - valid = true; - ::new (&storage.value) value_type(etl::forward(args)...); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(etl::forward(args)...); + valid = true; + return *p; } #else //*************************************************************************** @@ -470,17 +463,10 @@ namespace etl template reference create(const T1& t1) { - if (has_value()) - { - storage.value = T(t1); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1); + valid = true; + return *p; } //*************************************************************************** @@ -490,17 +476,10 @@ namespace etl template reference create(const T1& t1, const T2& t2) { - if (has_value()) - { - storage.value = T(t1, t2); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1, t2); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1, t2); + valid = true; + return *p; } //*************************************************************************** @@ -510,17 +489,10 @@ namespace etl template reference create(const T1& t1, const T2& t2, const T3& t3) { - if (has_value()) - { - storage.value = T(t1, t2, t3); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1, t2, t3); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1, t2, t3); + valid = true; + return *p; } //*************************************************************************** @@ -530,17 +502,10 @@ namespace etl template reference create(const T1& t1, const T2& t2, const T3& t3, const T4& 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; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1, t2, t3, t4); + valid = true; + return *p; } #endif @@ -684,6 +649,7 @@ namespace etl , valid(false) { ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of::value), ETL_ERROR(etl::alignment_error)); + create(t1); } //*************************************************************************** @@ -744,62 +710,67 @@ namespace etl #if ETL_USING_CPP11 //*************************************************************************** /// Constructs the instance of T forwarding the given \p args to its constructor. - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(etl::forward(args)...); valid = true; - return *::new (pbuffer) value_type(etl::forward(args)...); + return *p; } #else //*************************************************************************** /// Constructs the instance of T with type T1 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1); valid = true; - return *::new (pbuffer) value_type(t1); + return *p; } //*************************************************************************** /// Constructs the instance of T with types T1, T2 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1, const T2& t2) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1, t2); valid = true; - return *::new (pbuffer) value_type(t1, t2); + return *p; } //*************************************************************************** /// Constructs the instance of T with types T1, T2, T3 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1, const T2& t2, const T3& t3) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1, t2, t3); valid = true; - return *::new (pbuffer) value_type(t1, t2, t3); + return *p; } //*************************************************************************** /// Constructs the instance of T with types T1, T2, T3, T4 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1, t2, t3, t4); valid = true; - return *::new (pbuffer) value_type(t1, t2, t3, t4); + return *p; } #endif diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index c38acedb..24ff4c28 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -48,6 +48,7 @@ void f(int) { } +// Demonstrator class for etl::typed_storage tests struct A_t { A_t(uint32_t v_x, uint8_t v_y) @@ -56,13 +57,22 @@ struct A_t { } + // Just for test purpose. In production code, etl::typed_storage + // actually supports the use case of destructors being optimized + // away since they are not necessary for global objects that are + // never destroyed ~A_t() { x = 0; y = 0; } - bool operator==(A_t& other) + // etl::typed_storage helps implementing the use case of becoming + // independent of the destructor. By deleting the assignment operator, + // we make sure that the destructor is not linked + A_t& operator=(const A_t&) = delete; + + bool operator==(const A_t& other) const { return other.x == x && other.y == y; }