From e67066b788d7e1c3b17787c365dbf03b457a6bda Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 2 Aug 2025 13:47:33 +0100 Subject: [PATCH] Added emplace type constructors to etl::optional --- include/etl/optional.h | 96 ++++++++++++++++++++++++++++++++++++++--- test/test_optional.cpp | 70 ++++++++++++++++++++++++++++++ test/vs2022/etl.vcxproj | 30 ++++++------- 3 files changed, 176 insertions(+), 20 deletions(-) diff --git a/include/etl/optional.h b/include/etl/optional.h index f70b2689..4cff15ab 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -102,7 +102,7 @@ namespace etl //***************************************************************************** namespace private_optional { - template ::value> + template ::value> class optional_impl; //***************************************************************************** @@ -159,7 +159,6 @@ namespace etl storage.construct(etl::move(other.value())); } } -#endif //*************************************************************************** /// Constructor from value type. @@ -170,7 +169,6 @@ namespace etl storage.construct(value_); } -#if ETL_USING_CPP11 //*************************************************************************** /// Constructor from value type. //*************************************************************************** @@ -179,6 +177,27 @@ namespace etl { storage.construct(etl::move(value_)); } + + //*************************************************************************** + /// Constructor from variadic args. + //*************************************************************************** + template + ETL_CONSTEXPR20_STL + optional_impl(etl::in_place_t, TArgs&&... args) + { + storage.construct(etl::forward(args)...); + } + + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + ETL_CONSTEXPR20_STL optional_impl(etl::in_place_t, + std::initializer_list ilist, + TArgs&&... args) + { + storage.construct(ilist, etl::forward(args)...); + } #endif //*************************************************************************** @@ -734,7 +753,6 @@ namespace etl storage.construct(etl::move(other.value())); } } -#endif //*************************************************************************** /// Constructor from value type. @@ -745,7 +763,6 @@ namespace etl storage.construct(value_); } -#if ETL_USING_CPP11 //*************************************************************************** /// Constructor from value type. //*************************************************************************** @@ -754,6 +771,27 @@ namespace etl { storage.construct(etl::move(value_)); } + + //*************************************************************************** + /// Constructor from variadic args. + //*************************************************************************** + template + ETL_CONSTEXPR14 + optional_impl(etl::in_place_t, TArgs&&... args) + { + storage.construct(etl::forward(args)...); + } + + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + ETL_CONSTEXPR14 optional_impl(etl::in_place_t, + std::initializer_list ilist, + TArgs&&... args) + { + storage.construct(ilist, etl::forward(args)...); + } #endif //*************************************************************************** @@ -1397,6 +1435,54 @@ namespace etl } #endif +#if ETL_USING_CPP11 + //*************************************************************************** + /// Emplace construct from arguments. + //*************************************************************************** + template + ETL_CONSTEXPR14 + explicit optional(etl::in_place_t, Args&&... args) + : impl_t(etl::in_place_t{}, etl::forward(args)...) + { + } + + //*************************************************************************** + /// Emplace construct from arguments. + //*************************************************************************** + template + ETL_CONSTEXPR20_STL + explicit optional(etl::in_place_t, Args&&... args) + : impl_t(etl::in_place_t{}, etl::forward(args)...) + { + } + +#if ETL_HAS_INITIALIZER_LIST + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + ETL_CONSTEXPR14 + explicit optional(etl::in_place_t, + std::initializer_list ilist, + TArgs&&... args) + : impl_t(etl::in_place_t{}, ilist, etl::forward(args)...) + { + } + + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + ETL_CONSTEXPR20_STL + explicit optional(etl::in_place_t, + std::initializer_list ilist, + TArgs&&... args) + : impl_t(etl::in_place_t{}, ilist, etl::forward(args)...) + { + } +#endif +#endif + #if ETL_USING_CPP11 //*************************************************************************** /// Assignment operator from nullopt. diff --git a/test/test_optional.cpp b/test/test_optional.cpp index 87ee24c7..f0ea43ed 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -31,6 +31,7 @@ SOFTWARE. #include #include #include +#include #include "etl/optional.h" #include "etl/vector.h" @@ -118,6 +119,75 @@ namespace CHECK(!data4.has_value()); } +#if ETL_USING_CPP14 + //************************************************************************* + TEST(test_emplace_construction_cpp14) + { + constexpr etl::optional opt(etl::in_place_t{}, 1); + + CHECK_TRUE(opt.has_value()); + CHECK(bool(opt)); + CHECK_EQUAL(1, opt.value()); + } +#endif + +#if ETL_USING_CPP20 && ETL_USING_STL + //************************************************************************* + TEST(test_emplace_construction_cpp20) + { + struct TestData + { + constexpr TestData(int a_, int b_) + : a(a_), b(b_) + { + } + + int a; + int b; + }; + + constexpr etl::optional opt(etl::in_place_t{}, 1, 2); + + CHECK_TRUE(opt.has_value()); + CHECK(bool(opt)); + CHECK_EQUAL(1, opt.value().a); + CHECK_EQUAL(2, opt.value().b); + } +#endif + + //************************************************************************* + TEST(test_construct_from_initializer_list_and_arguments) + { + struct S + { + S() + : vi() + , a(0) + , b(0) + { + } + + S(std::initializer_list il, int a_, int b_) + : vi(il) + , a(a_) + , b(b_) + { + } + + std::vector vi; + int a; + int b; + }; + + etl::optional opt(etl::in_place_t{}, { 10, 11, 12 }, 1, 2); + + CHECK_EQUAL(10, opt.value().vi[0]); + CHECK_EQUAL(11, opt.value().vi[1]); + CHECK_EQUAL(12, opt.value().vi[2]); + CHECK_EQUAL(1, opt.value().a); + CHECK_EQUAL(2, opt.value().b); + } + //************************************************************************* TEST(test_deduced_initialisation) { diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index 721f9bcc..445f32d6 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -1403,7 +1403,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1429,7 +1429,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS;ETL_NO_STL;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS;ETL_NO_STL;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1455,7 +1455,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_FORCE_TEST_CPP03_IMPLEMENTATION;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_FORCE_TEST_CPP03_IMPLEMENTATION;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1481,7 +1481,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_FORCE_TEST_CPP03_IMPLEMENTATION;ETL_MESSAGES_ARE_NOT_VIRTUAL;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_FORCE_TEST_CPP03_IMPLEMENTATION;ETL_MESSAGES_ARE_NOT_VIRTUAL;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1507,7 +1507,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_MESSAGES_ARE_NOT_VIRTUAL;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_MESSAGES_ARE_NOT_VIRTUAL;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1533,7 +1533,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_IMESSAGE_IS_NON_VIRTUAL;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_IMESSAGE_IS_NON_VIRTUAL;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1559,7 +1559,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1585,7 +1585,7 @@ Level3 MaxSpeed - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1611,7 +1611,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1636,7 +1636,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1661,7 +1661,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1686,7 +1686,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1711,7 +1711,7 @@ Level3 MaxSpeed - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1737,7 +1737,7 @@ Level3 MaxSpeed - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions) ../../../unittest-cpp/;../../include;../../test @@ -1948,7 +1948,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions);N = 123456789;N + WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING;ETL_NO_STL;ETL_FORCE_STD_INITIALIZER_LIST;%(PreprocessorDefinitions) ./;../../../unittest-cpp/;../../include;../../test