From 92515111d906ed557e84f5eccc5ac77463257c7b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 22 May 2021 20:28:40 +0100 Subject: [PATCH] Interim commit --- include/etl/private/variant_new.h | 85 ++++++++++++++++++- test/test_variant_new.cpp | 136 +++++++++--------------------- 2 files changed, 121 insertions(+), 100 deletions(-) diff --git a/include/etl/private/variant_new.h b/include/etl/private/variant_new.h index 379e9ab8..1c2d36d4 100644 --- a/include/etl/private/variant_new.h +++ b/include/etl/private/variant_new.h @@ -58,7 +58,15 @@ namespace etl { static_assert(ETL_CPP11_SUPPORTED, "Only supported for C++11 or above"); - static size_t variant_npos = etl::integral_limits::max; + constexpr size_t variant_npos = etl::integral_limits::max; + + //*************************************************************************** + /// Monostate for variants. + ///\ingroup variant + //*************************************************************************** + struct monostate + { + }; //*************************************************************************** /// Base exception for the variant class. @@ -193,11 +201,13 @@ namespace etl template T& emplace(TArgs&&... args) { - static_assert(etl::is_one_of::value, "Unsupported type"); + static_assert(etl::is_one_of::value, "Unsupported type"); T temp(etl::forward(args)...); operation(action_type::Destruct, data, nullptr); + + operation = do_operation; operation(action_type::Construct, data, &temp); type_id = etl::parameter_pack::index_of_type::value; @@ -292,7 +302,7 @@ namespace etl template const T& get() const { - static_assert(etl::is_one_of::value, "Unsupported type"); + static_assert(etl::is_one_of::value, "Unsupported type"); ETL_ASSERT(is_type(), ETL_ERROR(variant_incorrect_type_exception)); return static_cast(data); @@ -475,6 +485,56 @@ namespace etl return get(v); } + //*************************************************************************** + /// get_if + //*************************************************************************** + template < size_t Index, class... Types > + constexpr etl::add_pointer_t>> + get_if(etl::variant* pv) noexcept + { + if ((pv != nullptr) && (pv->index() == Index)) + { + return &etl::get(*pv); + } + else + { + return nullptr; + } + } + + //*********************************** + template< size_t Index, class... Types > + constexpr etl::add_pointer_t>> + get_if(const etl::variant* pv) noexcept + { + if ((pv != nullptr) && (pv->index() == Index)) + { + return &etl::get(*pv); + } + else + { + return nullptr; + } + } + + //*********************************** + template< class T, class... Types > + constexpr etl::add_pointer_t get_if(etl::variant* pv) noexcept + { + constexpr size_t Index = etl::parameter_pack::index_of_type::value; + + return etl::get_if(pv); + } + + //*********************************** + template< class T, class... Types > + constexpr etl::add_pointer_t get_if(const etl::variant* pv) noexcept + { + constexpr size_t Index = etl::parameter_pack::index_of_type::value; + + return etl::get_if(pv); + } + //*************************************************************************** /// swap //*************************************************************************** @@ -483,4 +543,23 @@ namespace etl { lhs.swap(rhs); } + + //*************************************************************************** + /// variant_size + //*************************************************************************** + template + struct variant_size; + + template + struct variant_size> + : etl::integral_constant + { + }; + + template + struct variant_size + : etl::integral_constant::value> + { + }; + } diff --git a/test/test_variant_new.cpp b/test/test_variant_new.cpp index 68ac1c05..a99a6e83 100644 --- a/test/test_variant_new.cpp +++ b/test/test_variant_new.cpp @@ -307,6 +307,28 @@ namespace CHECK_EQUAL(text, variant_2.get()); } + //************************************************************************* + TEST(test_assignment_incorrect_type_exception) + { + std::string text("Some Text"); + test_variant_3a variant(text); + + int i; + CHECK_THROW(etl::get(variant), etl::variant_incorrect_type_exception); + (void)i; + } + + //************************************************************************* + TEST(test_self_assignment) + { + test_variant_3a variant; + + variant = 1; + variant = variant; + + CHECK_EQUAL(1, etl::get(variant)); + } + //************************************************************************* TEST(test_member_swap_variants) { @@ -342,105 +364,25 @@ namespace } //************************************************************************* - TEST(test_assignment_incorrect_type_exception) + TEST(test_emplace) { - std::string text("Some Text"); - test_variant_3a variant(text); + test_variant_emplace variant; - int i; - CHECK_THROW(etl::get(variant), etl::variant_incorrect_type_exception); - (void)i; + variant.emplace("1"); + CHECK(etl::holds_alternative(variant)); + CHECK_EQUAL(D1("1"), etl::get(variant)); + + variant.emplace("1", "2"); + CHECK(etl::holds_alternative(variant)); + CHECK_EQUAL(D2("1", "2"), etl::get(variant)); + + variant.emplace("1", "2", "3"); + CHECK(etl::holds_alternative(variant)); + CHECK_EQUAL(D3("1", "2", "3"), etl::get(variant)); + + variant.emplace("1", "2", "3", "4"); + CHECK(etl::holds_alternative(variant)); + CHECK_EQUAL(D4("1", "2", "3", "4"), etl::get(variant)); } - - ////************************************************************************* - //TEST(test_get) - //{ - // test_variant_3a variant; - - // variant = 1; - // CHECK_EQUAL(1, variant.get()); - - // variant = 'a'; - // CHECK_EQUAL('a', variant.get()); - - // variant = std::string("Some Text"); - // CHECK_EQUAL(std::string("Some Text"), variant.get()); - //} - - ////************************************************************************* - //TEST(test_get_const) - //{ - // test_variant_3a variant; - - // variant = 1; - // const test_variant_3a cvariant1(variant); - // CHECK_EQUAL(1, cvariant1.get()); - - // variant = 'a'; - // const test_variant_3a cvariant2(variant); - // CHECK_EQUAL('a', cvariant2.get()); - - // variant = std::string("Some Text"); - // const test_variant_3a cvariant3(variant); - // CHECK_EQUAL(std::string("Some Text"), cvariant3.get()); - //} - - ////************************************************************************* - //TEST(test_self_assignment) - //{ - // test_variant_3a variant; - - // variant = 1; - // variant = variant; - - // CHECK_EQUAL(1, variant.get()); - //} - - ////************************************************************************* - //TEST(TestGetException) - //{ - // test_variant_3a variant; - // variant = 1; - - // char c; - // CHECK_THROW(c = variant.get(), etl::variant_incorrect_type_exception); - // (void)c; - //} - - ////************************************************************************* - //TEST(TestPolymorphic) - //{ - // test_variant_polymorphic variant; - - // variant = derived_1(); - // variant.upcast().set(); - // CHECK_EQUAL(1, variant.get().value); - - // variant = derived_2(); - // variant.upcast().set(); - // CHECK_EQUAL(2, variant.get().value); - //} - - ////************************************************************************* - //TEST(TestEmplace) - //{ - // test_variant_emplace variant; - - // variant.emplace("1"); - // CHECK(variant.is_type()); - // CHECK_EQUAL(D1("1"), variant.get()); - - // variant.emplace("1", "2"); - // CHECK(variant.is_type()); - // CHECK_EQUAL(D2("1", "2"), variant.get()); - - // variant.emplace("1", "2", "3"); - // CHECK(variant.is_type()); - // CHECK_EQUAL(D3("1", "2", "3"), variant.get()); - - // variant.emplace("1", "2", "3", "4"); - // CHECK(variant.is_type()); - // CHECK_EQUAL(D4("1", "2", "3", "4"), variant.get()); - //} }; }