2018-10-24 18:34:17 +03:00
|
|
|
////
|
2021-09-11 17:39:55 +03:00
|
|
|
Copyright 2018-2021 Peter Dimov
|
2018-10-24 18:34:17 +03:00
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
2021-09-11 17:39:55 +03:00
|
|
|
https://www.boost.org/LICENSE_1_0.txt
|
2018-10-24 18:34:17 +03:00
|
|
|
////
|
|
|
|
|
|
|
|
[#reference]
|
|
|
|
# Reference
|
|
|
|
:idprefix: ref_
|
|
|
|
|
|
|
|
## <boost/variant2/variant.hpp>
|
|
|
|
|
|
|
|
### Synopsis
|
|
|
|
|
|
|
|
```
|
|
|
|
namespace boost {
|
|
|
|
namespace variant2 {
|
|
|
|
|
|
|
|
// in_place_type
|
|
|
|
|
|
|
|
template<class T> struct in_place_type_t {};
|
|
|
|
template<class T> constexpr in_place_type_t<T> in_place_type{};
|
|
|
|
|
|
|
|
// in_place_index
|
|
|
|
|
|
|
|
template<std::size_t I> struct in_place_index_t {};
|
|
|
|
template<std::size_t I> constexpr in_place_index_t<I> in_place_index{};
|
|
|
|
|
|
|
|
// variant
|
|
|
|
|
|
|
|
template<class... T> class variant;
|
|
|
|
|
|
|
|
// variant_size
|
|
|
|
|
|
|
|
template<class T> struct variant_size {};
|
|
|
|
|
|
|
|
template<class T> struct variant_size<T const>: variant_size<T> {};
|
|
|
|
template<class T> struct variant_size<T volatile>: variant_size<T> {};
|
|
|
|
template<class T> struct variant_size<T const volatile>: variant_size<T> {};
|
|
|
|
|
2019-02-22 02:07:47 +02:00
|
|
|
template<class T> struct variant_size<T&>: variant_size<T> {}; // extension
|
|
|
|
template<class T> struct variant_size<T&&>: variant_size<T> {}; // extension
|
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class T>
|
|
|
|
inline constexpr size_t variant_size_v = variant_size<T>::value;
|
|
|
|
|
|
|
|
template<class... T>
|
|
|
|
struct variant_size<variant<T...>>:
|
|
|
|
std::integral_constant<std::size_t, sizeof...(T)> {};
|
|
|
|
|
|
|
|
// variant_alternative
|
|
|
|
|
|
|
|
template<size_t I, class T> struct variant_alternative {};
|
|
|
|
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T const>;
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T volatile>;
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T const volatile>;
|
|
|
|
|
2019-02-22 02:07:47 +02:00
|
|
|
template<size_t I, class T> struct variant_alternative<I, T&>; // extension
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T&&>; // extension
|
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class T>
|
|
|
|
using variant_alternative_t = typename variant_alternative<I, T>::type;
|
|
|
|
|
|
|
|
template<size_t I, class... T>
|
|
|
|
struct variant_alternative<I, variant<T...>>;
|
|
|
|
|
|
|
|
// variant_npos
|
|
|
|
|
|
|
|
constexpr std::size_t variant_npos = -1;
|
|
|
|
|
|
|
|
// holds_alternative
|
|
|
|
|
|
|
|
template<class U, class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool holds_alternative(const variant<T...>& v) noexcept;
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
// get
|
|
|
|
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
2019-02-21 06:42:06 +02:00
|
|
|
get(variant<T...>& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&&
|
2019-02-21 06:42:06 +02:00
|
|
|
get(variant<T...>&& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&
|
2019-02-21 06:42:06 +02:00
|
|
|
get(const variant<T...>& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&&
|
2019-02-21 06:42:06 +02:00
|
|
|
get(const variant<T...>&& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
template<class U, class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr U& get(variant<T...>& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class U, class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr U&& get(variant<T...>&& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class U, class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr const U& get(const variant<T...>& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class U, class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr const U&& get(const variant<T...>&& v);
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
// get_if
|
|
|
|
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr add_pointer_t<variant_alternative_t<I, variant<T...>>>
|
2019-02-21 06:42:06 +02:00
|
|
|
get_if(variant<T...>* v) noexcept;
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr add_pointer_t<const variant_alternative_t<I, variant<T...>>>
|
2019-02-21 06:42:06 +02:00
|
|
|
get_if(const variant<T...>* v) noexcept;
|
2019-02-22 12:27:53 +02:00
|
|
|
|
|
|
|
template<class U, class... T>
|
|
|
|
constexpr add_pointer_t<U>
|
2019-02-21 06:42:06 +02:00
|
|
|
get_if(variant<T...>* v) noexcept;
|
2019-02-22 12:27:53 +02:00
|
|
|
template<class U, class... T>
|
|
|
|
constexpr add_pointer_t<const U>
|
2019-02-21 06:42:06 +02:00
|
|
|
get_if(const variant<T...>* v) noexcept;
|
2018-10-24 18:34:17 +03:00
|
|
|
|
2021-09-11 17:39:55 +03:00
|
|
|
// unsafe_get (extension)
|
|
|
|
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
|
|
|
unsafe_get(variant<T...>& v);
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&&
|
|
|
|
unsafe_get(variant<T...>&& v);
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&
|
|
|
|
unsafe_get(const variant<T...>& v);
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&&
|
|
|
|
unsafe_get(const variant<T...>&& v);
|
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
// relational operators
|
|
|
|
|
|
|
|
template<class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool operator==(const variant<T...>& v, const variant<T...>& w);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool operator!=(const variant<T...>& v, const variant<T...>& w);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool operator<(const variant<T...>& v, const variant<T...>& w);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool operator>(const variant<T...>& v, const variant<T...>& w);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool operator<=(const variant<T...>& v, const variant<T...>& w);
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class... T>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr bool operator>=(const variant<T...>& v, const variant<T...>& w);
|
2018-10-24 18:34:17 +03:00
|
|
|
|
2021-09-15 03:53:13 +03:00
|
|
|
// swap
|
|
|
|
|
|
|
|
template<class... T>
|
|
|
|
void swap(variant<T...>& v, variant<T...>& w) noexcept( /*see below*/ );
|
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
// visit
|
|
|
|
|
2020-06-03 18:01:57 +03:00
|
|
|
template<class R = /*unspecified*/, class F, class... V>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr /*see below*/ visit(F&& f, V&&... v);
|
2018-10-24 18:34:17 +03:00
|
|
|
|
2021-09-14 21:32:57 +03:00
|
|
|
// visit_by_index (extension)
|
|
|
|
|
2021-09-15 02:00:33 +03:00
|
|
|
template<class R = /*unspecified*/, class V, class... F>
|
|
|
|
constexpr /*see below*/ visit_by_index(V&& v, F&&.. f);
|
2021-09-14 21:32:57 +03:00
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
// monostate
|
|
|
|
|
|
|
|
struct monostate {};
|
|
|
|
|
|
|
|
constexpr bool operator==(monostate, monostate) noexcept { return true; }
|
|
|
|
constexpr bool operator!=(monostate, monostate) noexcept { return false; }
|
|
|
|
constexpr bool operator<(monostate, monostate) noexcept { return false; }
|
|
|
|
constexpr bool operator>(monostate, monostate) noexcept { return false; }
|
|
|
|
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
|
|
|
|
constexpr bool operator>=(monostate, monostate) noexcept { return true; }
|
|
|
|
|
2022-01-31 19:19:49 +02:00
|
|
|
// stream insertion (extension)
|
|
|
|
|
|
|
|
template<class Ch, class Tr, class... T>
|
|
|
|
std::basic_ostream<Ch, Tr>&
|
|
|
|
operator<<( std::basic_ostream<Ch, Tr>& os, variant<T...> const& v );
|
|
|
|
|
|
|
|
template<class Ch, class Tr>
|
|
|
|
std::basic_ostream<Ch, Tr>&
|
|
|
|
operator<<( std::basic_ostream<Ch, Tr>& os, monostate const& v );
|
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
// bad_variant_access
|
|
|
|
|
|
|
|
class bad_variant_access;
|
|
|
|
|
|
|
|
} // namespace variant2
|
|
|
|
} // namespace boost
|
|
|
|
```
|
|
|
|
|
|
|
|
### variant
|
|
|
|
|
|
|
|
```
|
|
|
|
namespace boost {
|
|
|
|
namespace variant2 {
|
|
|
|
|
|
|
|
template<class... T> class variant
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
// constructors
|
|
|
|
|
|
|
|
constexpr variant() noexcept( /*see below*/ );
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant( variant const & r ) noexcept( /*see below*/ );
|
|
|
|
constexpr variant( variant&& r ) noexcept( /*see below*/ );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
template<class U>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant( U&& u ) noexcept( /*see below*/ );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
template<class U, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_type_t<U>, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class U, class V, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_type_t<U>,
|
|
|
|
std::initializer_list<V> il, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
template<size_t I, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_index_t<I>, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class V, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_index_t<I>,
|
|
|
|
std::initializer_list<V> il, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
// destructor
|
|
|
|
|
|
|
|
~variant();
|
|
|
|
|
|
|
|
// assignment
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant& operator=( variant const & r ) noexcept( /*see below*/ );
|
|
|
|
constexpr variant& operator=( variant&& r ) noexcept( /*see below*/ );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
template<class U> constexpr variant& operator=( U&& u ) noexcept( /*see below*/ );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
// modifiers
|
|
|
|
|
|
|
|
template<class U, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr U& emplace( A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
template<class U, class V, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr U& emplace( std::initializer_list<V> il, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
template<size_t I, class... A>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
2019-02-21 06:42:06 +02:00
|
|
|
emplace( A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
template<size_t I, class V, class... A>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
2019-02-21 06:42:06 +02:00
|
|
|
emplace( std::initializer_list<V> il, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
// value status
|
|
|
|
|
|
|
|
constexpr bool valueless_by_exception() const noexcept;
|
|
|
|
constexpr size_t index() const noexcept;
|
|
|
|
|
|
|
|
// swap
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
void swap( variant& r ) noexcept( /*see below*/ );
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
// converting constructors (extension)
|
|
|
|
|
|
|
|
template<class... U> variant( variant<U...> const& r )
|
|
|
|
noexcept( /*see below*/ );
|
|
|
|
|
|
|
|
template<class... U> variant( variant<U...>&& r )
|
|
|
|
noexcept( /*see below*/ );
|
|
|
|
|
|
|
|
// subset (extension)
|
|
|
|
|
|
|
|
template<class... U> constexpr variant<U...> subset() & ;
|
|
|
|
template<class... U> constexpr variant<U...> subset() && ;
|
|
|
|
template<class... U> constexpr variant<U...> subset() const& ;
|
|
|
|
template<class... U> constexpr variant<U...> subset() const&& ;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace variant2
|
|
|
|
} // namespace boost
|
|
|
|
```
|
|
|
|
|
2019-05-12 19:19:55 +03:00
|
|
|
In the descriptions that follow, let `i` be in the range `[0, sizeof...(T))`,
|
|
|
|
and `Ti` be the `i`-th type in `T...`.
|
|
|
|
|
2018-10-24 18:34:17 +03:00
|
|
|
#### Constructors
|
|
|
|
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant() noexcept( std::is_nothrow_default_constructible_v<T0> );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Constructs a `variant` holding a value-initialized value of
|
|
|
|
type `T0`.
|
|
|
|
Ensures: :: `index() == 0`.
|
|
|
|
Throws: :: Any exception thrown by the value-initialization of `T0`.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_default_constructible_v<T0>` is `true`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant( variant const & w )
|
2019-02-18 19:51:23 +02:00
|
|
|
noexcept( mp_all<std::is_nothrow_copy_constructible<T>...>::value );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the variant to hold the same alternative and value as
|
|
|
|
`w`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_copy_constructible_v<Ti>` is `true` for all `i`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant( variant&& w )
|
2019-02-18 19:51:23 +02:00
|
|
|
noexcept( mp_all<std::is_nothrow_move_constructible<T>...>::value );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the variant to hold the same alternative and value as
|
|
|
|
`w`.
|
|
|
|
Throws: :: Any exception thrown by the move-initialization of the contained
|
|
|
|
value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_move_constructible_v<Ti>` is `true` for all `i`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
template<class U> constexpr variant( U&& u ) noexcept(/*see below*/);
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Let `Tj` be a type that is determined as follows: build an imaginary function
|
|
|
|
`FUN(Ti)` for each alternative type `Ti`. The overload `FUN(Tj)` selected by
|
|
|
|
overload resolution for the expression `FUN(std::forward<U>(u))` defines the
|
|
|
|
alternative `Tj` which is the type of the contained value after construction.
|
|
|
|
|
|
|
|
Effects: :: Initializes `*this` to hold the alternative type `Tj` and
|
|
|
|
initializes the contained value from `std::forward<U>(u)`.
|
|
|
|
Ensures: :: `holds_alternative<Tj>(*this)`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: The expression inside `noexcept` is equivalent to
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_nothrow_constructible_v<Tj, U>`. This function does not participate in
|
2018-10-24 18:34:17 +03:00
|
|
|
overload resolution unless
|
|
|
|
- `sizeof...(T)` is nonzero,
|
2019-02-18 19:51:23 +02:00
|
|
|
- `std::is_same_v<std::remove_cvref_t<U>, variant>` is `false`,
|
|
|
|
- `std::remove_cvref_t<U>` is neither a specialization of `in_place_type_t` nor a
|
2018-10-24 18:34:17 +03:00
|
|
|
specialization of `in_place_index_t`,
|
2019-02-18 19:51:23 +02:00
|
|
|
- `std::is_constructible_v<Tj, U>` is `true`, and
|
2018-10-24 18:34:17 +03:00
|
|
|
- the expression `FUN(std::forward<U>(u))` is well-formed.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class U, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_type_t<U>, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the contained value of type `U` with the arguments
|
|
|
|
`std::forward<A>(a)...`.
|
|
|
|
Ensures: :: `holds_alternative<U>(*this)`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
|
|
|
there is exactly one occurrence of `U` in `T...` and
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_constructible_v<U, A...>` is true.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
template<class U, class V, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_type_t<U>, std::initializer_list<V> il,
|
|
|
|
A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the contained value of type `U` with the arguments `il`,
|
|
|
|
`std::forward<A>(a)...`.
|
|
|
|
Ensures: :: `holds_alternative<U>(*this)`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
|
|
|
there is exactly one occurrence of `U` in `T...` and
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_constructible_v<U, initializer_list<V>&, A...>` is `true`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_index_t<I>, A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the contained value of type `TI` with the arguments
|
|
|
|
`std::forward<A>(a)...`.
|
|
|
|
Ensures: :: `index() == I`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
2019-02-18 19:51:23 +02:00
|
|
|
`I < sizeof...(T)` and `std::is_constructible_v<TI, A...>` is `true`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class V, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr explicit variant( in_place_index_t<I>, std::initializer_list<V> il,
|
|
|
|
A&&... a );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the contained value of type `TI` with the arguments
|
|
|
|
`il`, `std::forward<A>(a)...`.
|
|
|
|
Ensures: :: `index() == I`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
2019-02-21 06:42:06 +02:00
|
|
|
`I < sizeof...(T)` and
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_constructible_v<TI, initializer_list<V>&, A...>` is `true`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
#### Destructor
|
|
|
|
|
|
|
|
```
|
|
|
|
~variant();
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-05-11 21:04:45 +03:00
|
|
|
Effects: ::
|
|
|
|
Destroys the currently contained value.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
|
|
|
#### Assignment
|
|
|
|
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant& operator=( const variant& r )
|
2019-05-12 02:02:49 +03:00
|
|
|
noexcept( mp_all<std::is_nothrow_copy_constructible<T>...>::value );
|
2018-10-24 18:34:17 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-02-21 06:42:06 +02:00
|
|
|
Let `j` be `r.index()`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
2019-05-12 02:02:49 +03:00
|
|
|
Effects: :: `emplace<j>(get<j>(r))`.
|
2018-10-24 18:34:17 +03:00
|
|
|
Returns: :: `*this`.
|
2019-02-21 06:42:06 +02:00
|
|
|
Ensures: :: `index() == r.index()`.
|
2018-10-24 18:34:17 +03:00
|
|
|
Remarks: :: This operator does not participate in overload resolution unless
|
2019-02-18 19:51:23 +02:00
|
|
|
`std::is_copy_constructible_v<Ti> && std::is_copy_assignable_v<Ti>` is
|
|
|
|
`true` for all `i`.
|
2018-10-24 18:34:17 +03:00
|
|
|
|
2019-02-18 19:51:23 +02:00
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr variant& operator=( variant&& r )
|
2019-05-12 02:02:49 +03:00
|
|
|
noexcept( mp_all<std::is_nothrow_move_constructible<T>...>::value );
|
2019-02-18 19:51:23 +02:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-02-21 06:42:06 +02:00
|
|
|
Let `j` be `r.index()`.
|
2019-02-18 19:51:23 +02:00
|
|
|
|
2019-05-12 02:02:49 +03:00
|
|
|
Effects: :: `emplace<j>(get<j>(std::move(r)))`.
|
2019-02-18 19:51:23 +02:00
|
|
|
Returns: :: `*this`.
|
2019-02-21 06:42:06 +02:00
|
|
|
Ensures: :: `index() == r.index()`.
|
2019-02-18 19:51:23 +02:00
|
|
|
Remarks: :: This operator does not participate in overload resolution unless
|
|
|
|
`std::is_move_constructible_v<Ti> && std::is_move_assignable_v<Ti>` is
|
|
|
|
`true` for all `i`.
|
|
|
|
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
template<class U> constexpr variant& operator=( U&& u )
|
2019-02-18 19:51:23 +02:00
|
|
|
noexcept( /*see below*/ );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Let `Tj` be a type that is determined as follows: build an imaginary function
|
|
|
|
`FUN(Ti)` for each alternative type `Ti`. The overload `FUN(Tj)` selected by
|
|
|
|
overload resolution for the expression `FUN(std::forward<U>(u))` defines the
|
|
|
|
alternative `Tj` which is the type of the contained value after construction.
|
|
|
|
|
2019-05-12 02:02:49 +03:00
|
|
|
Effects: :: `emplace<j>(std::forward<U>(u))`.
|
2019-02-18 19:51:23 +02:00
|
|
|
Returns: :: `*this`.
|
|
|
|
Ensures: :: `index() == j`.
|
|
|
|
Remarks: ::
|
2019-05-12 02:02:49 +03:00
|
|
|
The expression inside `noexcept` is `std::is_nothrow_constructible_v<Tj, U&&>`.
|
2019-02-18 19:51:23 +02:00
|
|
|
This operator does not participate in overload resolution unless
|
|
|
|
- `std::is_same_v<std::remove_cvref_t<T>, variant>` is `false`,
|
2019-05-12 02:02:49 +03:00
|
|
|
- `std::is_constructible_v<Tj, U&&> && std::is_assignable_v<Tj&, U&&>` is
|
2019-02-18 19:51:23 +02:00
|
|
|
`true`, and
|
|
|
|
- the expression `FUN(std::forward<U>(u))` (with `FUN` being the
|
|
|
|
above-mentioned set of imaginary functions) is well-formed.
|
|
|
|
|
|
|
|
#### Modifiers
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class U, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr U& emplace( A&&... a );
|
2019-02-18 19:51:23 +02:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Let `I` be the zero-based index of `U` in `T...`.
|
|
|
|
|
|
|
|
Effects: :: Equivalent to: `return emplace<I>(std::forward<A>(a)...);`
|
|
|
|
Remarks: ::
|
|
|
|
This function shall not participate in overload resolution unless
|
2019-05-12 02:02:49 +03:00
|
|
|
`std::is_constructible_v<U, A&&...>` is `true` and `U` occurs exactly once
|
2019-02-18 19:51:23 +02:00
|
|
|
in `T...`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class U, class V, class... A>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr U& emplace( std::initializer_list<V> il, A&&... a );
|
2019-02-18 19:51:23 +02:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Let `I` be the zero-based index of `U` in `T...`.
|
|
|
|
|
|
|
|
Effects: :: Equivalent to: `return emplace<I>(il, std::forward<A>(a)...);`
|
|
|
|
Remarks: ::
|
|
|
|
This function shall not participate in overload resolution unless
|
2019-05-12 02:02:49 +03:00
|
|
|
`std::is_constructible_v<U, std::initializer_list<V>&, A&&...>` is `true`
|
2019-02-18 19:51:23 +02:00
|
|
|
and `U` occurs exactly once in `T...`.
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class... A>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
2019-02-21 06:42:06 +02:00
|
|
|
emplace( A&&... a );
|
2019-02-18 19:51:23 +02:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-03-06 16:07:56 +01:00
|
|
|
Requires: :: `I < sizeof...(T)`.
|
2019-02-18 19:51:23 +02:00
|
|
|
Effects: ::
|
2021-01-25 03:49:42 +02:00
|
|
|
Initializes a new contained value as if using the expression
|
|
|
|
`Ti(std::forward<A>(a)...)`, then destroys the currently contained value.
|
2019-02-18 19:51:23 +02:00
|
|
|
Ensures: :: `index() == I`.
|
|
|
|
Returns: :: A reference to the new contained value.
|
2019-03-25 16:35:27 +02:00
|
|
|
Throws: ::
|
|
|
|
Nothing unless the initialization of the new contained value throws.
|
2019-05-12 02:02:49 +03:00
|
|
|
Exception Safety: :: Strong. On exception, the contained value is unchanged.
|
2019-02-18 19:51:23 +02:00
|
|
|
Remarks: ::
|
|
|
|
This function shall not participate in overload resolution unless
|
2019-05-12 02:02:49 +03:00
|
|
|
`std::is_constructible_v<Ti, A&&...>` is `true`.
|
2019-02-18 19:51:23 +02:00
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class V, class... A>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
2019-02-21 06:42:06 +02:00
|
|
|
emplace( std::initializer_list<V> il, A&&... a );
|
2019-02-18 19:51:23 +02:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-03-06 16:07:56 +01:00
|
|
|
Requires: :: `I < sizeof...(T)`.
|
2019-02-18 19:51:23 +02:00
|
|
|
Effects: ::
|
2021-01-25 03:49:42 +02:00
|
|
|
Initializes a new contained value as if using the expression
|
|
|
|
`Ti(il, std::forward<A>(a)...)`, then destroys the currently contained value.
|
2019-02-18 19:51:23 +02:00
|
|
|
Ensures: :: `index() == I`.
|
|
|
|
Returns: :: A reference to the new contained value.
|
2019-03-25 16:35:27 +02:00
|
|
|
Throws: ::
|
|
|
|
Nothing unless the initialization of the new contained value throws.
|
2019-05-12 02:02:49 +03:00
|
|
|
Exception Safety: :: Strong. On exception, the contained value is unchanged.
|
2019-02-18 19:51:23 +02:00
|
|
|
Remarks: ::
|
|
|
|
This function shall not participate in overload resolution unless
|
2019-05-12 02:02:49 +03:00
|
|
|
`std::is_constructible_v<Ti, std::initializer_list<V>&, A&&...>` is `true`.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
|
|
|
#### Value Status
|
|
|
|
|
|
|
|
```
|
|
|
|
constexpr bool valueless_by_exception() const noexcept;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Returns: :: `false`.
|
|
|
|
|
2019-05-12 02:02:49 +03:00
|
|
|
NOTE: This function is provided purely for compatibility with `std::variant`.
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
```
|
|
|
|
constexpr size_t index() const noexcept;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-05-11 21:04:45 +03:00
|
|
|
Returns: ::
|
|
|
|
The zero-based index of the active alternative.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
|
|
|
#### Swap
|
|
|
|
|
|
|
|
```
|
|
|
|
void swap( variant& r ) noexcept( mp_all<std::is_nothrow_move_constructible<T>...,
|
|
|
|
is_nothrow_swappable<T>...>::value );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: ::
|
|
|
|
- If `index() == r.index()`, calls `swap(get<I>(*this), get<I>(r))`,
|
|
|
|
where `I` is `index()`.
|
|
|
|
- Otherwise, as if
|
|
|
|
`variant tmp(std::move(*this)); *this = std::move(r); r = std::move(tmp);`
|
|
|
|
|
|
|
|
#### Converting Constructors (extension)
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... U> variant( variant<U...> const& r )
|
|
|
|
noexcept( mp_all<std::is_nothrow_copy_constructible<U>...>::value );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the contained value from the contained value of `r`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
|
|
|
all types in `U...` are in `T...` and
|
|
|
|
`std::is_copy_constructible_v<Ui>::value` is `true` for all `Ui`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... U> variant( variant<U...>&& r )
|
|
|
|
noexcept( mp_all<std::is_nothrow_move_constructible<U>...>::value );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: Initializes the contained value from the contained value of
|
|
|
|
`std::move(r)`.
|
|
|
|
Throws: :: Any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
|
|
|
all types in `U...` are in `T...` and
|
|
|
|
`std::is_move_constructible_v<Ui>::value` is `true` for all `Ui`.
|
|
|
|
|
|
|
|
#### Subset (extension)
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... U> constexpr variant<U...> subset() & ;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<class... U> constexpr variant<U...> subset() const& ;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Returns: :: A `variant<U...>` whose contained value is copy-initialized from
|
|
|
|
the contained value of `*this` and has the same type.
|
|
|
|
Throws: ::
|
|
|
|
- If the active alternative of `*this` is not among the types in `U...`,
|
|
|
|
`bad_variant_access`.
|
|
|
|
- Otherwise, any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
|
|
|
all types in `U...` are in `T...` and
|
|
|
|
`std::is_copy_constructible_v<Ui>::value` is `true` for all `Ui`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... U> constexpr variant<U...> subset() && ;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<class... U> constexpr variant<U...> subset() const&& ;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Returns: :: A `variant<U...>` whose contained value is move-initialized from
|
|
|
|
the contained value of `*this` and has the same type.
|
|
|
|
Throws: ::
|
|
|
|
- If the active alternative of `*this` is not among the types in `U...`,
|
|
|
|
`bad_variant_access`.
|
|
|
|
- Otherwise, any exception thrown by the initialization of the contained value.
|
|
|
|
Remarks: :: This function does not participate in overload resolution unless
|
|
|
|
all types in `U...` are in `T...` and
|
|
|
|
`std::is_move_constructible_v<Ui>::value` is `true` for all `Ui`.
|
|
|
|
|
|
|
|
### variant_alternative
|
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T const>;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T volatile>;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T const volatile>;
|
|
|
|
```
|
2019-02-22 02:07:47 +02:00
|
|
|
```
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T&>; // extension
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class T> struct variant_alternative<I, T&&>; // extension
|
|
|
|
```
|
2019-02-21 06:42:06 +02:00
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
--
|
|
|
|
If `typename variant_alternative<I, T>::type` exists and is `U`,
|
|
|
|
|
|
|
|
* `variant_alternative<I, T const>::type` is `U const`;
|
|
|
|
* `variant_alternative<I, T volatile>::type` is `U volatile`;
|
|
|
|
* `variant_alternative<I, T const volatile>::type` is `U const volatile`.
|
2019-02-22 02:07:47 +02:00
|
|
|
* `variant_alternative<I, T&>::type` is `U&`.
|
|
|
|
* `variant_alternative<I, T&&>::type` is `U&&`.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
2019-02-22 02:07:47 +02:00
|
|
|
Otherwise, these structs have no member `type`.
|
2019-02-21 06:42:06 +02:00
|
|
|
--
|
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
struct variant_alternative<I, variant<T...>>;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
When `I < sizeof...(T)`, the nested type `type` is an alias for the `I`-th
|
2019-02-22 02:07:47 +02:00
|
|
|
(zero-based) type in `T...`. Otherwise, there is no member `type`.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
|
|
|
### holds_alternative
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class U, class... T>
|
|
|
|
constexpr bool holds_alternative(const variant<T...>& v) noexcept;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
|
|
|
|
program is ill-formed.
|
|
|
|
Returns: :: `true` if `index()` is equal to the zero-based index of `U`
|
|
|
|
in `T...`.
|
|
|
|
|
|
|
|
### get
|
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
|
|
|
get(variant<T...>& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&&
|
|
|
|
get(variant<T...>&& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&
|
|
|
|
get(const variant<T...>& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&&
|
|
|
|
get(const variant<T...>&& v);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: If `v.index()` is `I`, returns a reference to the object stored in
|
|
|
|
the variant. Otherwise, throws `bad_variant_access`.
|
2019-05-12 19:19:55 +03:00
|
|
|
Remarks: :: These functions do not participate in overload resolution
|
|
|
|
unless `I` < `sizeof...(T)`.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
|
|
|
```
|
|
|
|
template<class U, class... T>
|
|
|
|
constexpr U& get(variant<T...>& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<class U, class... T>
|
|
|
|
constexpr U&& get(variant<T...>&& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<class U, class... T>
|
|
|
|
constexpr const U& get(const variant<T...>& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<class U, class... T>
|
|
|
|
constexpr const U&& get(const variant<T...>&& v);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
|
|
|
|
program is ill-formed.
|
|
|
|
Effects: :: If `v` holds a value of type `U`, returns a reference to that value.
|
|
|
|
Otherwise, throws `bad_variant_access`.
|
|
|
|
|
|
|
|
### get_if
|
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr add_pointer_t<variant_alternative_t<I, variant<T...>>>
|
|
|
|
get_if(variant<T...>* v) noexcept;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr add_pointer_t<const variant_alternative_t<I, variant<T...>>>
|
|
|
|
get_if(const variant<T...>* v) noexcept;
|
|
|
|
```
|
2019-02-22 12:27:53 +02:00
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: :: A pointer to the value stored in the variant, if
|
|
|
|
`v != nullptr && v\->index() == I`. Otherwise, `nullptr`.
|
2019-05-12 19:19:55 +03:00
|
|
|
Remarks: :: These functions do not participate in overload resolution
|
|
|
|
unless `I` < `sizeof...(T)`.
|
2019-02-22 12:27:53 +02:00
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
```
|
2019-02-22 12:27:53 +02:00
|
|
|
template<class U, class... T>
|
|
|
|
constexpr add_pointer_t<U>
|
2019-02-21 06:42:06 +02:00
|
|
|
get_if(variant<T...>* v) noexcept;
|
|
|
|
```
|
|
|
|
```
|
2019-02-22 12:27:53 +02:00
|
|
|
template<class U, class... T>
|
|
|
|
constexpr add_pointer_t<const U>
|
2019-02-21 06:42:06 +02:00
|
|
|
get_if(const variant<T...>* v) noexcept;
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-02-22 12:27:53 +02:00
|
|
|
Requires: :: The type `U` occurs exactly once in `T...`. Otherwise, the
|
|
|
|
program is ill-formed.
|
|
|
|
Effects: :: Equivalent to: `return get_if<I>(v);` with `I` being
|
|
|
|
the zero-based index of `U` in `T...`.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
2021-09-11 17:39:55 +03:00
|
|
|
### unsafe_get (extension)
|
|
|
|
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&
|
|
|
|
unsafe_get(variant<T...>& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr variant_alternative_t<I, variant<T...>>&&
|
|
|
|
unsafe_get(variant<T...>&& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&
|
|
|
|
unsafe_get(const variant<T...>& v);
|
|
|
|
```
|
|
|
|
```
|
|
|
|
template<size_t I, class... T>
|
|
|
|
constexpr const variant_alternative_t<I, variant<T...>>&&
|
|
|
|
unsafe_get(const variant<T...>&& v);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Requires: :: `v.index() == I`.
|
|
|
|
Returns: :: a reference to the object stored in the variant.
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
### Relational Operators
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
constexpr bool operator==(const variant<T...>& v, const variant<T...>& w);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-05-12 19:19:55 +03:00
|
|
|
Returns: :: `v.index() == w.index() && get<I>(v) == get<I>(w)`, where `I`
|
2019-02-21 06:42:06 +02:00
|
|
|
is `v.index()`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
constexpr bool operator!=(const variant<T...>& v, const variant<T...>& w);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Returns: :: `!(v == w)`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
constexpr bool operator<(const variant<T...>& v, const variant<T...>& w);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-05-12 19:19:55 +03:00
|
|
|
Returns: :: `v.index() < w.index() || (v.index() == w.index() && get<I>(v) < get<I>(w))`,
|
2019-02-21 06:42:06 +02:00
|
|
|
where `I` is `v.index()`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
constexpr bool operator>(const variant<T...>& v, const variant<T...>& w);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Returns: :: `w < v`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
constexpr bool operator<=(const variant<T...>& v, const variant<T...>& w);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-05-12 19:19:55 +03:00
|
|
|
Returns: :: `v.index() < w.index() || (v.index() == w.index() && get<I>(v) \<= get<I>(w))`,
|
2019-02-21 06:42:06 +02:00
|
|
|
where `I` is `v.index()`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
constexpr bool operator>=(const variant<T...>& v, const variant<T...>& w);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
2019-05-11 21:04:45 +03:00
|
|
|
Returns: ::
|
|
|
|
`w \<= v`.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
2021-09-15 03:53:13 +03:00
|
|
|
### swap
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class... T>
|
|
|
|
void swap(variant<T...>& v, variant<T...>& w) noexcept( /*see below*/ );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: ::
|
|
|
|
Equivalent to `v.swap(w)`.
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
### visit
|
|
|
|
|
|
|
|
```
|
2020-06-03 18:01:57 +03:00
|
|
|
template<class R = /*unspecified*/, class F, class... V>
|
2019-02-21 06:42:06 +02:00
|
|
|
constexpr /*see below*/ visit(F&& f, V&&... v);
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Returns: :: `std::forward<F>(f)(get<I>(std::forward<V>(v))...)`, where
|
|
|
|
`I...` is `v.index()...`.
|
2020-06-03 18:01:57 +03:00
|
|
|
Remarks: :: If `R` is given explicitly, as in `visit<int>`, the return
|
|
|
|
type is `R`. Otherwise, it's deduced from `F`. All possible applications
|
|
|
|
of `F` to the variant alternatives must have the same return type for
|
|
|
|
this deduction to succeed.
|
2019-02-21 06:42:06 +02:00
|
|
|
|
2021-09-14 21:32:57 +03:00
|
|
|
### visit_by_index (extension)
|
|
|
|
|
|
|
|
```
|
2021-09-15 02:00:33 +03:00
|
|
|
template<class R = /*unspecified*/, class V, class... F>
|
|
|
|
constexpr /*see below*/ visit_by_index(V&& v, F&&.. f);
|
2021-09-14 21:32:57 +03:00
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Requires: :: `variant_size<V>::value == sizeof...(F)`, or the program is ill-formed.
|
2021-09-15 02:00:33 +03:00
|
|
|
Returns: :: `std::forward<Fi>(fi)(get<i>(std::forward<V>(v)))`, where
|
2021-09-14 21:32:57 +03:00
|
|
|
`i` is `v.index()` and `Fi` and `fi` are the `i`-th element of `F...` and `f...`
|
|
|
|
accordingly.
|
2021-09-15 02:00:33 +03:00
|
|
|
Remarks: :: If `R` is given explicitly, as in `visit_by_index<int>`, the return
|
|
|
|
type is `R`. Otherwise, it's deduced from `F...` and `V`. All the applications
|
|
|
|
of `Fi` to the corresponding variant alternatives must have the same return type
|
|
|
|
for this deduction to succeed.
|
2021-09-14 21:32:57 +03:00
|
|
|
|
2022-01-31 19:19:49 +02:00
|
|
|
### Stream Insertion (extension)
|
|
|
|
```
|
|
|
|
template<class Ch, class Tr, class... T>
|
|
|
|
std::basic_ostream<Ch, Tr>&
|
|
|
|
operator<<( std::basic_ostream<Ch, Tr>& os, variant<T...> const& v );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Requires: ::
|
|
|
|
`sizeof...(T) != 0`.
|
|
|
|
Returns: ::
|
|
|
|
`os << get<I>(v)`, where `I` is `v.index()`.
|
|
|
|
|
|
|
|
```
|
|
|
|
template<class Ch, class Tr>
|
|
|
|
std::basic_ostream<Ch, Tr>&
|
|
|
|
operator<<( std::basic_ostream<Ch, Tr>& os, monostate const& v );
|
|
|
|
```
|
|
|
|
[none]
|
|
|
|
* {blank}
|
|
|
|
+
|
|
|
|
Effects: ::
|
|
|
|
`os << "monostate"`.
|
|
|
|
Returns: ::
|
|
|
|
`os`.
|
|
|
|
|
2019-02-21 06:42:06 +02:00
|
|
|
### bad_variant_access
|
|
|
|
|
|
|
|
```
|
|
|
|
class bad_variant_access: public std::exception
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
bad_variant_access() noexcept = default;
|
|
|
|
|
|
|
|
char const * what() const noexcept
|
|
|
|
{
|
|
|
|
return "bad_variant_access";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
```
|
2021-09-11 17:39:55 +03:00
|
|
|
|
|
|
|
## <boost/variant2.hpp>
|
|
|
|
|
|
|
|
This convenience header includes `<boost/variant2/variant.hpp>`.
|