|
|
|
@ -81,6 +81,8 @@ struct monostate
|
|
|
|
|
{
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1940)
|
|
|
|
|
|
|
|
|
|
constexpr bool operator<(monostate, monostate) noexcept { return false; }
|
|
|
|
|
constexpr bool operator>(monostate, monostate) noexcept { return false; }
|
|
|
|
|
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
|
|
|
|
@ -88,6 +90,17 @@ constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
|
|
|
|
constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
|
|
|
|
constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
constexpr bool operator<(monostate const&, monostate const&) noexcept { return false; }
|
|
|
|
|
constexpr bool operator>(monostate const&, monostate const&) noexcept { return false; }
|
|
|
|
|
constexpr bool operator<=(monostate const&, monostate const&) noexcept { return true; }
|
|
|
|
|
constexpr bool operator>=(monostate const&, monostate const&) noexcept { return true; }
|
|
|
|
|
constexpr bool operator==(monostate const&, monostate const&) noexcept { return true; }
|
|
|
|
|
constexpr bool operator!=(monostate const&, monostate const&) noexcept { return false; }
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// variant forward declaration
|
|
|
|
|
|
|
|
|
|
template<class... T> class variant;
|
|
|
|
@ -520,11 +533,11 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_false, T1, T.
|
|
|
|
|
T1 first_;
|
|
|
|
|
variant_storage<T...> rest_;
|
|
|
|
|
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
|
|
|
|
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -564,18 +577,18 @@ template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, c
|
|
|
|
|
|
|
|
|
|
variant_storage<T...> rest_;
|
|
|
|
|
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
|
|
|
|
|
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
|
|
|
|
|
|
|
|
|
|
~variant_storage_impl()
|
|
|
|
|
{
|
|
|
|
@ -637,11 +650,11 @@ template<class T1, class... T> union variant_storage_impl<mp11::mp_true, T1, T..
|
|
|
|
|
T1 first_;
|
|
|
|
|
variant_storage<T...> rest_;
|
|
|
|
|
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): first_( std::forward<A>(a)... )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
|
|
|
|
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-1>(), std::forward<A>(a)... )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -687,18 +700,18 @@ template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, c
|
|
|
|
|
|
|
|
|
|
variant_storage<T...> rest_;
|
|
|
|
|
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<0>, A&&... a ): t0_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<1>, A&&... a ): t1_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<2>, A&&... a ): t2_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<3>, A&&... a ): t3_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<4>, A&&... a ): t4_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<5>, A&&... a ): t5_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<6>, A&&... a ): t6_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<7>, A&&... a ): t7_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<8>, A&&... a ): t8_( std::forward<A>(a)... ) {}
|
|
|
|
|
template<class... A> constexpr variant_storage_impl( mp11::mp_size_t<9>, A&&... a ): t9_( std::forward<A>(a)... ) {}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> constexpr explicit variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
|
|
|
|
|
template<std::size_t I, class... A> constexpr variant_storage_impl( mp11::mp_size_t<I>, A&&... a ): rest_( mp11::mp_size_t<I-10>(), std::forward<A>(a)... ) {}
|
|
|
|
|
|
|
|
|
|
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<0>, A&&... a ) { ::new( &t0_ ) T0( std::forward<A>(a)... ); }
|
|
|
|
|
template<class... A> void emplace_impl( mp11::mp_false, mp11::mp_size_t<1>, A&&... a ) { ::new( &t1_ ) T1( std::forward<A>(a)... ); }
|
|
|
|
@ -814,21 +827,21 @@ struct none {};
|
|
|
|
|
// trivially destructible, single buffered
|
|
|
|
|
template<class... T> struct variant_base_impl<true, true, T...>
|
|
|
|
|
{
|
|
|
|
|
int ix_;
|
|
|
|
|
variant_storage<none, T...> st1_;
|
|
|
|
|
unsigned ix_;
|
|
|
|
|
variant_storage<none, T...> st_;
|
|
|
|
|
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() )
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st_( mp11::mp_size_t<0>() )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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)... );
|
|
|
|
|
::new( &st_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = I::value + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -843,7 +856,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
|
|
|
|
|
|
|
|
|
assert( ix_ == J );
|
|
|
|
|
|
|
|
|
|
return st1_.get( mp11::mp_size_t<J>() );
|
|
|
|
|
return st_.get( mp11::mp_size_t<J>() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
|
|
|
@ -851,14 +864,14 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
|
|
|
|
// size_t const J = I+1;
|
|
|
|
|
// assert( ix_ == I+1 );
|
|
|
|
|
|
|
|
|
|
return st1_.get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
return st_.get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t J, class U, class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_true, A&&... a )
|
|
|
|
|
{
|
|
|
|
|
static_assert( std::is_nothrow_constructible<U, A&&...>::value, "Logic error: U must be nothrow constructible from A&&..." );
|
|
|
|
|
|
|
|
|
|
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
st_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = J;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -868,7 +881,7 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
|
|
|
|
|
|
|
|
|
U tmp( std::forward<A>(a)... );
|
|
|
|
|
|
|
|
|
|
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
|
|
|
|
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
|
|
|
|
ix_ = J;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -884,84 +897,78 @@ template<class... T> struct variant_base_impl<true, true, T...>
|
|
|
|
|
// trivially destructible, double buffered
|
|
|
|
|
template<class... T> struct variant_base_impl<true, false, T...>
|
|
|
|
|
{
|
|
|
|
|
int ix_;
|
|
|
|
|
variant_storage<none, T...> st1_;
|
|
|
|
|
variant_storage<none, T...> st2_;
|
|
|
|
|
unsigned ix_;
|
|
|
|
|
variant_storage<none, T...> st_[ 2 ];
|
|
|
|
|
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() ), st2_( mp11::mp_size_t<0>() )
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... ), st2_( mp11::mp_size_t<0>() )
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( ( I::value + 1 ) * 2 ), st_{ { mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... }, { mp11::mp_size_t<0>() } }
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
::new( &st_[ 0 ] ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = ( I::value + 1 ) * 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constexpr std::size_t index() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ix_ >= 0? ix_ - 1: -ix_ - 1;
|
|
|
|
|
return ix_ / 2 - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I> BOOST_CXX14_CONSTEXPR mp11::mp_at_c<variant<T...>, I>& _get_impl( mp11::mp_size_t<I> ) noexcept
|
|
|
|
|
{
|
|
|
|
|
assert( index() == I );
|
|
|
|
|
|
|
|
|
|
size_t const J = I+1;
|
|
|
|
|
|
|
|
|
|
assert( ix_ == J || -ix_ == J );
|
|
|
|
|
|
|
|
|
|
constexpr mp11::mp_size_t<J> j{};
|
|
|
|
|
return ix_ >= 0? st1_.get( j ): st2_.get( j );
|
|
|
|
|
return st_[ ix_ & 1 ].get( j );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
// assert( index() == I );
|
|
|
|
|
// size_t const J = I+1;
|
|
|
|
|
// assert( ix_ == J || -ix_ == J );
|
|
|
|
|
// constexpr mp_size_t<J> j{};
|
|
|
|
|
|
|
|
|
|
return ix_ >= 0? st1_.get( mp11::mp_size_t<I+1>() ): st2_.get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
return st_[ ix_ & 1 ].get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( A&&... a )
|
|
|
|
|
{
|
|
|
|
|
size_t const J = I+1;
|
|
|
|
|
|
|
|
|
|
if( ix_ >= 0 )
|
|
|
|
|
{
|
|
|
|
|
st2_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = -static_cast<int>( J );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = J;
|
|
|
|
|
}
|
|
|
|
|
unsigned i2 = 1 - ( ix_ & 1 );
|
|
|
|
|
|
|
|
|
|
st_[ i2 ].emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
|
|
|
|
|
ix_ = J * 2 + i2;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// not trivially destructible, single buffered
|
|
|
|
|
template<class... T> struct variant_base_impl<false, true, T...>
|
|
|
|
|
{
|
|
|
|
|
int ix_;
|
|
|
|
|
variant_storage<none, T...> st1_;
|
|
|
|
|
unsigned ix_;
|
|
|
|
|
variant_storage<none, T...> st_;
|
|
|
|
|
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() )
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st_( mp11::mp_size_t<0>() )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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)... );
|
|
|
|
|
::new( &st_ ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = I::value + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -977,7 +984,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
|
|
|
|
template<class I> void operator()( I ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
|
|
|
|
this_->st1_.get( I() ).~U();
|
|
|
|
|
this_->st_.get( I() ).~U();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -1005,7 +1012,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
|
|
|
|
|
|
|
|
|
assert( ix_ == J );
|
|
|
|
|
|
|
|
|
|
return st1_.get( mp11::mp_size_t<J>() );
|
|
|
|
|
return st_.get( mp11::mp_size_t<J>() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
|
|
|
@ -1013,7 +1020,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
|
|
|
|
// size_t const J = I+1;
|
|
|
|
|
// assert( ix_ == J );
|
|
|
|
|
|
|
|
|
|
return st1_.get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
return st_.get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> void emplace( A&&... a )
|
|
|
|
@ -1028,7 +1035,7 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
|
|
|
|
|
|
|
|
|
_destroy();
|
|
|
|
|
|
|
|
|
|
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
|
|
|
|
st_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
|
|
|
|
|
ix_ = J;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
@ -1036,23 +1043,61 @@ template<class... T> struct variant_base_impl<false, true, T...>
|
|
|
|
|
// not trivially destructible, double buffered
|
|
|
|
|
template<class... T> struct variant_base_impl<false, false, T...>
|
|
|
|
|
{
|
|
|
|
|
int ix_;
|
|
|
|
|
variant_storage<none, T...> st1_;
|
|
|
|
|
variant_storage<none, T...> st2_;
|
|
|
|
|
unsigned ix_;
|
|
|
|
|
|
|
|
|
|
#if defined(__GNUC__) && __GNUC__ < 11 && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
|
|
|
|
|
|
|
|
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63707 :-(
|
|
|
|
|
|
|
|
|
|
variant_storage<none, T...> st1_, st2_;
|
|
|
|
|
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st1_( mp11::mp_size_t<0>() ), st2_( mp11::mp_size_t<0>() )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( I::value + 1 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... ), st2_( mp11::mp_size_t<0>() )
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( ( I::value + 1 ) * 2 ), st1_( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... ), st2_( mp11::mp_size_t<0>() )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_CXX14_CONSTEXPR variant_storage<none, T...>& storage( unsigned i2 ) noexcept
|
|
|
|
|
{
|
|
|
|
|
return i2 == 0? st1_: st2_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constexpr variant_storage<none, T...> const& storage( unsigned i2 ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return i2 == 0? st1_: st2_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
variant_storage<none, T...> st_[ 2 ];
|
|
|
|
|
|
|
|
|
|
constexpr variant_base_impl(): ix_( 0 ), st_{ { mp11::mp_size_t<0>() }, { mp11::mp_size_t<0>() } }
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class I, class... A> constexpr explicit variant_base_impl( I, A&&... a ): ix_( ( I::value + 1 ) * 2 ), st_{ { mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... }, { mp11::mp_size_t<0>() } }
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_CXX14_CONSTEXPR variant_storage<none, T...>& storage( unsigned i2 ) noexcept
|
|
|
|
|
{
|
|
|
|
|
return st_[ i2 ];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constexpr variant_storage<none, T...> const& storage( unsigned i2 ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
return st_[ i2 ];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
::new( &storage( 0 ) ) variant_storage<none, T...>( mp11::mp_size_t<I::value + 1>(), std::forward<A>(a)... );
|
|
|
|
|
ix_ = ( I::value + 1 ) * 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//[&]( auto I ){
|
|
|
|
@ -1063,35 +1108,18 @@ template<class... T> struct variant_base_impl<false, false, T...>
|
|
|
|
|
struct _destroy_L1
|
|
|
|
|
{
|
|
|
|
|
variant_base_impl * this_;
|
|
|
|
|
unsigned i2_;
|
|
|
|
|
|
|
|
|
|
template<class I> void operator()( I ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
|
|
|
|
this_->st1_.get( I() ).~U();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _destroy_L2
|
|
|
|
|
{
|
|
|
|
|
variant_base_impl * this_;
|
|
|
|
|
|
|
|
|
|
template<class I> void operator()( I ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
using U = mp11::mp_at<mp11::mp_list<none, T...>, I>;
|
|
|
|
|
this_->st2_.get( I() ).~U();
|
|
|
|
|
this_->storage( i2_ ).get( I() ).~U();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void _destroy() noexcept
|
|
|
|
|
{
|
|
|
|
|
if( ix_ > 0 )
|
|
|
|
|
{
|
|
|
|
|
mp11::mp_with_index<1 + sizeof...(T)>( ix_, _destroy_L1{ this } );
|
|
|
|
|
}
|
|
|
|
|
else if( ix_ < 0 )
|
|
|
|
|
{
|
|
|
|
|
mp11::mp_with_index<1 + sizeof...(T)>( -ix_, _destroy_L2{ this } );
|
|
|
|
|
}
|
|
|
|
|
mp11::mp_with_index<1 + sizeof...(T)>( ix_ / 2, _destroy_L1{ this, ix_ & 1 } );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~variant_base_impl() noexcept
|
|
|
|
@ -1101,46 +1129,38 @@ template<class... T> struct variant_base_impl<false, false, T...>
|
|
|
|
|
|
|
|
|
|
constexpr std::size_t index() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return ix_ >= 0? ix_ - 1: -ix_ - 1;
|
|
|
|
|
return ix_ / 2 - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I> BOOST_CXX14_CONSTEXPR mp11::mp_at_c<variant<T...>, I>& _get_impl( mp11::mp_size_t<I> ) noexcept
|
|
|
|
|
{
|
|
|
|
|
assert( index() == I );
|
|
|
|
|
|
|
|
|
|
size_t const J = I+1;
|
|
|
|
|
|
|
|
|
|
assert( ix_ == J || -ix_ == J );
|
|
|
|
|
|
|
|
|
|
constexpr mp11::mp_size_t<J> j{};
|
|
|
|
|
return ix_ >= 0? st1_.get( j ): st2_.get( j );
|
|
|
|
|
return storage( ix_ & 1 ).get( j );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I> constexpr mp11::mp_at_c<variant<T...>, I> const& _get_impl( mp11::mp_size_t<I> ) const noexcept
|
|
|
|
|
{
|
|
|
|
|
// assert( index() == I );
|
|
|
|
|
// size_t const J = I+1;
|
|
|
|
|
// assert( ix_ == J || -ix_ == J );
|
|
|
|
|
// constexpr mp_size_t<J> j{};
|
|
|
|
|
|
|
|
|
|
return ix_ >= 0? st1_.get( mp11::mp_size_t<I+1>() ): st2_.get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
return storage( ix_ & 1 ).get( mp11::mp_size_t<I+1>() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t I, class... A> void emplace( A&&... a )
|
|
|
|
|
{
|
|
|
|
|
size_t const J = I+1;
|
|
|
|
|
|
|
|
|
|
if( ix_ >= 0 )
|
|
|
|
|
{
|
|
|
|
|
st2_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
_destroy();
|
|
|
|
|
unsigned i2 = 1 - ( ix_ & 1 );
|
|
|
|
|
|
|
|
|
|
ix_ = -static_cast<int>( J );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
_destroy();
|
|
|
|
|
storage( i2 ).emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
|
|
|
|
|
_destroy();
|
|
|
|
|
|
|
|
|
|
ix_ = J;
|
|
|
|
|
}
|
|
|
|
|
ix_ = J * 2 + i2;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -2085,7 +2105,7 @@ template<class R, class F, class V1, class V2> struct visit_L2
|
|
|
|
|
template<class I> auto operator()( I ) const -> Vret<R, F, V1, V2>
|
|
|
|
|
{
|
|
|
|
|
auto f2 = bind_front( std::forward<F>(f), unsafe_get<I::value>( std::forward<V1>(v1) ) );
|
|
|
|
|
return visit<R>( f2, std::forward<V2>(v2) );
|
|
|
|
|
return visit<R>( f2, std::forward<V2>(v2) );
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|