diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 7a4a2cf..9dd64cc 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -773,6 +773,19 @@ template using remove_cv_ref_t = typename std::remove_cv::type>::type; + +struct narrowing_check_impl +{ + template + static auto check(T (&&)[1]) -> mp11::mp_identity; + + template + using fn = decltype(check({ std::declval() })); +}; + +template using narrowing_check = mp11::mp_if, mp11::mp_identity, mp11::mp_invoke_q>; + template struct overload; template<> struct overload<> @@ -780,15 +793,40 @@ template<> struct overload<> void operator()() const; }; -template struct overload: overload +template struct overload : overload +{ + using overload::operator(); + template auto operator()(T1, U&&) const -> narrowing_check; +}; + +template struct overload : overload +{ + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; +}; + +template struct overload : overload { using overload::operator(); - mp11::mp_identity operator()(T1) const; + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; }; +template struct overload : overload +{ + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; +}; + +template struct overload : overload +{ + using overload::operator(); + template auto operator()(bool, U&&) const -> mp11::mp_if, bool>, mp11::mp_identity>; +}; + + #if BOOST_WORKAROUND( BOOST_MSVC, < 1930 ) -template using resolve_overload_type_ = decltype( overload()(std::declval()) ); +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... > { @@ -798,7 +836,7 @@ template using resolve_overload_type = typename resolve_ove #else -template using resolve_overload_type = typename decltype( overload()(std::declval()) )::type; +template using resolve_overload_type = typename decltype( overload()(std::declval(), std::declval()) )::type; #endif @@ -1947,8 +1985,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 ) 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} };