diff --git a/include/etl/overload.h b/include/etl/overload.h index 52a41fcd..b2ab3333 100644 --- a/include/etl/overload.h +++ b/include/etl/overload.h @@ -65,44 +65,6 @@ namespace etl #else - //************************************************************************* - /// Variadic template definition of overload for C++14. - //************************************************************************* - //namespace private_overload - //{ - // //*********************************** - // // Overload helper templates. - // //*********************************** - // template - // struct overload_helper; - - // template <> - // struct overload_helper<> - // { - // }; - - // template - // struct overload_helper : TFirst, overload_helper - // { - // using TFirst::operator(); - - // template - // overload_helper(UFirst&& u, UOthers&&... others) - // : TFirst{ etl::forward(u) }, overload_helper{ etl::forward(others)... } - // { - // } - // }; - //} - - ////*********************************** - ///// Make an overload. - ////*********************************** - //template - //constexpr auto make_overload(TOverloads&&... overloads) - //{ - // return private_overload::overload_helper{ etl::forward(overloads)... }; - //} - template struct overload : TFirst, overload { @@ -110,7 +72,8 @@ namespace etl using overload::operator(); }; - template struct overload : TFirst + template + struct overload : TFirst { using TFirst::operator(); }; diff --git a/include/etl/private/variant_new.h b/include/etl/private/variant_new.h index 3e8adc76..139c0552 100644 --- a/include/etl/private/variant_new.h +++ b/include/etl/private/variant_new.h @@ -940,18 +940,18 @@ namespace etl void do_operator(TVisitor& visitor) { #if defined(ETL_VARIANT_CPP11_MAX_8_TYPES) - ETL_STATIC_ASSERT(sizeof...(TTypes) <= 8U, "There are more than 8 types in this variant"); + ETL_STATIC_ASSERT(sizeof...(TTypes) <= 8U, "ETL_VARIANT_CPP11_MAX_8_TYPES - Only a maximum of 8 types are allowed in this variant"); #endif #if defined(ETL_VARIANT_CPP11_MAX_16_TYPES) - ETL_STATIC_ASSERT(sizeof...(TTypes) <= 16U, "There are more than 16 types in this variant"); + ETL_STATIC_ASSERT(sizeof...(TTypes) <= 16U, "ETL_VARIANT_CPP11_MAX_16_TYPES - Only a maximum of 16 types are allowed in this variant"); #endif #if defined(ETL_VARIANT_CPP11_MAX_24_TYPES) - ETL_STATIC_ASSERT(sizeof...(TTypes) <= 24U, "There are more than 24 types in this variant"); + ETL_STATIC_ASSERT(sizeof...(TTypes) <= 24U, "ETL_VARIANT_CPP11_MAX_24_TYPES - Only a maximum of 24 types are allowed in this variant"); #endif - ETL_STATIC_ASSERT(sizeof...(TTypes) <= 32U, "There are more than 32 types in this variant"); + ETL_STATIC_ASSERT(sizeof...(TTypes) <= 32U, "A maximum of 32 types are allowed in this variant"); switch (index()) { @@ -1162,9 +1162,9 @@ namespace etl } //*************************************************************************** - /// get_if (pointer parameter) - //*************************************************************************** - template < size_t Index, typename... TTypes > + /// get_if + //*************************************************************************** + template< size_t Index, typename... TTypes > ETL_CONSTEXPR14 etl::add_pointer_t>> get_if(etl::variant* pv) noexcept { @@ -1199,7 +1199,14 @@ namespace etl { constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; - return etl::get_if(pv); + if ((pv != nullptr) && (pv->index() == Index)) + { + return &etl::get(*pv); + } + else + { + return nullptr; + } } //*********************************** @@ -1208,19 +1215,9 @@ namespace etl { constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; - return etl::get_if(pv); - } - - //*************************************************************************** - /// get_if (reference parameter) - //*************************************************************************** - template < size_t Index, typename... TTypes > - ETL_CONSTEXPR14 etl::add_pointer_t>> - get_if(etl::variant& v) noexcept - { - if (v.index() == Index) + if ((pv != nullptr) && (pv->index() == Index)) { - return &etl::get(v); + return &etl::get(*pv); } else { @@ -1228,63 +1225,6 @@ namespace etl } } - //*********************************** - template< size_t Index, typename... TTypes > - ETL_CONSTEXPR14 etl::add_pointer_t>> - get_if(const etl::variant& v) noexcept - { - if (v.index() == Index) - { - return &etl::get(v); - } - else - { - return nullptr; - } - } - - //*********************************** - template< size_t Index, typename... TTypes > - ETL_CONSTEXPR14 etl::add_pointer_t>> - get_if(etl::variant&& v) noexcept - { - if (v.index() == Index) - { - return &etl::get(v); - } - else - { - return nullptr; - } - } - - //*********************************** - template< class T, typename... TTypes > - ETL_CONSTEXPR14 etl::add_pointer_t get_if(etl::variant& v) noexcept - { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; - - return etl::get_if(v); - } - - //*********************************** - template< class T, typename... TTypes > - ETL_CONSTEXPR14 etl::add_pointer_t get_if(const etl::variant& v) noexcept - { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; - - return etl::get_if(v); - } - - //*********************************** - template< class T, typename... TTypes > - ETL_CONSTEXPR14 etl::add_pointer_t get_if(etl::variant&& v) noexcept - { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; - - return etl::get_if(v); - } - //*************************************************************************** /// swap //*************************************************************************** diff --git a/include/etl/variant.h b/include/etl/variant.h index 7e4a20e6..7f6b4546 100644 --- a/include/etl/variant.h +++ b/include/etl/variant.h @@ -31,7 +31,7 @@ SOFTWARE. #ifndef ETL_VARIANT_INCLUDED #define ETL_VARIANT_INCLUDED -#if ETL_USE_LEGACY_VARIANT +#if !ETL_CPP11_SUPPORTED || ETL_USE_LEGACY_VARIANT #include "private/variant_legacy.h" #else #include "private/variant_new.h" diff --git a/test/etl_profile.h b/test/etl_profile.h index 8b455130..710bb5a9 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -100,7 +100,7 @@ SOFTWARE. #define ETL_MEM_CAST_FORCE_CPP03 #endif -#define ETL_OVERLOAD_FORCE_CPP14 +//#define ETL_OVERLOAD_FORCE_CPP14 //#define ETL_VARIANT_FORCE_CPP11 #define ETL_VARIANT_CPP11_MAX_16_TYPES diff --git a/test/test_mem_cast.cpp b/test/test_mem_cast.cpp index 304be224..f233a81f 100644 --- a/test/test_mem_cast.cpp +++ b/test/test_mem_cast.cpp @@ -68,9 +68,7 @@ namespace using MemCast = etl::mem_cast; using MemCastTypes = etl::mem_cast_types; - char c; - double d; - Data data; + Data data; SUITE(test_mem_cast) { diff --git a/test/test_mem_cast_ptr.cpp b/test/test_mem_cast_ptr.cpp index 582d9c7a..2cc88738 100644 --- a/test/test_mem_cast_ptr.cpp +++ b/test/test_mem_cast_ptr.cpp @@ -65,8 +65,6 @@ namespace // Test variant types. using MemCast = etl::mem_cast_ptr; - char c; - double d; Data data; char* Ptr(int i) @@ -83,8 +81,6 @@ namespace { MemCast memCast; - char* p = nullptr; - memCast.data(Ptr(1)); CHECK_EQUAL(1U , memCast.alignment()); diff --git a/test/test_variant_new.cpp b/test/test_variant_new.cpp index c264c0eb..5ce23d0a 100644 --- a/test/test_variant_new.cpp +++ b/test/test_variant_new.cpp @@ -30,6 +30,7 @@ SOFTWARE. #include "etl/private/variant_new.h" #include "etl/visitor.h" +#include "etl/overload.h" #include #include @@ -675,7 +676,7 @@ namespace } //************************************************************************* - TEST(test_variant_visitor) + TEST(test_variant_accept_visitor) { struct Visitor : public etl::visitor { @@ -724,7 +725,7 @@ namespace } //************************************************************************* - TEST(test_variant_operator_visit) + TEST(test_variant_accept_functor_with_functor_class) { struct Visitor { @@ -745,7 +746,7 @@ namespace result_i = i; } - void operator()(std::string& s) + void operator()(const std::string& s) { result_s = s; } @@ -772,6 +773,35 @@ namespace CHECK_EQUAL("3", visitor.result_s); } + //************************************************************************* + TEST(test_variant__accept_functor_with_overload) + { + char result_c; + int result_i; + std::string result_s; + + auto visitor = etl::overload + { + [&result_c](char c) { result_c = 1; }, + [&result_i](int i) { result_i = 2; }, + [&result_s](const std::string& s) { result_s = "3"; } + }; + + test_variant_etl_3 variant_etl; + + variant_etl = char(1); + variant_etl.accept_functor(visitor); + CHECK_EQUAL(1, result_c); + + variant_etl = int(2); + variant_etl.accept_functor(visitor); + CHECK_EQUAL(2, result_i); + + variant_etl = std::string("3"); + variant_etl.accept_functor(visitor); + CHECK_EQUAL("3", result_s); + } + //************************************************************************* TEST(test_get_if_index) { @@ -779,27 +809,18 @@ namespace variant_etl = char(1); CHECK(etl::get_if<0>(&variant_etl) != nullptr); - CHECK(etl::get_if<0>(variant_etl) != nullptr); CHECK(etl::get_if<1>(&variant_etl) == nullptr); - CHECK(etl::get_if<1>(variant_etl) == nullptr); CHECK(etl::get_if<2>(&variant_etl) == nullptr); - CHECK(etl::get_if<2>(variant_etl) == nullptr); variant_etl = int(2); CHECK(etl::get_if<0>(&variant_etl) == nullptr); - CHECK(etl::get_if<0>(variant_etl) == nullptr); CHECK(etl::get_if<1>(&variant_etl) != nullptr); - CHECK(etl::get_if<1>(variant_etl) != nullptr); CHECK(etl::get_if<2>(&variant_etl) == nullptr); - CHECK(etl::get_if<2>(variant_etl) == nullptr); variant_etl = std::string("3"); CHECK(etl::get_if<0>(&variant_etl) == nullptr); - CHECK(etl::get_if<0>(variant_etl) == nullptr); CHECK(etl::get_if<1>(&variant_etl) == nullptr); - CHECK(etl::get_if<1>(variant_etl) == nullptr); CHECK(etl::get_if<2>(&variant_etl) != nullptr); - CHECK(etl::get_if<2>(variant_etl) != nullptr); } //************************************************************************* @@ -809,27 +830,18 @@ namespace variant_etl = char(1); CHECK(etl::get_if(&variant_etl) != nullptr); - CHECK(etl::get_if(variant_etl) != nullptr); CHECK(etl::get_if(&variant_etl) == nullptr); - CHECK(etl::get_if(variant_etl) == nullptr); CHECK(etl::get_if(&variant_etl) == nullptr); - CHECK(etl::get_if(variant_etl) == nullptr); variant_etl = int(2); CHECK(etl::get_if(&variant_etl) == nullptr); - CHECK(etl::get_if(variant_etl) == nullptr); CHECK(etl::get_if(&variant_etl) != nullptr); - CHECK(etl::get_if(variant_etl) != nullptr); CHECK(etl::get_if(&variant_etl) == nullptr); - CHECK(etl::get_if(variant_etl) == nullptr); variant_etl = std::string("3"); CHECK(etl::get_if(&variant_etl) == nullptr); - CHECK(etl::get_if(variant_etl) == nullptr); CHECK(etl::get_if(&variant_etl) == nullptr); - CHECK(etl::get_if(variant_etl) == nullptr); CHECK(etl::get_if(&variant_etl) != nullptr); - CHECK(etl::get_if(variant_etl) != nullptr); } //************************************************************************* @@ -938,97 +950,165 @@ namespace //************************************************************************* TEST(test_get_by_type) { - MoveableCopyable movecopyable; + MoveableCopyable value1; + MoveableCopyable value2; + MoveableCopyable value3; - etl::variant v(movecopyable); + etl::variant v_etl(value1); + const etl::variant cv_etl(value2); + etl::variant& rv_etl(v_etl); + const etl::variant& crv_etl(value3); - const etl::variant cv(movecopyable); - - etl::variant& rv(v); - - const etl::variant& crv(v); + std::variant v_std(value1); + const std::variant cv_std(value2); + std::variant& rv_std(v_std); + const std::variant& crv_std(value3); // From variant reference - MoveableCopyable movecopyable_vr = etl::get(rv); - - // From variant rvalue reference - MoveableCopyable&& movecopyable_vrr = etl::get(etl::move(v)); + MoveableCopyable value_vr_etl = etl::get(rv_etl); + MoveableCopyable value_vr_std = std::get(rv_std); + CHECK_EQUAL(value_vr_std.moved_from, value_vr_etl.moved_from); + CHECK_EQUAL(value_vr_std.moved_to, value_vr_etl.moved_to); + CHECK_EQUAL(value_vr_std.copied_to, value_vr_etl.copied_to); // From variant const reference - const MoveableCopyable& movecopyable_vcr = etl::get(crv); - + const MoveableCopyable& value_vcr_etl = etl::get(crv_etl); + const MoveableCopyable& value_vcr_std = std::get(crv_std); + CHECK_EQUAL(value_vcr_std.moved_from, value_vcr_etl.moved_from); + CHECK_EQUAL(value_vcr_std.moved_to, value_vcr_etl.moved_to); + CHECK_EQUAL(value_vcr_std.copied_to, value_vcr_etl.copied_to); + + // From variant rvalue reference + MoveableCopyable&& value_vrr_etl = etl::get(etl::move(v_etl)); + MoveableCopyable&& value_vrr_std = std::get(etl::move(v_std)); + CHECK_EQUAL(value_vrr_std.moved_from, value_vrr_etl.moved_from); + CHECK_EQUAL(value_vrr_std.moved_to, value_vrr_etl.moved_to); + CHECK_EQUAL(value_vrr_std.copied_to, value_vrr_etl.copied_to); + // From variant const rvalue reference - const MoveableCopyable&& movecopyable_vcrr = etl::get(etl::move(cv)); + const MoveableCopyable&& value_vcrr_etl = etl::get(etl::move(cv_etl)); + const MoveableCopyable&& value_vcrr_std = std::get(etl::move(cv_std)); + CHECK_EQUAL(value_vcrr_std.moved_from, value_vcrr_etl.moved_from); + CHECK_EQUAL(value_vcrr_std.moved_to, value_vcrr_etl.moved_to); + CHECK_EQUAL(value_vcrr_std.copied_to, value_vcrr_etl.copied_to); } //************************************************************************* - //TEST(test_copyable_vs_moveable_types_etl) - //{ - // Copyable copyable_from; - // Copyable copyable_to; + TEST(test_get_by_index) + { + MoveableCopyable value1; + MoveableCopyable value2; + MoveableCopyable value3; - // Moveable moveable_from; - // Moveable moveable_to; + etl::variant v_etl(value1); + const etl::variant cv_etl(value2); + etl::variant& rv_etl(v_etl); + const etl::variant& crv_etl(value3); - // MoveableCopyable movecopyable_from1; - // MoveableCopyable movecopyable_from2; - // MoveableCopyable movecopyable_to1; - // MoveableCopyable movecopyable_to2; + std::variant v_std(value1); + const std::variant cv_std(value2); + std::variant& rv_std(v_std); + const std::variant& crv_std(value3); - // etl::variant variant_c(copyable_from); - // copyable_to = etl::get<0>(variant_c); + // From variant reference + MoveableCopyable value_vr_etl = etl::get<0U>(rv_etl); + MoveableCopyable value_vr_std = std::get<0U>(rv_std); + CHECK_EQUAL(value_vr_std.moved_from, value_vr_etl.moved_from); + CHECK_EQUAL(value_vr_std.moved_to, value_vr_etl.moved_to); + CHECK_EQUAL(value_vr_std.copied_to, value_vr_etl.copied_to); - // etl::variant variant_m(etl::move(moveable_from)); - // moveable_to = etl::move(etl::get<0>(variant_m)); + // From variant const reference + const MoveableCopyable& value_vcr_etl = etl::get<0U>(crv_etl); + const MoveableCopyable& value_vcr_std = std::get<0U>(crv_std); + CHECK_EQUAL(value_vcr_std.moved_from, value_vcr_etl.moved_from); + CHECK_EQUAL(value_vcr_std.moved_to, value_vcr_etl.moved_to); + CHECK_EQUAL(value_vcr_std.copied_to, value_vcr_etl.copied_to); - // etl::variant variant_mc1(movecopyable_from1); - // movecopyable_to1 = etl::get<0>(variant_mc1); + // From variant rvalue reference + MoveableCopyable&& value_vrr_etl = etl::get<0U>(etl::move(v_etl)); + MoveableCopyable&& value_vrr_std = std::get<0U>(etl::move(v_std)); + CHECK_EQUAL(value_vrr_std.moved_from, value_vrr_etl.moved_from); + CHECK_EQUAL(value_vrr_std.moved_to, value_vrr_etl.moved_to); + CHECK_EQUAL(value_vrr_std.copied_to, value_vrr_etl.copied_to); - // etl::variant variant_mc2(etl::move(movecopyable_from2)); - // movecopyable_to2 = etl::move(etl::get<0>(variant_mc2)); - - // etl::variant variant_mc3(variant_mc1); - - // etl::variant variant_mc4(etl::move(variant_mc1)); - - // etl::variant variant_mc5(variant_mc2); - - // etl::variant variant_mc6(etl::move(variant_mc2)); - //} + // From variant const rvalue reference + const MoveableCopyable&& value_vcrr_etl = etl::get<0U>(etl::move(cv_etl)); + const MoveableCopyable&& value_vcrr_std = std::get<0U>(etl::move(cv_std)); + CHECK_EQUAL(value_vcrr_std.moved_from, value_vcrr_etl.moved_from); + CHECK_EQUAL(value_vcrr_std.moved_to, value_vcrr_etl.moved_to); + CHECK_EQUAL(value_vcrr_std.copied_to, value_vcrr_etl.copied_to); + } //************************************************************************* -// TEST(test_copyable_vs_moveable_types_std) -// { -// Copyable copyable_from; -// Copyable copyable_to; -// -// Moveable moveable_from; -// Moveable moveable_to; -// -// MoveableCopyable movecopyable_from1; -// MoveableCopyable movecopyable_from2; -// MoveableCopyable movecopyable_to1; -// MoveableCopyable movecopyable_to2; -// -// std::variant variant_c(copyable_from); -// copyable_to = std::get<0>(variant_c); -// -// //std::variant variant_m(etl::move(moveable_from)); -// //moveable_to = std::move(std::get<0>(variant_m)); -// -// std::variant variant_mc1(movecopyable_from1); -// movecopyable_to1 = std::get<0>(variant_mc1); -// -//// std::variant variant_mc2(std::move(movecopyable_from2)); -//// movecopyable_to2 = std::move(std::get<0>(variant_mc2)); -// -//// std::variant variant_mc3(variant_mc1); -// -//// std::variant variant_mc4(std::move(variant_mc1)); -// -//// std::variant variant_mc5(variant_mc2); -// -//// std::variant variant_mc6(std::move(variant_mc2)); -// } + TEST(test_get_if_by_type) + { + int value; + + etl::variant v(value); + const etl::variant cv(value); + etl::variant& rv(v); + const etl::variant& crv(v); + + int* pi; + const int* pci; + double* pd; + const double* pcd; + + etl::variant* pv = nullptr; + + // From nullptr + pi = etl::get_if(pv); + CHECK(pi == nullptr); + + // From variant reference + pi = etl::get_if(&rv); + CHECK(pi != nullptr); + + pd = etl::get_if(&rv); + CHECK(pd == nullptr); + + // From variant const reference + pci = etl::get_if(&crv); + CHECK(pci != nullptr); + + pcd = etl::get_if(&crv); + CHECK(pcd == nullptr); + } + + //************************************************************************* + TEST(test_get_if_by_index) + { + int value; + + etl::variant v(value); + const etl::variant cv(value); + etl::variant& rv(v); + const etl::variant& crv(v); + + int* pi; + const int* pci; + double* pd; + const double* pcd; + + etl::variant* pv = nullptr; + + // From nullptr + pi = etl::get_if<0U>(pv); + CHECK(pi == nullptr); + + // From variant reference + pi = etl::get_if<0U>(&rv); + CHECK(pi != nullptr); + + pd = etl::get_if<1U>(&rv); + CHECK(pd == nullptr); + + // From variant const reference + pci = etl::get_if<0U>(&crv); + CHECK(pci != nullptr); + + pcd = etl::get_if<1U>(&crv); + CHECK(pcd == nullptr); + } }; }