Skip to content

Commit db57df1

Browse files
author
John Wellbelove
committed
Merge branch 'development'
# Conflicts: # include/etl/alignment.h
2 parents 7324388 + 476c965 commit db57df1

13 files changed

+85
-82
lines changed

arduino/library-arduino.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Embedded Template Library ETL",
3-
"version": "20.43.1",
3+
"version": "20.43.2",
44
"authors": {
55
"name": "John Wellbelove",
66
"email": "[email protected]"

arduino/library-arduino.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Embedded Template Library ETL
2-
version=20.43.1
2+
version=20.43.2
33
author= John Wellbelove <[email protected]>
44
maintainer=John Wellbelove <[email protected]>
55
license=MIT

include/etl/alignment.h

Lines changed: 36 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -450,17 +450,10 @@ namespace etl
450450
template <typename... TArgs>
451451
reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS)
452452
{
453-
if (has_value())
454-
{
455-
storage.value = T(args...);
456-
}
457-
else
458-
{
459-
valid = true;
460-
::new (&storage.value) value_type(etl::forward<TArgs>(args)...);
461-
}
462-
463-
return storage.value;
453+
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
454+
pointer p = ::new (&storage.value) value_type(etl::forward<TArgs>(args)...);
455+
valid = true;
456+
return *p;
464457
}
465458
#else
466459
//***************************************************************************
@@ -470,17 +463,10 @@ namespace etl
470463
template <typename T1>
471464
reference create(const T1& t1)
472465
{
473-
if (has_value())
474-
{
475-
storage.value = T(t1);
476-
}
477-
else
478-
{
479-
valid = true;
480-
::new (&storage.value) value_type(t1);
481-
}
482-
483-
return storage.value;
466+
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
467+
pointer p = ::new (&storage.value) value_type(t1);
468+
valid = true;
469+
return *p;
484470
}
485471

486472
//***************************************************************************
@@ -490,17 +476,10 @@ namespace etl
490476
template <typename T1, typename T2>
491477
reference create(const T1& t1, const T2& t2)
492478
{
493-
if (has_value())
494-
{
495-
storage.value = T(t1, t2);
496-
}
497-
else
498-
{
499-
valid = true;
500-
::new (&storage.value) value_type(t1, t2);
501-
}
502-
503-
return storage.value;
479+
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
480+
pointer p = ::new (&storage.value) value_type(t1, t2);
481+
valid = true;
482+
return *p;
504483
}
505484

506485
//***************************************************************************
@@ -510,17 +489,10 @@ namespace etl
510489
template <typename T1, typename T2, typename T3>
511490
reference create(const T1& t1, const T2& t2, const T3& t3)
512491
{
513-
if (has_value())
514-
{
515-
storage.value = T(t1, t2, t3);
516-
}
517-
else
518-
{
519-
valid = true;
520-
::new (&storage.value) value_type(t1, t2, t3);
521-
}
522-
523-
return storage.value;
492+
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
493+
pointer p = ::new (&storage.value) value_type(t1, t2, t3);
494+
valid = true;
495+
return *p;
524496
}
525497

526498
//***************************************************************************
@@ -530,17 +502,10 @@ namespace etl
530502
template <typename T1, typename T2, typename T3, typename T4>
531503
reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
532504
{
533-
if (has_value())
534-
{
535-
storage.value = T(t1, t2, t3, t4);
536-
}
537-
else
538-
{
539-
valid = true;
540-
::new (&storage.value) value_type(t1, t2, t3, t4);
541-
}
542-
543-
return storage.value;
505+
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
506+
pointer p = ::new (&storage.value) value_type(t1, t2, t3, t4);
507+
valid = true;
508+
return *p;
544509
}
545510
#endif
546511

@@ -684,6 +649,7 @@ namespace etl
684649
, valid(false)
685650
{
686651
ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of<T>::value), ETL_ERROR(etl::alignment_error));
652+
create(t1);
687653
}
688654

689655
//***************************************************************************
@@ -744,62 +710,67 @@ namespace etl
744710
#if ETL_USING_CPP11
745711
//***************************************************************************
746712
/// Constructs the instance of T forwarding the given \p args to its constructor.
747-
/// \returns the instance of T which has been constructed in the internal byte array.
713+
/// \returns the instance of T which has been constructed in the external buffer.
748714
//***************************************************************************
749715
template <typename... TArgs>
750716
reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS)
751717
{
752718
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
719+
pointer p = ::new (pbuffer) value_type(etl::forward<TArgs>(args)...);
753720
valid = true;
754-
return *::new (pbuffer) value_type(etl::forward<TArgs>(args)...);
721+
return *p;
755722
}
756723
#else
757724
//***************************************************************************
758725
/// Constructs the instance of T with type T1
759-
/// \returns the instance of T which has been constructed in the internal byte array.
726+
/// \returns the instance of T which has been constructed in the external buffer.
760727
//***************************************************************************
761728
template <typename T1>
762729
reference create(const T1& t1)
763730
{
764731
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
732+
pointer p = ::new (pbuffer) value_type(t1);
765733
valid = true;
766-
return *::new (pbuffer) value_type(t1);
734+
return *p;
767735
}
768736

