Compare commits

...

5 Commits

4 changed files with 165 additions and 67 deletions

View File

@@ -1346,7 +1346,7 @@ and <code>U</code> occurs exactly once in <code>T&#8230;&#8203;</code>.</p>
<dl>
<dt class="hdlist1">Requires: </dt>
<dd>
<p><code>I &lt; sizeof(T&#8230;&#8203;)</code>.</p>
<p><code>I &lt; sizeof&#8230;&#8203;(T)</code>.</p>
</dd>
<dt class="hdlist1">Effects: </dt>
<dd>
@@ -1361,6 +1361,30 @@ value as if using the expression <code>Ti(std::forward&lt;A&gt;(a)&#8230;&#8203;
<dd>
<p>A reference to the new contained value.</p>
</dd>
<dt class="hdlist1">Throws: </dt>
<dd>
<p>Nothing unless the initialization of the new contained value throws.</p>
</dd>
<dt class="hdlist1">Exception Safety: </dt>
<dd>
<p>On exception:</p>
<div class="ulist">
<ul>
<li>
<p>If the list of alternatives contains <code>monostate</code>, the contained value
is either unchanged, or <code>monostate{}</code>;</p>
</li>
<li>
<p>Otherwise, if the list of alternatives contains types for which
<code>is_nothrow_default_constructible_v</code> is <code>true</code>, the contained value
is either unchanged, or <code>Tj{}</code>, where <code>Tj</code> is the first such alternative;</p>
</li>
<li>
<p>Otherwise, the contained value is unchanged.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>This function shall not participate in overload resolution unless
@@ -1386,7 +1410,7 @@ value as if using the expression <code>Ti(std::forward&lt;A&gt;(a)&#8230;&#8203;
<dl>
<dt class="hdlist1">Requires: </dt>
<dd>
<p><code>I &lt; sizeof(T&#8230;&#8203;)</code>.</p>
<p><code>I &lt; sizeof&#8230;&#8203;(T)</code>.</p>
</dd>
<dt class="hdlist1">Effects: </dt>
<dd>
@@ -1401,6 +1425,30 @@ value as if using the expression <code>Ti(il, std::forward&lt;A&gt;(a)&#8230;&#8
<dd>
<p>A reference to the new contained value.</p>
</dd>
<dt class="hdlist1">Throws: </dt>
<dd>
<p>Nothing unless the initialization of the new contained value throws.</p>
</dd>
<dt class="hdlist1">Exception Safety: </dt>
<dd>
<p>On exception:</p>
<div class="ulist">
<ul>
<li>
<p>If the list of alternatives contains <code>monostate</code>, the contained value
is either unchanged, or <code>monostate{}</code>;</p>
</li>
<li>
<p>Otherwise, if the list of alternatives contains types for which
<code>is_nothrow_default_constructible_v</code> is <code>true</code>, the contained value
is either unchanged, or <code>Tj{}</code>, where <code>Tj</code> is the first such alternative;</p>
</li>
<li>
<p>Otherwise, the contained value is unchanged.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>This function shall not participate in overload resolution unless
@@ -2141,7 +2189,7 @@ the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Versi
</div>
<div id="footer">
<div id="footer-text">
Last updated 2019-02-22 19:16:54 GTBST
Last updated 2019-02-22 19:21:28 GTBST
</div>
</div>
<style>

View File

@@ -502,6 +502,15 @@ Effects: ::
value as if using the expression `Ti(std::forward<A>(a)...)`.
Ensures: :: `index() == I`.
Returns: :: A reference to the new contained value.
Throws: ::
Nothing unless the initialization of the new contained value throws.
Exception Safety: :: On exception:
- If the list of alternatives contains `monostate`, the contained value
is either unchanged, or `monostate{}`;
- Otherwise, if the list of alternatives contains types for which
`is_nothrow_default_constructible_v` is `true`, the contained value
is either unchanged, or `Tj{}`, where `Tj` is the first such alternative;
- Otherwise, the contained value is unchanged.
Remarks: ::
This function shall not participate in overload resolution unless
`std::is_constructible_v<Ti, A...>` is `true`.
@@ -520,6 +529,15 @@ Effects: ::
value as if using the expression `Ti(il, std::forward<A>(a)...)`.
Ensures: :: `index() == I`.
Returns: :: A reference to the new contained value.
Throws: ::
Nothing unless the initialization of the new contained value throws.
Exception Safety: :: On exception:
- If the list of alternatives contains `monostate`, the contained value
is either unchanged, or `monostate{}`;
- Otherwise, if the list of alternatives contains types for which
`is_nothrow_default_constructible_v` is `true`, the contained value
is either unchanged, or `Tj{}`, where `Tj` is the first such alternative;
- Otherwise, the contained value is unchanged.
Remarks: ::
This function shall not participate in overload resolution unless
`std::is_constructible_v<Ti, std::initializer_list<V>&, A...>` is `true`.

View File

@@ -651,12 +651,16 @@ template<class... T> struct variant_base_impl<true, true, T...>
template<std::size_t J, class U, bool B, class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_true, mp11::mp_bool<B>, 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)... );
ix_ = J;
}
template<std::size_t J, class U, class... A> BOOST_CXX14_CONSTEXPR void emplace_impl( mp11::mp_false, mp11::mp_true, A&&... a )
{
static_assert( std::is_nothrow_move_constructible<U>::value, "Logic error: U must be nothrow move constructible" );
U tmp( std::forward<A>(a)... );
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
@@ -665,34 +669,24 @@ template<class... T> struct variant_base_impl<true, true, T...>
template<std::size_t J, class U, class... A> void emplace_impl( mp11::mp_false, mp11::mp_false, A&&... a )
{
if( can_be_valueless<T...>::value )
static_assert( can_be_valueless<T...>::value, "Logic error: T... must have a fallback type" );
std::size_t const K = valueless_index<T...>::value;
static_assert( K < sizeof...(T), "Logic error: T... must have a fallback index" );
try
{
std::size_t const K = valueless_index<T...>::value;
assert( K < sizeof...(T) );
try
{
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J;
}
catch( ... )
{
st1_.emplace( mp11::mp_size_t<K+1>() );
ix_ = K+1;
throw;
}
}
else
{
assert( std::is_nothrow_move_constructible<U>::value );
U tmp( std::forward<A>(a)... );
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J;
}
catch( ... )
{
st1_.emplace( mp11::mp_size_t<K+1>() );
ix_ = K+1;
throw;
}
}
template<std::size_t I, class... A> BOOST_CXX14_CONSTEXPR void emplace( A&&... a )
@@ -700,7 +694,10 @@ template<class... T> struct variant_base_impl<true, true, T...>
std::size_t const J = I+1;
using U = mp11::mp_at_c<variant<T...>, I>;
this->emplace_impl<J, U>( std::is_nothrow_constructible<U, A&&...>(), mp11::mp_all<detail::is_trivially_move_constructible<U>, detail::is_trivially_move_assignable<T>...>(), std::forward<A>(a)... );
constexpr bool B1 = can_be_valueless<T...>::value;
constexpr bool B2 = mp11::mp_all<detail::is_trivially_move_constructible<U>, detail::is_trivially_move_assignable<T>...>::value;
this->emplace_impl<J, U>( std::is_nothrow_constructible<U, A&&...>(), mp11::mp_bool<B2 || !B1>(), std::forward<A>(a)... );
}
};
@@ -839,51 +836,61 @@ template<class... T> struct variant_base_impl<false, true, T...>
return st1_.get( mp11::mp_size_t<I+1>() );
}
template<std::size_t J, class U, class... A> void emplace_impl( mp11::mp_int<0>, A&&... a )
{
static_assert( std::is_nothrow_constructible<U, A&&...>::value, "Logic error: U must be nothrow constructible from A&&..." );
_destroy();
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J;
}
template<std::size_t J, class U, class... A> void emplace_impl( mp11::mp_int<1>, A&&... a )
{
static_assert( can_be_valueless<T...>::value, "Logic error: T... must have a fallback type" );
std::size_t const K = valueless_index<T...>::value;
static_assert( K < sizeof...(T), "Logic error: T... must have a fallback index" );
_destroy();
try
{
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J;
}
catch( ... )
{
st1_.emplace( mp11::mp_size_t<K+1>() );
ix_ = K+1;
throw;
}
}
template<std::size_t J, class U, class... A> void emplace_impl( mp11::mp_int<2>, A&&... a )
{
static_assert( std::is_nothrow_move_constructible<U>::value, "Logic error: U must be nothrow move constructible" );
U tmp( std::forward<A>(a)... );
_destroy();
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
ix_ = J;
}
template<std::size_t I, class... A> void emplace( A&&... a )
{
size_t const J = I+1;
using U = mp11::mp_at_c<variant<T...>, I>;
if( std::is_nothrow_constructible<U, A...>::value )
{
_destroy();
int const D = std::is_nothrow_constructible<U, A&&...>::value? 0: ( can_be_valueless<T...>::value? 1: 2 );
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J;
}
else if( can_be_valueless<T...>::value )
{
std::size_t const K = valueless_index<T...>::value;
assert( K < sizeof...(T) );
_destroy();
try
{
st1_.emplace( mp11::mp_size_t<J>(), std::forward<A>(a)... );
ix_ = J;
}
catch( ... )
{
st1_.emplace( mp11::mp_size_t<K+1>() );
ix_ = K+1;
throw;
}
}
else
{
assert( std::is_nothrow_move_constructible<U>::value );
U tmp( std::forward<A>(a)... );
_destroy();
st1_.emplace( mp11::mp_size_t<J>(), std::move(tmp) );
ix_ = J;
}
this->emplace_impl<J, U>( mp11::mp_int<D>(), std::forward<A>(a)... );
}
};

View File

@@ -57,6 +57,21 @@ STATIC_ASSERT( !std::is_nothrow_move_constructible<X2>::value );
STATIC_ASSERT( !std::is_nothrow_copy_assignable<X2>::value );
STATIC_ASSERT( !std::is_nothrow_move_assignable<X2>::value );
struct Y1
{
};
struct Y2
{
~Y2() {}
};
struct Guard
{
explicit Guard(int) {}
Guard(Guard&&) = delete;
};
int main()
{
{
@@ -165,5 +180,15 @@ int main()
BOOST_TEST_EQ( get<0>(v).v, 4 );
}
{
variant<Y1, Guard> v;
v.emplace<Guard>( 1 );
}
{
variant<Y2, Guard> v;
v.emplace<Guard>( 1 );
}
return boost::report_errors();
}