From 280bacf780bfa21e0612508a79853e12740d8c6a Mon Sep 17 00:00:00 2001 From: John Buonagurio Date: Sun, 6 Sep 2020 22:22:25 -0400 Subject: [PATCH 1/3] Work on resolve_overload_* functions for P0608 support --- include/boost/variant2/variant.hpp | 46 +++++++++++++++++++----------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 7a4a2cf..3a58ed3 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -773,34 +773,50 @@ template struct overload; +template using remove_cv_ref_t = typename std::remove_cv::type>::type; -template<> struct overload<> +struct narrowing_check_impl { - void operator()() const; + template + static auto check(T (&&)[1]) -> mp11::mp_identity; + + template + using fn = decltype(check({ std::declval() })); }; -template struct overload: overload +template using narrowing_check = mp11::mp_if, mp11::mp_identity, mp11::mp_invoke_q>; + +template struct overload { - using overload::operator(); - mp11::mp_identity operator()(T1) const; + template + auto operator()(T, U&&) const -> narrowing_check; }; -#if BOOST_WORKAROUND( BOOST_MSVC, < 1930 ) +template struct overload_bool +{ + template + auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; +}; -template using resolve_overload_type_ = decltype( overload()(std::declval()) ); +template<> struct overload : overload_bool {}; +template<> struct overload : overload_bool {}; +template<> struct overload : overload_bool {}; +template<> struct overload : overload_bool {}; -template struct resolve_overload_type_impl: mp11::mp_defer< resolve_overload_type_, U, T... > +template struct overloads : T... { + void operator()() const; + using T::operator()...; }; -template using resolve_overload_type = typename resolve_overload_type_impl::type::type; +template struct resolve_overload_type_impl; -#else +template class L, class... T> struct resolve_overload_type_impl> +{ + using type = typename decltype( overloads...>()(std::declval(), std::declval()) )::type; +}; -template using resolve_overload_type = typename decltype( overload()(std::declval()) )::type; - -#endif +template using resolve_overload_type = typename resolve_overload_type_impl>>::type; template using resolve_overload_index = mp11::mp_find, resolve_overload_type>; @@ -1947,8 +1963,6 @@ template constexpr bool operator>=( variant const & v, variant namespace detail { -template using remove_cv_ref_t = typename std::remove_cv::type>::type; - template variant const & extract_variant_base_( variant const & ); #if BOOST_WORKAROUND( BOOST_MSVC, < 1930 ) From 98bd0891e75c680f11836a24189f7dd0eba469c3 Mon Sep 17 00:00:00 2001 From: John Buonagurio Date: Tue, 8 Sep 2020 16:51:59 -0400 Subject: [PATCH 2/3] Work on resolve_overload_* functions for P0608 support --- include/boost/variant2/variant.hpp | 56 +++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 3a58ed3..9dd64cc 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -786,37 +786,59 @@ struct narrowing_check_impl template using narrowing_check = mp11::mp_if, mp11::mp_identity, mp11::mp_invoke_q>; -template struct overload +template struct overload; + +template<> struct overload<> { - template - auto operator()(T, U&&) const -> narrowing_check; + void operator()() const; }; -template struct overload_bool +template struct overload : overload { - template - auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; + using overload::operator(); + template auto operator()(T1, U&&) const -> narrowing_check; }; -template<> struct overload : overload_bool {}; -template<> struct overload : overload_bool {}; -template<> struct overload : overload_bool {}; -template<> struct overload : overload_bool {}; +template struct overload : overload +{ + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; +}; -template struct overloads : T... +template struct overload : overload { - void operator()() const; - using T::operator()...; + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; }; -template struct resolve_overload_type_impl; +template struct overload : overload +{ + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; +}; -template class L, class... T> struct resolve_overload_type_impl> +template struct overload : overload { - using type = typename decltype( overloads...>()(std::declval(), std::declval()) )::type; + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; }; -template using resolve_overload_type = typename resolve_overload_type_impl>>::type; + +#if BOOST_WORKAROUND( BOOST_MSVC, < 1930 ) + +template using resolve_overload_type_ = decltype( overload()(std::declval(), std::declval()) ); + +template struct resolve_overload_type_impl: mp11::mp_defer< resolve_overload_type_, U, T... > +{ +}; + +template using resolve_overload_type = typename resolve_overload_type_impl::type::type; + +#else + +template using resolve_overload_type = typename decltype( overload()(std::declval(), std::declval()) )::type; + +#endif template using resolve_overload_index = mp11::mp_find, resolve_overload_type>; From c7788fac9d3457766c97c90bc8f6c0c759c12a26 Mon Sep 17 00:00:00 2001 From: John Buonagurio Date: Tue, 8 Sep 2020 17:07:59 -0400 Subject: [PATCH 3/3] Add test case for P0608 support --- test/variant_convert_construct.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/variant_convert_construct.cpp b/test/variant_convert_construct.cpp index dbf61d9..818c791 100644 --- a/test/variant_convert_construct.cpp +++ b/test/variant_convert_construct.cpp @@ -156,6 +156,20 @@ int main() BOOST_TEST( holds_alternative( v3 ) ); BOOST_TEST_EQ( get( v2 ), get( v3 ) ); } + + { + variant v( "s2" ); + + variant v2( v ); + + BOOST_TEST( holds_alternative( v2 ) ); + BOOST_TEST_EQ( get( v ), get( v2 ) ); + + variant v3( std::move(v) ); + + BOOST_TEST( holds_alternative( v3 ) ); + BOOST_TEST_EQ( get( v2 ), get( v3 ) ); + } { variant v{ X1{1} };