769737
//***************************************************************************
770738
/// Constructs the instance of T with types T1, T2
771-
/// \returns the instance of T which has been constructed in the internal byte array.
739+
/// \returns the instance of T which has been constructed in the external buffer.
772740
//***************************************************************************
773741
template <typename T1, typename T2>
774742
reference create(const T1& t1, const T2& t2)
775743
{
776744
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
745+
pointer p = ::new (pbuffer) value_type(t1, t2);
777746
valid = true;
778-
return *::new (pbuffer) value_type(t1, t2);
747+
return *p;
779748
}
780749

781750
//***************************************************************************
782751
/// Constructs the instance of T with types T1, T2, T3
783-
/// \returns the instance of T which has been constructed in the internal byte array.
752+
/// \returns the instance of T which has been constructed in the external buffer.
784753
//***************************************************************************
785754
template <typename T1, typename T2, typename T3>
786755
reference create(const T1& t1, const T2& t2, const T3& t3)
787756
{
788757
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
758+
pointer p = ::new (pbuffer) value_type(t1, t2, t3);
789759
valid = true;
790-
return *::new (pbuffer) value_type(t1, t2, t3);
760+
return *p;
791761
}
792762

793763
//***************************************************************************
794764
/// Constructs the instance of T with types T1, T2, T3, T4
795-
/// \returns the instance of T which has been constructed in the internal byte array.
765+
/// \returns the instance of T which has been constructed in the external buffer.
796766
//***************************************************************************
797767
template <typename T1, typename T2, typename T3, typename T4>
798768
reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
799769
{
800770
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
771+
pointer p = ::new (pbuffer) value_type(t1, t2, t3, t4);
801772
valid = true;
802-
return *::new (pbuffer) value_type(t1, t2, t3, t4);
773+
return *p;
803774
}
804775
#endif
805776

include/etl/optional.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,17 @@ namespace etl
536536

537537
return storage.u.value;
538538
}
539+
540+
//*************************************************************************
541+
/// Emplaces with zero arguments, i.e. default construct emplace.
542+
//*************************************************************************
543+
ETL_CONSTEXPR20_STL
544+
T& emplace()
545+
{
546+
storage.construct();
547+
548+
return storage.u.value;
549+
}
539550
#else
540551
//*************************************************************************
541552
/// Emplaces a value.

include/etl/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ SOFTWARE.
4040

4141
#define ETL_VERSION_MAJOR 20
4242
#define ETL_VERSION_MINOR 43
43-
#define ETL_VERSION_PATCH 1
43+
#define ETL_VERSION_PATCH 2
4444

4545
#define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH)
4646
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH)

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Embedded Template Library",
3-
"version": "20.43.1",
3+
"version": "20.43.2",
44
"authors": {
55
"name": "John Wellbelove",
66
"email": "[email protected]"

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Embedded Template Library
2-
version=20.43.1
2+
version=20.43.2
33
author= John Wellbelove <[email protected]>
44
maintainer=John Wellbelove <[email protected]>
55
license=MIT

support/Release notes.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
===============================================================================
2+
20.43.2
3+
4+
Pull Requests:
5+
#1182 Fix etl::typed_storage by supporting omitted destructors
6+
#1183 Regression fix: Support zero arguments emplace() in etl::optional
7+
8+
===============================================================================
29
20.43.1
310

411
Updates:

test/test_alignment.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void f(int)
4848
{
4949
}
5050

51+
// Demonstrator class for etl::typed_storage tests
5152
struct A_t
5253
{
5354
A_t(uint32_t v_x, uint8_t v_y)
@@ -56,13 +57,22 @@ struct A_t
5657
{
5758
}
5859

60+
// Just for test purpose. In production code, etl::typed_storage
61+
// actually supports the use case of destructors being optimized
62+
// away since they are not necessary for global objects that are
63+
// never destroyed
5964
~A_t()
6065
{
6166
x = 0;
6267
y = 0;
6368
}
6469

65-
bool operator==(A_t& other)
70+
// etl::typed_storage helps implementing the use case of becoming
71+
// independent of the destructor. By deleting the assignment operator,
72+
// we make sure that the destructor is not linked
73+
A_t& operator=(const A_t&) = delete;
74+
75+
bool operator==(const A_t& other) const
6676
{
6777
return other.x == x && other.y == y;
6878
}

test/test_optional.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,27 @@ namespace
218218
}
219219

220220
//*************************************************************************
221-
TEST(test_emplace_zero_parameters)
221+
TEST(test_emplace_zero_parameters_fundamental)
222222
{
223223
etl::optional<std::uint8_t> result = 1;
224-
result.emplace();
224+
CHECK_EQUAL(0, static_cast<int>(result.emplace()));
225225

226226
CHECK_TRUE(result.has_value());
227227
CHECK_EQUAL(0, int(result.value()));
228228
}
229229

230+
//*************************************************************************
231+
TEST(test_emplace_zero_parameters_non_fundamental)
232+
{
233+
etl::optional<std::string> result = std::string("abc");
234+
235+
std::string& ref = result.emplace();
236+
CHECK_EQUAL(std::string(), ref);
237+
CHECK_EQUAL(&ref, &result.value());
238+
CHECK_TRUE(result.has_value());
239+
CHECK_EQUAL("", std::string(result.value()));
240+
}
241+
230242
//*************************************************************************
231243
TEST(test_emplace_return)
232244
{

0 commit comments

Comments
 (0)