diff --git a/doc/variant/reference.adoc b/doc/variant/reference.adoc index 8040a7b..eed8867 100644 --- a/doc/variant/reference.adoc +++ b/doc/variant/reference.adoc @@ -69,66 +69,66 @@ constexpr std::size_t variant_npos = -1; // holds_alternative template - constexpr bool holds_alternative(const variant&) noexcept; + constexpr bool holds_alternative(const variant& v) noexcept; // get template constexpr variant_alternative_t>& - get(variant&); + get(variant& v); template constexpr variant_alternative_t>&& - get(variant&&); + get(variant&& v); template constexpr const variant_alternative_t>& - get(const variant&); + get(const variant& v); template constexpr const variant_alternative_t>&& - get(const variant&&); + get(const variant&& v); template - constexpr U& get(variant&); + constexpr U& get(variant& v); template - constexpr U&& get(variant&&); + constexpr U&& get(variant&& v); template - constexpr const U& get(const variant&); + constexpr const U& get(const variant& v); template - constexpr const U&& get(const variant&&); + constexpr const U&& get(const variant&& v); // get_if template constexpr add_pointer_t>> - get_if(variant*) noexcept; + get_if(variant* v) noexcept; template constexpr add_pointer_t>> - get_if(const variant*) noexcept; + get_if(const variant* v) noexcept; template constexpr add_pointer_t - get_if(variant*) noexcept; + get_if(variant* v) noexcept; template constexpr add_pointer_t - get_if(const variant*) noexcept; + get_if(const variant* v) noexcept; // relational operators template - constexpr bool operator==(const variant&, const variant&); + constexpr bool operator==(const variant& v, const variant& w); template - constexpr bool operator!=(const variant&, const variant&); + constexpr bool operator!=(const variant& v, const variant& w); template - constexpr bool operator<(const variant&, const variant&); + constexpr bool operator<(const variant& v, const variant& w); template - constexpr bool operator>(const variant&, const variant&); + constexpr bool operator>(const variant& v, const variant& w); template - constexpr bool operator<=(const variant&, const variant&); + constexpr bool operator<=(const variant& v, const variant& w); template - constexpr bool operator>=(const variant&, const variant&); + constexpr bool operator>=(const variant& v, const variant& w); // visit template - constexpr /*see below*/ visit(F&&, V&&...); + constexpr /*see below*/ visit(F&& f, V&&... v); // monostate @@ -144,7 +144,7 @@ constexpr bool operator>=(monostate, monostate) noexcept { return true; } // swap template - void swap(variant&, variant&) noexcept( see below ); + void swap(variant& v, variant& w) noexcept( /*see below*/ ); // bad_variant_access @@ -168,23 +168,23 @@ public: constexpr variant() noexcept( /*see below*/ ); - constexpr variant(variant const &) noexcept( /*see below*/ ); - constexpr variant(variant&&) noexcept( /*see below*/ ); + constexpr variant( variant const & r ) noexcept( /*see below*/ ); + constexpr variant( variant&& r ) noexcept( /*see below*/ ); template - constexpr variant(U&&) noexcept( /*see below*/ ); + constexpr variant( U&& u ) noexcept( /*see below*/ ); template - constexpr explicit variant(in_place_type_t, A&&...); + constexpr explicit variant( in_place_type_t, A&&... a ); template - constexpr explicit variant(in_place_type_t, std::initializer_list, - A&&...); + constexpr explicit variant( in_place_type_t, + std::initializer_list il, A&&... a ); template - constexpr explicit variant(in_place_index_t, A&&...); + constexpr explicit variant( in_place_index_t, A&&... a ); template - constexpr explicit variant(in_place_index_t, std::initializer_list, - A&&...); + constexpr explicit variant( in_place_index_t, + std::initializer_list il, A&&... a ); // destructor @@ -192,24 +192,24 @@ public: // assignment - constexpr variant& operator=(variant const &) noexcept( /*see below*/ ); - constexpr variant& operator=(variant&&) noexcept( /*see below*/ ); + constexpr variant& operator=( variant const & r ) noexcept( /*see below*/ ); + constexpr variant& operator=( variant&& r ) noexcept( /*see below*/ ); - template constexpr variant& operator=(U&&) noexcept( /*see below*/ ); + template constexpr variant& operator=( U&& u ) noexcept( /*see below*/ ); // modifiers template - constexpr U& emplace(A&&...); + constexpr U& emplace( A&&... a ); template - constexpr U& emplace(std::initializer_list, A&&...); + constexpr U& emplace( std::initializer_list il, A&&... a ); template constexpr variant_alternative_t>& - emplace(A&&...); + emplace( A&&... a ); template constexpr variant_alternative_t>& - emplace(std::initializer_list, A&&...); + emplace( std::initializer_list il, A&&... a ); // value status @@ -218,7 +218,7 @@ public: // swap - void swap(variant&) noexcept( /*see below*/ ); + void swap( variant& r ) noexcept( /*see below*/ ); // converting constructors (extension) @@ -243,7 +243,7 @@ public: #### Constructors ``` -constexpr variant() noexcept(std::is_nothrow_default_constructible_v); +constexpr variant() noexcept( std::is_nothrow_default_constructible_v ); ``` [none] * {blank} @@ -256,7 +256,7 @@ Remarks: :: This function does not participate in overload resolution unless `std::is_default_constructible_v` is `true`. ``` -constexpr variant(variant const & w) +constexpr variant( variant const & w ) noexcept( mp_all...>::value ); ``` [none] @@ -269,7 +269,7 @@ Remarks: :: This function does not participate in overload resolution unless `std::is_copy_constructible_v` is `true` for all `i`. ``` -constexpr variant(variant&& w) +constexpr variant( variant&& w ) noexcept( mp_all...>::value ); ``` [none] @@ -283,7 +283,7 @@ 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*/); +template constexpr variant( U&& u ) noexcept(/*see below*/); ``` [none] * {blank} @@ -309,7 +309,7 @@ specialization of `in_place_index_t`, ``` template - constexpr explicit variant(in_place_type_t, A&&... a); + constexpr explicit variant( in_place_type_t, A&&... a ); ``` [none] * {blank} @@ -324,8 +324,8 @@ Remarks: :: This function does not participate in overload resolution unless ``` template - constexpr explicit variant(in_place_type_t, std::initializer_list il, - A&&... a); + constexpr explicit variant( in_place_type_t, std::initializer_list il, + A&&... a ); ``` [none] * {blank} @@ -340,7 +340,7 @@ Remarks: :: This function does not participate in overload resolution unless ``` template - constexpr explicit variant(in_place_index_t, A&&... a); + constexpr explicit variant( in_place_index_t, A&&... a ); ``` [none] * {blank} @@ -354,8 +354,8 @@ Remarks: :: This function does not participate in overload resolution unless ``` template - constexpr explicit variant(in_place_index_t, std::initializer_list il, - A&&... a); + constexpr explicit variant( in_place_index_t, std::initializer_list il, + A&&... a ); ``` [none] * {blank} @@ -365,7 +365,7 @@ Effects: :: Initializes the contained value of type `TI` with the arguments 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 + `I < sizeof...(T)` and `std::is_constructible_v&, A...>` is `true`. #### Destructor @@ -381,47 +381,47 @@ Effects: :: Destroys the currently contained value. #### Assignment ``` -constexpr variant& operator=(const variant& rhs) +constexpr variant& operator=( const variant& r ) noexcept( mp_all..., std::is_nothrow_copy_assignable...>::value ); ``` [none] * {blank} + -Let `j` be `rhs.index()`. +Let `j` be `r.index()`. Effects: :: -- If `index() == j`, assigns the value contained in `rhs` to the value +- If `index() == j`, assigns the value contained in `r` to the value contained in `*this`. -- Otherwise, equivalent to `emplace(get(rhs))`. +- Otherwise, equivalent to `emplace(get(r))`. Returns: :: `*this`. -Ensures: :: `index() == rhs.index()`. +Ensures: :: `index() == r.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) +constexpr variant& operator=( variant&& r ) noexcept( mp_all..., std::is_nothrow_move_assignable...>::value ); ``` [none] * {blank} + -Let `j` be `rhs.index()`. +Let `j` be `r.index()`. Effects: :: -- If `index() == j`, assigns the value contained in `std::move(rhs)` to the +- If `index() == j`, assigns the value contained in `std::move(r)` to the value contained in `*this`. -- Otherwise, equivalent to `emplace(get(std::move(rhs)))`. +- Otherwise, equivalent to `emplace(get(std::move(r)))`. Returns: :: `*this`. -Ensures: :: `index() == rhs.index()`. +Ensures: :: `index() == r.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) +template constexpr variant& operator=( U&& u ) noexcept( /*see below*/ ); ``` [none] @@ -452,7 +452,7 @@ Remarks: :: ``` template - constexpr U& emplace(A&&... a); + constexpr U& emplace( A&&... a ); ``` [none] * {blank} @@ -467,7 +467,7 @@ Remarks: :: ``` template - constexpr U& emplace(std::initializer_list il, A&&... a); + constexpr U& emplace( std::initializer_list il, A&&... a ); ``` [none] * {blank} @@ -484,7 +484,7 @@ Remarks: :: ``` template constexpr variant_alternative_t>& - emplace(A&&... a); + emplace( A&&... a ); ``` [none] * {blank} @@ -502,7 +502,7 @@ Remarks: :: ``` template constexpr variant_alternative_t>& - emplace(std::initializer_list il, A&&... a); + emplace( std::initializer_list il, A&&... a ); ``` [none] * {blank} @@ -516,3 +516,332 @@ 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`. + +#### Value Status + +``` +constexpr bool valueless_by_exception() const noexcept; +``` +[none] +* {blank} ++ +Returns: :: `false`. + +``` +constexpr size_t index() const noexcept; +``` +[none] +* {blank} ++ +Returns: :: The zero-based index of the active alternative. + +#### Swap + +``` +void swap( variant& r ) noexcept( mp_all..., + is_nothrow_swappable...>::value ); +``` +[none] +* {blank} ++ +Effects: :: +- If `index() == r.index()`, calls `swap(get(*this), get(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 variant( variant const& r ) + noexcept( mp_all...>::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::value` is `true` for all `Ui`. + +``` +template variant( variant&& r ) + noexcept( mp_all...>::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::value` is `true` for all `Ui`. + +#### Subset (extension) + +``` +template constexpr variant subset() & ; +``` +``` +template constexpr variant subset() const& ; +``` +[none] +* {blank} ++ +Returns: :: A `variant` 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::value` is `true` for all `Ui`. + +``` +template constexpr variant subset() && ; +``` +``` +template constexpr variant subset() const&& ; +``` +[none] +* {blank} ++ +Returns: :: A `variant` 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::value` is `true` for all `Ui`. + +### variant_alternative + +``` +template struct variant_alternative; +``` +``` +template struct variant_alternative; +``` +``` +template struct variant_alternative; +``` +[none] +* {blank} ++ +-- +If `typename variant_alternative::type` exists and is `U`, + +* `variant_alternative::type` is `U const`; +* `variant_alternative::type` is `U volatile`; +* `variant_alternative::type` is `U const volatile`. + +Otherwise, the three structs have no `type` member. +-- + +``` +template + struct variant_alternative>; +``` +[none] +* {blank} ++ +When `I < sizeof...(T)`, the nested type `type` is an alias for the `I`-th +(zero-based) type in `T...`. Otherwise, there is no `type` member. + +### holds_alternative + +``` +template + constexpr bool holds_alternative(const variant& 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 + constexpr variant_alternative_t>& + get(variant& v); +``` +``` +template + constexpr variant_alternative_t>&& + get(variant&& v); +``` +``` +template + constexpr const variant_alternative_t>& + get(const variant& v); +``` +``` +template + constexpr const variant_alternative_t>&& + get(const variant&& v); +``` +[none] +* {blank} ++ +Effects: :: If `v.index()` is `I`, returns a reference to the object stored in + the variant. Otherwise, throws `bad_variant_access`. + +``` +template + constexpr U& get(variant& v); +``` +``` +template + constexpr U&& get(variant&& v); +``` +``` +template + constexpr const U& get(const variant& v); +``` +``` +template + constexpr const U&& get(const variant&& 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 + constexpr add_pointer_t>> + get_if(variant* v) noexcept; +``` +``` +template + constexpr add_pointer_t>> + get_if(const variant* v) noexcept; +``` +``` +template + constexpr add_pointer_t + get_if(variant* v) noexcept; +``` +``` +template + constexpr add_pointer_t + get_if(const variant* v) noexcept; +``` +[none] +* {blank} ++ +Requires: :: `I < sizeof...(U)`. Otherwise, the program is ill-formed. +Effects: :: A pointer to the value stored in the variant, if + `v != nullptr && v\->index() == I`. Otherwise, `nullptr`. + +### Relational Operators + +``` +template + constexpr bool operator==(const variant& v, const variant& w); +``` +[none] +* {blank} ++ +Returns: :: `v.index() == w.index && get(v) == get(w)`, where `I` + is `v.index()`. + +``` +template + constexpr bool operator!=(const variant& v, const variant& w); +``` +[none] +* {blank} ++ +Returns: :: `!(v == w)`. + +``` +template + constexpr bool operator<(const variant& v, const variant& w); +``` +[none] +* {blank} ++ +Returns: :: `v.index() < w.index || (v.index() == w.index && get(v) < get(w))`, + where `I` is `v.index()`. + +``` +template + constexpr bool operator>(const variant& v, const variant& w); +``` +[none] +* {blank} ++ +Returns: :: `w < v`. + +``` +template + constexpr bool operator<=(const variant& v, const variant& w); +``` +[none] +* {blank} ++ +Returns: :: `v.index() < w.index || (v.index() == w.index && get(v) \<= get(w))`, + where `I` is `v.index()`. + +``` +template + constexpr bool operator>=(const variant& v, const variant& w); +``` +[none] +* {blank} ++ +Returns: :: `w \<= v`. + +### visit + +``` +template + constexpr /*see below*/ visit(F&& f, V&&... v); +``` +[none] +* {blank} ++ +Returns: :: `std::forward(f)(get(std::forward(v))...)`, where + `I...` is `v.index()...`. + +### swap + +``` +template + void swap(variant& v, variant& w) noexcept( /*see below*/ ); +``` +[none] +* {blank} ++ +Effects: :: Equivalent to `v.swap(w)`. + +### 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"; + } +}; +```