Fix exception safety issue in copy/move/converting constructor

This commit is contained in:
Peter Dimov
2019-02-26 15:12:37 +02:00
parent 9d7a44761b
commit 30d974d0fc

View File

@ -608,6 +608,13 @@ template<class... T> struct variant_base_impl<true, true, T...>
{
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
{
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
ix_ = I::value + 1;
}
constexpr std::size_t index() const noexcept
{
return ix_ - 1;
@ -700,6 +707,13 @@ template<class... T> struct variant_base_impl<true, false, T...>
{
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
{
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
ix_ = I::value + 1;
}
constexpr std::size_t index() const noexcept
{
return ix_ >= 0? ix_ - 1: -ix_ - 1;
@ -755,6 +769,13 @@ template<class... T> struct variant_base_impl<false, true, T...>
{
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
{
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
ix_ = I::value + 1;
}
//[&]( auto I ){
// using U = mp_at_c<mp_list<none, T...>, I>;
// st1_.get( I ).~U();
@ -869,6 +890,13 @@ template<class... T> struct variant_base_impl<false, false, T...>
{
}
// requires: ix_ == 0
template<class I, class... A> void _replace( I, A&&... a )
{
::new( &st1_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
ix_ = I::value + 1;
}
//[&]( auto I ){
// using U = mp_at_c<mp_list<none, T...>, I>;
// st1_.get( I ).~U();
@ -1090,7 +1118,7 @@ private:
template<class I> void operator()( I i ) const
{
::new( static_cast<void*>( this_ ) ) variant_base( i, r._get_impl( i ) );
this_->_replace( i, r._get_impl( i ) );
}
};
@ -1123,7 +1151,7 @@ private:
template<class I> void operator()( I i ) const
{
::new( static_cast<void*>( this_ ) ) variant_base( i, std::move( r._get_impl( i ) ) );
this_->_replace( i, std::move( r._get_impl( i ) ) );
}
};
@ -1369,7 +1397,7 @@ private:
template<class I> void operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<T...>, mp11::mp_at<mp11::mp_list<U...>, I>>;
::new( static_cast<void*>(this_) ) variant_base( J{}, r._get_impl( i ) );
this_->_replace( J{}, r._get_impl( i ) );
}
};
@ -1393,7 +1421,7 @@ private:
template<class I> void operator()( I i ) const
{
using J = mp11::mp_find<mp11::mp_list<T...>, mp11::mp_at<mp11::mp_list<U...>, I>>;
::new( static_cast<void*>(this_) ) variant_base( J{}, std::move( r._get_impl( i ) ) );
this_->_replace( J{}, std::move( r._get_impl( i ) ) );
}
};