diff --git a/include/boost/variant2/variant.hpp b/include/boost/variant2/variant.hpp index 5515600..e6c24d2 100644 --- a/include/boost/variant2/variant.hpp +++ b/include/boost/variant2/variant.hpp @@ -651,12 +651,16 @@ template struct variant_base_impl template BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_true, mp11::mp_bool, A&&... a ) { + static_assert( std::is_nothrow_constructible::value, "Logic error: U must be nothrow constructible from A&&" ); + st1_.emplace( mp11::mp_size_t(), std::forward(a)... ); ix_ = J; } template BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_true, A&&... a ) { + static_assert( std::is_nothrow_move_constructible::value, "Logic error: U must be nothrow move constructible" ); + U tmp( std::forward(a)... ); st1_.emplace( mp11::mp_size_t(), std::move(tmp) ); @@ -665,34 +669,24 @@ template struct variant_base_impl template void emplace_impl( mp11::mp_false, mp11::mp_false, A&&... a ) { - if( can_be_valueless::value ) + 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 { - std::size_t const K = valueless_index::value; - - assert( K < sizeof...(T) ); - - try - { - st1_.emplace( mp11::mp_size_t(), std::forward(a)... ); - ix_ = J; - } - catch( ... ) - { - st1_.emplace( mp11::mp_size_t() ); - ix_ = K+1; - - throw; - } - } - else - { - assert( std::is_nothrow_move_constructible::value ); - - U tmp( std::forward(a)... ); - - st1_.emplace( mp11::mp_size_t(), std::move(tmp) ); + 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 ) @@ -700,7 +694,10 @@ template struct variant_base_impl std::size_t const J = I+1; using U = mp11::mp_at_c, I>; - this->emplace_impl( std::is_nothrow_constructible(), mp11::mp_all, detail::is_trivially_move_assignable...>(), std::forward(a)... ); + 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)... ); } }; diff --git a/test/variant_emplace_type.cpp b/test/variant_emplace_type.cpp index 4189bbb..d7d86ee 100644 --- a/test/variant_emplace_type.cpp +++ b/test/variant_emplace_type.cpp @@ -57,6 +57,16 @@ STATIC_ASSERT( !std::is_nothrow_move_constructible::value ); STATIC_ASSERT( !std::is_nothrow_copy_assignable::value ); STATIC_ASSERT( !std::is_nothrow_move_assignable::value ); +struct Y1 +{ +}; + +struct Guard +{ + explicit Guard(int) {} + Guard(Guard&&) = delete; +}; + int main() { { @@ -165,5 +175,10 @@ int main() BOOST_TEST_EQ( get<0>(v).v, 4 ); } + { + variant v; + v.emplace( 1 ); + } + return boost::report_errors(); }