diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index f7fac51..7834ef7 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -598,11 +598,8 @@ template using resolve_overload_index = mp11::mp_find using can_be_valueless = mp11::mp_any..., std::is_nothrow_default_constructible...>; -template using valueless_index = mp11::mp_if, monostate>, mp11::mp_find, monostate>, mp11::mp_find_if, std::is_nothrow_default_constructible>>; - -template struct variant_base_impl; // trivially destructible, single buffered -template using variant_base = variant_base_impl...>::value, mp11::mp_any...>, can_be_valueless>::value, T...>; +template struct variant_base_impl; +template using variant_base = variant_base_impl...>::value, mp11::mp_all...>::value, T...>; struct none {}; @@ -649,7 +646,7 @@ template struct variant_base_impl return st1_.get( mp11::mp_size_t() ); } - template BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_true, mp11::mp_bool, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_true, A&&... a ) { static_assert( std::is_nothrow_constructible::value, "Logic error: U must be nothrow constructible from A&&..." ); @@ -657,7 +654,7 @@ template struct variant_base_impl ix_ = J; } - template BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_true, A&&... a ) + template BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, A&&... a ) { static_assert( std::is_nothrow_move_constructible::value, "Logic error: U must be nothrow move constructible" ); @@ -667,37 +664,12 @@ template struct variant_base_impl ix_ = J; } - template void emplace_impl( mp11::mp_false, mp11::mp_false, A&&... a ) - { - static_assert( can_be_valueless::value, "Logic error: T... must have a fallback type" ); - - std::size_t const K = valueless_index::value; - - static_assert( K < sizeof...(T), "Logic error: T... must have a fallback index" ); - - try - { - st1_.emplace( mp11::mp_size_t(), std::forward(a)... ); - ix_ = J; - } - catch( ... ) - { - st1_.emplace( mp11::mp_size_t() ); - ix_ = K+1; - - throw; - } - } - template BOOST_CXX14_CONSTEXPR void emplace( A&&... a ) { std::size_t const J = I+1; using U = mp11::mp_at_c, I>; - constexpr bool B1 = can_be_valueless::value; - constexpr bool B2 = mp11::mp_all, detail::is_trivially_move_assignable...>::value; - - this->emplace_impl( std::is_nothrow_constructible(), mp11::mp_bool(), std::forward(a)... ); + this->emplace_impl( std::is_nothrow_constructible(), std::forward(a)... ); } }; @@ -836,42 +808,12 @@ template struct variant_base_impl return st1_.get( mp11::mp_size_t() ); } - template void emplace_impl( mp11::mp_int<0>, A&&... a ) + template void emplace( A&&... a ) { - static_assert( std::is_nothrow_constructible::value, "Logic error: U must be nothrow constructible from A&&..." ); + size_t const J = I+1; - _destroy(); + using U = mp11::mp_at_c, I>; - st1_.emplace( mp11::mp_size_t(), std::forward(a)... ); - ix_ = J; - } - - template void emplace_impl( mp11::mp_int<1>, A&&... a ) - { - static_assert( can_be_valueless::value, "Logic error: T... must have a fallback type" ); - - std::size_t const K = valueless_index::value; - - static_assert( K < sizeof...(T), "Logic error: T... must have a fallback index" ); - - _destroy(); - - try - { - st1_.emplace( mp11::mp_size_t(), std::forward(a)... ); - ix_ = J; - } - catch( ... ) - { - st1_.emplace( mp11::mp_size_t() ); - ix_ = K+1; - - throw; - } - } - - template void emplace_impl( mp11::mp_int<2>, A&&... a ) - { static_assert( std::is_nothrow_move_constructible::value, "Logic error: U must be nothrow move constructible" ); U tmp( std::forward(a)... ); @@ -881,17 +823,6 @@ template struct variant_base_impl st1_.emplace( mp11::mp_size_t(), std::move(tmp) ); ix_ = J; } - - template void emplace( A&&... a ) - { - size_t const J = I+1; - - using U = mp11::mp_at_c, I>; - - int const D = std::is_nothrow_constructible::value? 0: ( can_be_valueless::value? 1: 2 ); - - this->emplace_impl( mp11::mp_int(), std::forward(a)... ); - } }; // not trivially destructible, double buffered diff --git a/test/variant_valueless.cpp b/test/variant_valueless.cpp index 176c674..d5d18d7 100644 --- a/test/variant_valueless.cpp +++ b/test/variant_valueless.cpp @@ -115,8 +115,8 @@ int main() } catch( std::exception const& ) { - // basic guarantee; X1 is nothrow default-constructible - BOOST_TEST_EQ( v.index(), 1 ); + // strong guarantee + BOOST_TEST_EQ( v.index(), 0 ); } } @@ -132,8 +132,8 @@ int main() } catch( std::exception const& ) { - // basic guarantee; X1 is nothrow default-constructible - BOOST_TEST_EQ( v.index(), 0 ); + // strong guarantee + BOOST_TEST_EQ( v.index(), 1 ); } } @@ -149,8 +149,8 @@ int main() } catch( std::exception const& ) { - // basic guarantee; monostate - BOOST_TEST_EQ( v.index(), 2 ); + // strong guarantee + BOOST_TEST_EQ( v.index(), 0 ); } } @@ -166,8 +166,8 @@ int main() } catch( std::exception const& ) { - // basic guarantee; monostate - BOOST_TEST_EQ( v.index(), 2 ); + // strong guarantee + BOOST_TEST_EQ( v.index(), 1 ); } } @@ -183,8 +183,8 @@ int main() } catch( std::exception const& ) { - // basic guarantee; X1 is nothrow default-constructible - BOOST_TEST_EQ( v.index(), 2 ); + // strong guarantee + BOOST_TEST_EQ( v.index(), 0 ); } } @@ -200,8 +200,8 @@ int main() } catch( std::exception const& ) { - // basic guarantee; monostate - BOOST_TEST_EQ( v.index(), 3 ); + // strong guarantee + BOOST_TEST_EQ( v.index(), 0 ); } } @@ -234,18 +234,8 @@ int main() } catch( std::exception const& ) { - // X3 is not v2d::trivially_move_assignable on libstdc++ 4.x - - if( v2d::is_trivially_move_assignable::value ) - { - // all trivially destructible and move-assignable, no change - BOOST_TEST_EQ( v.index(), 0 ); - } - else - { - // basic guarantee; X1 is nothrow default-constructible - BOOST_TEST_EQ( v.index(), 1 ); - } + // strong guarantee + BOOST_TEST_EQ( v.index(), 0 ); } } @@ -261,18 +251,8 @@ int main() } catch( std::exception const& ) { - // X3 is not v2d::trivially_move_assignable on libstdc++ 4.x - - if( v2d::is_trivially_move_assignable::value ) - { - // all trivially destructible and move-assignable, no change - BOOST_TEST_EQ( v.index(), 0 ); - } - else - { - // basic guarantee; monostate - BOOST_TEST_EQ( v.index(), 2 ); - } + // strong guarantee + BOOST_TEST_EQ( v.index(), 0 ); } }