mirror of
https://github.com/boostorg/variant2.git
synced 2025-12-24 07:38:06 +01:00
Compare commits
12 Commits
pre-review
...
feature/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70fbd17be9 | ||
|
|
e8e56139a8 | ||
|
|
2d6385031e | ||
|
|
9f7e525984 | ||
|
|
2e8ae0c796 | ||
|
|
89986c7634 | ||
|
|
1da3892239 | ||
|
|
3808c9b122 | ||
|
|
f1b1e7cade | ||
|
|
6d7be90ce0 | ||
|
|
9875cfdc98 | ||
|
|
688849f9e8 |
@@ -1346,7 +1346,7 @@ and <code>U</code> occurs exactly once in <code>T…​</code>.</p>
|
||||
<dl>
|
||||
<dt class="hdlist1">Requires: </dt>
|
||||
<dd>
|
||||
<p><code>I < sizeof(T…​)</code>.</p>
|
||||
<p><code>I < sizeof…​(T)</code>.</p>
|
||||
</dd>
|
||||
<dt class="hdlist1">Effects: </dt>
|
||||
<dd>
|
||||
@@ -1361,6 +1361,30 @@ value as if using the expression <code>Ti(std::forward<A>(a)…​
|
||||
<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<A>(a)…​
|
||||
<dl>
|
||||
<dt class="hdlist1">Requires: </dt>
|
||||
<dd>
|
||||
<p><code>I < sizeof(T…​)</code>.</p>
|
||||
<p><code>I < sizeof…​(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<A>(a)…
|
||||
<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>
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
#ifndef BOOST_VARIANT2_OUTCOME_HPP_INCLUDED
|
||||
#define BOOST_VARIANT2_OUTCOME_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017 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
|
||||
|
||||
#ifndef BOOST_VARIANT2_VARIANT_HPP_INCLUDED
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#endif
|
||||
#include <system_error>
|
||||
#include <exception>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace variant2
|
||||
{
|
||||
|
||||
enum class outcome_errc
|
||||
{
|
||||
not_initialized
|
||||
};
|
||||
|
||||
class outcome_error_category: public std::error_category
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char * name() const noexcept
|
||||
{
|
||||
return "boost::variant2::outcome";
|
||||
}
|
||||
|
||||
virtual std::string message( int e ) const
|
||||
{
|
||||
switch( e )
|
||||
{
|
||||
case (int)outcome_errc::not_initialized:
|
||||
|
||||
return "outcome<> not initialized";
|
||||
|
||||
default:
|
||||
|
||||
return "unknown outcome<> error";
|
||||
}
|
||||
}
|
||||
|
||||
static outcome_error_category const & instance()
|
||||
{
|
||||
static outcome_error_category cat;
|
||||
return cat;
|
||||
}
|
||||
};
|
||||
|
||||
std::error_code make_error_code( outcome_errc e )
|
||||
{
|
||||
return std::error_code( static_cast<int>( e ), outcome_error_category::instance() );
|
||||
}
|
||||
|
||||
template<class T> class outcome
|
||||
{
|
||||
private:
|
||||
|
||||
variant<T, std::error_code, std::exception_ptr> v_;
|
||||
|
||||
public:
|
||||
|
||||
// constructors
|
||||
|
||||
constexpr outcome() noexcept: v_( make_error_code( outcome_errc::not_initialized ) )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr outcome( T const& t ): v_( t )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr outcome( T&& t ): v_( std::move(t) )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr outcome( std::error_code const & ec ) noexcept: v_( ec )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr outcome( std::exception_ptr const & ep ) noexcept: v_( ep )
|
||||
{
|
||||
}
|
||||
|
||||
// queries
|
||||
|
||||
constexpr bool has_value() const noexcept
|
||||
{
|
||||
return v_.index() == 0;
|
||||
}
|
||||
|
||||
constexpr bool has_error() const noexcept
|
||||
{
|
||||
return v_.index() == 1;
|
||||
}
|
||||
|
||||
constexpr bool has_exception() const noexcept
|
||||
{
|
||||
return v_.index() == 2;
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return v_.index() == 0;
|
||||
}
|
||||
|
||||
// checked value access
|
||||
|
||||
constexpr T& value() &
|
||||
{
|
||||
if( has_value() )
|
||||
{
|
||||
return *get_if<0>(&v_);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::system_error( *get_if<1>(&v_) );
|
||||
}
|
||||
}
|
||||
|
||||
constexpr T const& value() const&
|
||||
{
|
||||
if( has_value() )
|
||||
{
|
||||
return *get_if<0>(&v_);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::system_error( *get_if<1>(&v_) );
|
||||
}
|
||||
}
|
||||
|
||||
constexpr T&& value() &&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
|
||||
constexpr T const&& value() const&&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
|
||||
// unchecked value access
|
||||
|
||||
T* operator->() noexcept
|
||||
{
|
||||
return get_if<0>(&v_);
|
||||
}
|
||||
|
||||
T const* operator->() const noexcept
|
||||
{
|
||||
return get_if<0>(&v_);
|
||||
}
|
||||
|
||||
T& operator*() & noexcept
|
||||
{
|
||||
T* p = get_if<0>(&v_);
|
||||
|
||||
assert( p != 0 );
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
T const& operator*() const & noexcept
|
||||
{
|
||||
T const* p = get_if<0>(&v_);
|
||||
|
||||
assert( p != 0 );
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
T&& operator*() && noexcept
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
||||
T const&& operator*() const && noexcept
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
||||
// error access
|
||||
|
||||
/*constexpr*/ std::error_code error() const noexcept
|
||||
{
|
||||
if( has_error() )
|
||||
{
|
||||
return *get_if<1>(&v_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::error_code();
|
||||
}
|
||||
}
|
||||
|
||||
// exception access
|
||||
|
||||
std::exception_ptr exception() const noexcept
|
||||
{
|
||||
if( has_exception() )
|
||||
{
|
||||
return *get_if<2>(&v_);
|
||||
}
|
||||
else if( has_value() )
|
||||
{
|
||||
return std::exception_ptr();
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::make_exception_ptr( std::system_error( *get_if<1>(&v_) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// setters
|
||||
|
||||
void set_value( T const& t ) noexcept( std::is_nothrow_copy_constructible<T>::value )
|
||||
{
|
||||
v_.emplace<0>( t );
|
||||
}
|
||||
|
||||
void set_value( T&& t ) noexcept( std::is_nothrow_move_constructible<T>::value )
|
||||
{
|
||||
v_.emplace<0>( std::move( t ) );
|
||||
}
|
||||
|
||||
void set_error( std::error_code const & e ) noexcept
|
||||
{
|
||||
v_.emplace<1>( e );
|
||||
}
|
||||
|
||||
void set_exception( std::exception_ptr const & x ) noexcept
|
||||
{
|
||||
v_.emplace<2>( x );
|
||||
}
|
||||
|
||||
// swap
|
||||
|
||||
void swap( outcome& r ) noexcept( noexcept( v_.swap( r.v_ ) ) )
|
||||
{
|
||||
v_.swap( r.v_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace variant2
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_VARIANT2_OUTCOME_HPP_INCLUDED
|
||||
@@ -1,226 +0,0 @@
|
||||
#ifndef BOOST_VARIANT2_RESULT_HPP_INCLUDED
|
||||
#define BOOST_VARIANT2_RESULT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017 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
|
||||
|
||||
#ifndef BOOST_VARIANT2_VARIANT_HPP_INCLUDED
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#endif
|
||||
#include <system_error>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace variant2
|
||||
{
|
||||
|
||||
enum class result_errc
|
||||
{
|
||||
not_initialized
|
||||
};
|
||||
|
||||
class result_error_category: public std::error_category
|
||||
{
|
||||
public:
|
||||
|
||||
virtual const char * name() const noexcept
|
||||
{
|
||||
return "boost::variant2::result";
|
||||
}
|
||||
|
||||
virtual std::string message( int e ) const
|
||||
{
|
||||
switch( e )
|
||||
{
|
||||
case (int)result_errc::not_initialized:
|
||||
|
||||
return "result<> not initialized";
|
||||
|
||||
default:
|
||||
|
||||
return "unknown result<> error";
|
||||
}
|
||||
}
|
||||
|
||||
static result_error_category const & instance()
|
||||
{
|
||||
static result_error_category cat;
|
||||
return cat;
|
||||
}
|
||||
};
|
||||
|
||||
std::error_code make_error_code( result_errc e )
|
||||
{
|
||||
return std::error_code( static_cast<int>( e ), result_error_category::instance() );
|
||||
}
|
||||
|
||||
template<class T> class result
|
||||
{
|
||||
private:
|
||||
|
||||
variant<T, std::error_code> v_;
|
||||
|
||||
public:
|
||||
|
||||
// constructors
|
||||
|
||||
constexpr result() noexcept: v_( make_error_code( result_errc::not_initialized ) )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr result( T const& t ): v_( t )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr result( T&& t ): v_( std::move(t) )
|
||||
{
|
||||
}
|
||||
|
||||
constexpr result( std::error_code const & ec ) noexcept: v_( ec )
|
||||
{
|
||||
}
|
||||
|
||||
// queries
|
||||
|
||||
constexpr bool has_value() const noexcept
|
||||
{
|
||||
return v_.index() == 0;
|
||||
}
|
||||
|
||||
constexpr bool has_error() const noexcept
|
||||
{
|
||||
return v_.index() == 1;
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return v_.index() == 0;
|
||||
}
|
||||
|
||||
// checked value access
|
||||
|
||||
constexpr T& value() &
|
||||
{
|
||||
if( has_value() )
|
||||
{
|
||||
return *get_if<0>(&v_);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::system_error( *get_if<1>(&v_) );
|
||||
}
|
||||
}
|
||||
|
||||
constexpr T const& value() const&
|
||||
{
|
||||
if( has_value() )
|
||||
{
|
||||
return *get_if<0>(&v_);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::system_error( *get_if<1>(&v_) );
|
||||
}
|
||||
}
|
||||
|
||||
constexpr T&& value() &&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
|
||||
constexpr T const&& value() const&&
|
||||
{
|
||||
return std::move( value() );
|
||||
}
|
||||
|
||||
// unchecked value access
|
||||
|
||||
T* operator->() noexcept
|
||||
{
|
||||
return get_if<0>(&v_);
|
||||
}
|
||||
|
||||
T const* operator->() const noexcept
|
||||
{
|
||||
return get_if<0>(&v_);
|
||||
}
|
||||
|
||||
T& operator*() & noexcept
|
||||
{
|
||||
T* p = get_if<0>(&v_);
|
||||
|
||||
assert( p != 0 );
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
T const& operator*() const & noexcept
|
||||
{
|
||||
T const* p = get_if<0>(&v_);
|
||||
|
||||
assert( p != 0 );
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
T&& operator*() && noexcept
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
||||
T const&& operator*() const && noexcept
|
||||
{
|
||||
return std::move(**this);
|
||||
}
|
||||
|
||||
// error access
|
||||
|
||||
/*constexpr*/ std::error_code error() const noexcept
|
||||
{
|
||||
if( has_error() )
|
||||
{
|
||||
return *get_if<1>(&v_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::error_code();
|
||||
}
|
||||
}
|
||||
|
||||
// setters
|
||||
|
||||
void set_value( T const& t ) noexcept( std::is_nothrow_copy_constructible<T>::value )
|
||||
{
|
||||
v_.emplace<0>( t );
|
||||
}
|
||||
|
||||
void set_value( T&& t ) noexcept( std::is_nothrow_move_constructible<T>::value )
|
||||
{
|
||||
v_.emplace<0>( std::move( t ) );
|
||||
}
|
||||
|
||||
void set_error( std::error_code const & e ) noexcept
|
||||
{
|
||||
v_.emplace<1>( e );
|
||||
}
|
||||
|
||||
// swap
|
||||
|
||||
void swap( result& r ) noexcept( noexcept( v_.swap( r.v_ ) ) )
|
||||
{
|
||||
v_.swap( r.v_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace variant2
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_VARIANT2_RESULT_HPP_INCLUDED
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef BOOST_VARIANT2_VARIANT_HPP_INCLUDED
|
||||
#define BOOST_VARIANT2_VARIANT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2018 Peter Dimov.
|
||||
// Copyright 2017-2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
@@ -266,6 +266,10 @@ template<std::size_t I, class... T> struct variant_alternative<I, variant<T...>>
|
||||
|
||||
#endif
|
||||
|
||||
// variant_npos
|
||||
|
||||
constexpr std::size_t variant_npos = ~static_cast<std::size_t>( 0 );
|
||||
|
||||
// holds_alternative
|
||||
|
||||
template<class U, class... T> constexpr bool holds_alternative( variant<T...> const& v ) noexcept
|
||||
@@ -286,7 +290,7 @@ template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T
|
||||
{
|
||||
static_assert( I < sizeof...(T), "Index out of bounds" );
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1930)
|
||||
|
||||
return (void)( v.index() != I? throw bad_variant_access(): 0 ), std::move( v._get_impl( mp11::mp_size_t<I>() ) );
|
||||
|
||||
@@ -308,7 +312,7 @@ template<std::size_t I, class... T> constexpr variant_alternative_t<I, variant<T
|
||||
{
|
||||
static_assert( I < sizeof...(T), "Index out of bounds" );
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1930)
|
||||
|
||||
return (void)( v.index() != I? throw bad_variant_access(): 0 ), std::move( v._get_impl( mp11::mp_size_t<I>() ) );
|
||||
|
||||
@@ -368,7 +372,7 @@ template<class U, class... T> constexpr U&& get(variant<T...>&& v)
|
||||
|
||||
using I = mp11::mp_find<variant<T...>, U>;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1930)
|
||||
|
||||
return (void)( v.index() != I::value? throw bad_variant_access(): 0 ), std::move( v._get_impl( I() ) );
|
||||
|
||||
@@ -395,7 +399,7 @@ template<class U, class... T> constexpr U const&& get(variant<T...> const&& v)
|
||||
|
||||
using I = mp11::mp_find<variant<T...>, U>;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1930)
|
||||
|
||||
return (void)( v.index() != I::value? throw bad_variant_access(): 0 ), std::move( v._get_impl( I() ) );
|
||||
|
||||
@@ -574,7 +578,7 @@ template<class T1, class... T> struct overload<T1, T...>: overload<T...>
|
||||
mp11::mp_identity<T1> operator()(T1) const;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND( BOOST_MSVC, < 1920 )
|
||||
#if BOOST_WORKAROUND( BOOST_MSVC, < 1930 )
|
||||
|
||||
template<class U, class... T> using resolve_overload_type_ = decltype( overload<T...>()(std::declval<U>()) );
|
||||
|
||||
@@ -647,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) );
|
||||
@@ -661,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 )
|
||||
@@ -696,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)... );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -835,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)... );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1179,30 +1190,30 @@ public:
|
||||
class Ud = typename std::decay<U>::type,
|
||||
class E1 = typename std::enable_if< !std::is_same<Ud, variant>::value && !detail::is_in_place_index<Ud>::value && !detail::is_in_place_type<Ud>::value >::type,
|
||||
class V = detail::resolve_overload_type<U&&, T...>,
|
||||
class E2 = typename std::enable_if<std::is_constructible<V, U>::value>::type
|
||||
class E2 = typename std::enable_if<std::is_constructible<V, U&&>::value>::type
|
||||
>
|
||||
constexpr variant( U&& u )
|
||||
noexcept( std::is_nothrow_constructible<V, U>::value )
|
||||
noexcept( std::is_nothrow_constructible<V, U&&>::value )
|
||||
: variant_base( detail::resolve_overload_index<U&&, T...>(), std::forward<U>(u) )
|
||||
{
|
||||
}
|
||||
|
||||
template<class U, class... A, class I = mp11::mp_find<variant<T...>, U>, class E = typename std::enable_if<std::is_constructible<U, A...>::value>::type>
|
||||
template<class U, class... A, class I = mp11::mp_find<variant<T...>, U>, class E = typename std::enable_if<std::is_constructible<U, A&&...>::value>::type>
|
||||
constexpr explicit variant( in_place_type_t<U>, A&&... a ): variant_base( I(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
template<class U, class V, class... A, class I = mp11::mp_find<variant<T...>, U>, class E = typename std::enable_if<std::is_constructible<U, std::initializer_list<V>&, A...>::value>::type>
|
||||
template<class U, class V, class... A, class I = mp11::mp_find<variant<T...>, U>, class E = typename std::enable_if<std::is_constructible<U, std::initializer_list<V>&, A&&...>::value>::type>
|
||||
constexpr explicit variant( in_place_type_t<U>, std::initializer_list<V> il, A&&... a ): variant_base( I(), il, std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, A...>::value>::type>
|
||||
template<std::size_t I, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, A&&...>::value>::type>
|
||||
constexpr explicit variant( in_place_index_t<I>, A&&... a ): variant_base( mp11::mp_size_t<I>(), std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
|
||||
template<std::size_t I, class V, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, std::initializer_list<V>&, A...>::value>::type>
|
||||
template<std::size_t I, class V, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, std::initializer_list<V>&, A&&...>::value>::type>
|
||||
constexpr explicit variant( in_place_index_t<I>, std::initializer_list<V> il, A&&... a ): variant_base( mp11::mp_size_t<I>(), il, std::forward<A>(a)... )
|
||||
{
|
||||
}
|
||||
@@ -1295,10 +1306,10 @@ public:
|
||||
template<class U,
|
||||
class E1 = typename std::enable_if<!std::is_same<typename std::decay<U>::type, variant>::value>::type,
|
||||
class V = detail::resolve_overload_type<U, T...>,
|
||||
class E2 = typename std::enable_if<std::is_assignable<V&, U>::value && std::is_constructible<V, U>::value>::type
|
||||
class E2 = typename std::enable_if<std::is_assignable<V&, U&&>::value && std::is_constructible<V, U&&>::value>::type
|
||||
>
|
||||
BOOST_CXX14_CONSTEXPR variant& operator=( U&& u )
|
||||
noexcept( std::is_nothrow_assignable<V&, U>::value && std::is_nothrow_constructible<V, U>::value )
|
||||
noexcept( std::is_nothrow_assignable<V&, U&&>::value && std::is_nothrow_constructible<V, U&&>::value )
|
||||
{
|
||||
std::size_t const I = detail::resolve_overload_index<U, T...>::value;
|
||||
|
||||
@@ -1317,7 +1328,7 @@ public:
|
||||
// modifiers
|
||||
|
||||
template<class U, class... A,
|
||||
class E = typename std::enable_if< mp11::mp_count<variant<T...>, U>::value == 1 && std::is_constructible<U, A...>::value >::type>
|
||||
class E = typename std::enable_if< mp11::mp_count<variant<T...>, U>::value == 1 && std::is_constructible<U, A&&...>::value >::type>
|
||||
BOOST_CXX14_CONSTEXPR U& emplace( A&&... a )
|
||||
{
|
||||
using I = mp11::mp_find<variant<T...>, U>;
|
||||
@@ -1326,7 +1337,7 @@ public:
|
||||
}
|
||||
|
||||
template<class U, class V, class... A,
|
||||
class E = typename std::enable_if< mp11::mp_count<variant<T...>, U>::value == 1 && std::is_constructible<U, std::initializer_list<V>&, A...>::value >::type>
|
||||
class E = typename std::enable_if< mp11::mp_count<variant<T...>, U>::value == 1 && std::is_constructible<U, std::initializer_list<V>&, A&&...>::value >::type>
|
||||
BOOST_CXX14_CONSTEXPR U& emplace( std::initializer_list<V> il, A&&... a )
|
||||
{
|
||||
using I = mp11::mp_find<variant<T...>, U>;
|
||||
@@ -1334,14 +1345,14 @@ public:
|
||||
return _get_impl( I() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, A...>::value>::type>
|
||||
template<std::size_t I, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, A&&...>::value>::type>
|
||||
BOOST_CXX14_CONSTEXPR variant_alternative_t<I, variant<T...>>& emplace( A&&... a )
|
||||
{
|
||||
variant_base::template emplace<I>( std::forward<A>(a)... );
|
||||
return _get_impl( mp11::mp_size_t<I>() );
|
||||
}
|
||||
|
||||
template<std::size_t I, class V, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, std::initializer_list<V>&, A...>::value>::type>
|
||||
template<std::size_t I, class V, class... A, class E = typename std::enable_if<std::is_constructible<mp11::mp_at_c<variant<T...>, I>, std::initializer_list<V>&, A&&...>::value>::type>
|
||||
BOOST_CXX14_CONSTEXPR variant_alternative_t<I, variant<T...>>& emplace( std::initializer_list<V> il, A&&... a )
|
||||
{
|
||||
variant_base::template emplace<I>( il, std::forward<A>(a)... );
|
||||
@@ -1350,6 +1361,11 @@ public:
|
||||
|
||||
// value status
|
||||
|
||||
constexpr bool valueless_by_exception() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
using variant_base::index;
|
||||
|
||||
// swap
|
||||
|
||||
16
test/Jamfile
16
test/Jamfile
@@ -1,6 +1,6 @@
|
||||
# Boost.Variant2 Library Test Jamfile
|
||||
#
|
||||
# Copyright 2015-2017 Peter Dimov
|
||||
# Copyright 2015-2019 Peter Dimov
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -9,7 +9,19 @@
|
||||
import testing ;
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
project : requirements [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr ] ;
|
||||
project
|
||||
: default-build
|
||||
|
||||
<warnings>all
|
||||
|
||||
: requirements
|
||||
|
||||
[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr ]
|
||||
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
<toolset>gcc:<warnings-as-errors>on
|
||||
<toolset>clang:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
run variant_size.cpp ;
|
||||
run variant_alternative.cpp ;
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( disable: 4702 ) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/variant2/variant.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
Reference in New Issue
Block a user