//// Copyright 2018, 2019 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 //// [#reference] # Reference :idprefix: ref_ ## ### Synopsis ``` namespace boost { namespace variant2 { // in_place_type template struct in_place_type_t {}; template constexpr in_place_type_t in_place_type{}; // in_place_index template struct in_place_index_t {}; template constexpr in_place_index_t in_place_index{}; // variant template class variant; // variant_size template struct variant_size {}; template struct variant_size: variant_size {}; template struct variant_size: variant_size {}; template struct variant_size: variant_size {}; template inline constexpr size_t variant_size_v = variant_size::value; template struct variant_size>: std::integral_constant {}; // variant_alternative template struct variant_alternative {}; template struct variant_alternative; template struct variant_alternative; template struct variant_alternative; template using variant_alternative_t = typename variant_alternative::type; template struct variant_alternative>; // variant_npos constexpr std::size_t variant_npos = -1; // holds_alternative template constexpr bool holds_alternative(const variant&) noexcept; // get template constexpr variant_alternative_t>& get(variant&); template constexpr variant_alternative_t>&& get(variant&&); template constexpr const variant_alternative_t>& get(const variant&); template constexpr const variant_alternative_t>&& get(const variant&&); template constexpr U& get(variant&); template constexpr U&& get(variant&&); template constexpr const U& get(const variant&); template constexpr const U&& get(const variant&&); // get_if template constexpr add_pointer_t>> get_if(variant*) noexcept; template constexpr add_pointer_t>> get_if(const variant*) noexcept; template constexpr add_pointer_t get_if(variant*) noexcept; template constexpr add_pointer_t get_if(const variant*) noexcept; // relational operators template constexpr bool operator==(const variant&, const variant&); template constexpr bool operator!=(const variant&, const variant&); template constexpr bool operator<(const variant&, const variant&); template constexpr bool operator>(const variant&, const variant&); template constexpr bool operator<=(const variant&, const variant&); template constexpr bool operator>=(const variant&, const variant&); // visit template constexpr /*see below*/ visit(F&&, V&&...); // 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; } // swap template void swap(variant&, variant&) noexcept( see below ); // bad_variant_access class bad_variant_access; } // namespace variant2 } // namespace boost ``` ### variant ``` namespace boost { namespace variant2 { template class variant { public: // constructors constexpr variant() noexcept( /*see below*/ ); constexpr variant(variant const &) noexcept( /*see below*/ ); constexpr variant(variant&&) noexcept( /*see below*/ ); template constexpr variant(U&&) noexcept( /*see below*/ ); template constexpr explicit variant(in_place_type_t, A&&...); template constexpr explicit variant(in_place_type_t, std::initializer_list, A&&...); template constexpr explicit variant(in_place_index_t, A&&...); template constexpr explicit variant(in_place_index_t, std::initializer_list, A&&...); // destructor ~variant(); // assignment constexpr variant& operator=(variant const &) noexcept( /*see below*/ ); constexpr variant& operator=(variant&&) noexcept( /*see below*/ ); template constexpr variant& operator=(U&&) noexcept( /*see below*/ ); // modifiers template constexpr U& emplace(A&&...); template constexpr U& emplace(std::initializer_list, A&&...); template constexpr variant_alternative_t>& emplace(A&&...); template constexpr variant_alternative_t>& emplace(std::initializer_list, A&&...); // value status constexpr bool valueless_by_exception() const noexcept; constexpr size_t index() const noexcept; // swap void swap(variant&) noexcept( /*see below*/ ); // converting constructors (extension) template variant( variant const& r ) noexcept( /*see below*/ ); template variant( variant&& r ) noexcept( /*see below*/ ); // subset (extension) template constexpr variant subset() & ; template constexpr variant subset() && ; template constexpr variant subset() const& ; template constexpr variant subset() const&& ; }; } // namespace variant2 } // namespace boost ``` #### Constructors ``` constexpr variant() noexcept(std::is_nothrow_default_constructible_v); ``` [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 `std::is_default_constructible_v` is `true`. ``` constexpr variant(variant const & w) noexcept( mp_all...>::value ); ``` [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 `std::is_copy_constructible_v` is `true` for all `i`. ``` constexpr variant(variant&& w) noexcept( mp_all...>::value ); ``` [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 `std::is_move_constructible_v` is `true` for all `i`. ``` template constexpr variant(U&& u) 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))` 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)`. Ensures: :: `holds_alternative(*this)`. Throws: :: Any exception thrown by the initialization of the contained value. Remarks: :: The expression inside `noexcept` is equivalent to `std::is_nothrow_constructible_v`. This function does not participate in overload resolution unless - `sizeof...(T)` is nonzero, - `std::is_same_v, variant>` is `false`, - `std::remove_cvref_t` is neither a specialization of `in_place_type_t` nor a specialization of `in_place_index_t`, - `std::is_constructible_v` is `true`, and - the expression `FUN(std::forward(u))` is well-formed. ``` template constexpr explicit variant(in_place_type_t, A&&... a); ``` [none] * {blank} + Effects: :: Initializes the contained value of type `U` with the arguments `std::forward(a)...`. Ensures: :: `holds_alternative(*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 `std::is_constructible_v` is true. ``` template constexpr explicit variant(in_place_type_t, std::initializer_list il, A&&... a); ``` [none] * {blank} + Effects: :: Initializes the contained value of type `U` with the arguments `il`, `std::forward(a)...`. Ensures: :: `holds_alternative(*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 `std::is_constructible_v&, A...>` is `true`. ``` template constexpr explicit variant(in_place_index_t, A&&... a); ``` [none] * {blank} + Effects: :: Initializes the contained value of type `TI` with the arguments `std::forward(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 `I < sizeof...(T)` and `std::is_constructible_v` is `true`. ``` template constexpr explicit variant(in_place_index_t, std::initializer_list il, A&&... a); ``` [none] * {blank} + Effects: :: Initializes the contained value of type `TI` with the arguments `il`, `std::forward(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 `I < sizeof...(Types)` and `std::is_constructible_v&, A...>` is `true`. #### Destructor ``` ~variant(); ``` [none] * {blank} + Effects: :: Destroys the currently contained value. #### Assignment ``` constexpr variant& operator=(const variant& rhs) noexcept( mp_all..., std::is_nothrow_copy_assignable...>::value ); ``` [none] * {blank} + Let `j` be `rhs.index()`. Effects: :: - If `index() == j`, assigns the value contained in `rhs` to the value contained in `*this`. - Otherwise, equivalent to `emplace(get(rhs))`. Returns: :: `*this`. Ensures: :: `index() == rhs.index()`. Remarks: :: This operator does not participate in overload resolution unless `std::is_copy_constructible_v && std::is_copy_assignable_v` is `true` for all `i`. ``` constexpr variant& operator=(variant&& rhs) noexcept( mp_all..., std::is_nothrow_move_assignable...>::value ); ``` [none] * {blank} + Let `j` be `rhs.index()`. Effects: :: - If `index() == j`, assigns the value contained in `std::move(rhs)` to the value contained in `*this`. - Otherwise, equivalent to `emplace(get(std::move(rhs)))`. Returns: :: `*this`. Ensures: :: `index() == rhs.index()`. Remarks: :: This operator does not participate in overload resolution unless `std::is_move_constructible_v && std::is_move_assignable_v` is `true` for all `i`. ``` template constexpr variant& operator=(U&& u) 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))` defines the alternative `Tj` which is the type of the contained value after construction. Effects: :: - If `index() == j`, assigns `std::forward(u)` to the value contained in `*this`. - Otherwise, equivalent to `emplace(std::forward(u))`. Returns: :: `*this`. Ensures: :: `index() == j`. Remarks: :: The expression inside `noexcept` is `std::is_nothrow_constructible_v && std::is_nothrow_assignable_v`. This operator does not participate in overload resolution unless - `std::is_same_v, variant>` is `false`, - `std::is_constructible_v && std::is_assignable_v` is `true`, and - the expression `FUN(std::forward(u))` (with `FUN` being the above-mentioned set of imaginary functions) is well-formed. #### Modifiers ``` template constexpr U& emplace(A&&... a); ``` [none] * {blank} + Let `I` be the zero-based index of `U` in `T...`. Effects: :: Equivalent to: `return emplace(std::forward(a)...);` Remarks: :: This function shall not participate in overload resolution unless `std::is_constructible_v` is `true` and `U` occurs exactly once in `T...`. ``` template constexpr U& emplace(std::initializer_list il, A&&... a); ``` [none] * {blank} + Let `I` be the zero-based index of `U` in `T...`. Effects: :: Equivalent to: `return emplace(il, std::forward(a)...);` Remarks: :: This function shall not participate in overload resolution unless `std::is_constructible_v&, A...>` is `true` and `U` occurs exactly once in `T...`. ``` template constexpr variant_alternative_t>& emplace(A&&... a); ``` [none] * {blank} + Requires: :: `I < sizeof(T...)`. Effects: :: Destroys the currently contained value, then initializes a new contained value as if using the expression `Ti(std::forward(a)...)`. Ensures: :: `index() == I`. Returns: :: A reference to the new contained value. Remarks: :: This function shall not participate in overload resolution unless `std::is_constructible_v` is `true`. ``` template constexpr variant_alternative_t>& emplace(std::initializer_list il, A&&... a); ``` [none] * {blank} + Requires: :: `I < sizeof(T...)`. Effects: :: Destroys the currently contained value, then initializes a new contained value as if using the expression `Ti(il, std::forward(a)...)`. Ensures: :: `index() == I`. Returns: :: A reference to the new contained value. Remarks: :: This function shall not participate in overload resolution unless `std::is_constructible_v&, A...>` is `true`.