Do not trivially copy/move assign when not trivially copy/move constructible

This commit is contained in:
Peter Dimov
2019-03-03 05:14:51 +02:00
parent 30d974d0fc
commit fdfe9df167
4 changed files with 109 additions and 4 deletions

View File

@ -1201,7 +1201,7 @@ public:
// assignment
template<class E1 = void,
class E2 = mp11::mp_if<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_copy_assignable<T>...>, E1>
class E2 = mp11::mp_if<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_copy_constructible<T>..., detail::is_trivially_copy_assignable<T>...>, E1>
>
BOOST_CXX14_CONSTEXPR variant& operator=( variant const & r ) noexcept
{
@ -1232,7 +1232,7 @@ private:
public:
template<class E1 = void,
class E2 = mp11::mp_if<mp11::mp_not<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_copy_assignable<T>...>>, E1>,
class E2 = mp11::mp_if<mp11::mp_not<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_copy_constructible<T>..., detail::is_trivially_copy_assignable<T>...>>, E1>,
class E3 = mp11::mp_if<mp11::mp_all<std::is_copy_constructible<T>..., std::is_copy_assignable<T>...>, E1>
>
BOOST_CXX14_CONSTEXPR variant& operator=( variant const & r )
@ -1243,7 +1243,7 @@ public:
}
template<class E1 = void,
class E2 = mp11::mp_if<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_move_assignable<T>...>, E1>
class E2 = mp11::mp_if<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_move_constructible<T>..., detail::is_trivially_move_assignable<T>...>, E1>
>
BOOST_CXX14_CONSTEXPR variant& operator=( variant && r ) noexcept
{
@ -1274,7 +1274,7 @@ private:
public:
template<class E1 = void,
class E2 = mp11::mp_if<mp11::mp_not<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_move_assignable<T>...>>, E1>,
class E2 = mp11::mp_if<mp11::mp_not<mp11::mp_all<std::is_trivially_destructible<T>..., detail::is_trivially_move_constructible<T>..., detail::is_trivially_move_assignable<T>...>>, E1>,
class E3 = mp11::mp_if<mp11::mp_all<std::is_move_constructible<T>..., std::is_move_assignable<T>...>, E1>
>
variant& operator=( variant && r )

View File

@ -68,3 +68,6 @@ run variant_valueless.cpp ;
run variant_copy_construct_throw.cpp ;
run variant_move_construct_throw.cpp ;
run variant_convert_construct_throw.cpp ;
run variant_copy_assign_throw.cpp ;
run variant_move_assign_throw.cpp ;

View File

@ -0,0 +1,51 @@
// Copyright 2019 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/core/lightweight_test.hpp>
#include <stdexcept>
using namespace boost::variant2;
struct Y1
{
Y1(){} // =default fails on msvc-14.0
Y1(Y1 const&)
{
throw std::runtime_error( "Y1(Y1 const&)" );
}
Y1& operator=(Y1 const&) = default;
};
struct Y2
{
Y2(){}
Y2(Y2 const&)
{
throw std::runtime_error( "Y2(Y2 const&)" );
}
Y2& operator=(Y2 const&) = default;
};
void test()
{
variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
BOOST_TEST_THROWS( v1 = v2, std::runtime_error )
}
int main()
{
test();
return boost::report_errors();
}

View File

@ -0,0 +1,51 @@
// Copyright 2019 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/variant2/variant.hpp>
#include <boost/core/lightweight_test.hpp>
#include <stdexcept>
using namespace boost::variant2;
struct Y1
{
Y1(){} // =default fails on msvc-14.0
Y1(Y1&&)
{
throw std::runtime_error( "Y1(Y1&&)" );
}
Y1& operator=(Y1&&) = default;
};
struct Y2
{
Y2(){}
Y2(Y2&&)
{
throw std::runtime_error( "Y2(Y2&&)" );
}
Y2& operator=(Y2&&) = default;
};
void test()
{
variant<Y1, Y2> v1( in_place_type_t<Y1>{} );
variant<Y1, Y2> v2( in_place_type_t<Y2>{} );
BOOST_TEST_THROWS( v1 = std::move( v2 ), std::runtime_error )
}
int main()
{
test();
return boost::report_errors();
}