[expected.object.assign] (original) (raw)
22 General utilities library [utilities]
22.8 Expected objects [expected]
22.8.6 Class template expected [expected.expected]
22.8.6.4 Assignment [expected.object.assign]
This subclause makes use of the following exposition-only function template:template<class T, class U, class... Args> constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { if constexpr (is_nothrow_constructible_v<T, Args...>) { destroy_at(addressof(oldval)); construct_at(addressof(newval), std::forward<Args>(args)...);} else if constexpr (is_nothrow_move_constructible_v<T>) { T tmp(std::forward<Args>(args)...); destroy_at(addressof(oldval)); construct_at(addressof(newval), std::move(tmp));} else { U tmp(std::move(oldval)); destroy_at(addressof(oldval));try { construct_at(addressof(newval), std::forward<Args>(args)...);} catch (...) { construct_at(addressof(oldval), std::move(tmp));throw;} } }
constexpr expected& operator=(const expected& rhs);
Effects:
- If this->has_value() && rhs.has_value() is true, equivalent to val = *rhs.
- Otherwise, if this->has_value() is true, equivalent to:reinit-expected(unex, val, rhs.error())
- Otherwise, if rhs.has_value() is true, equivalent to:reinit-expected(val, unex, *rhs)
- Otherwise, equivalent to unex = rhs.error().
Then, if no exception was thrown, equivalent to: has_val = rhs.has_value(); return *this;
Remarks: This operator is defined as deleted unless:
- is_copy_assignable_v<T> is true and
- is_copy_constructible_v<T> is true and
- is_copy_assignable_v<E> is true and
- is_copy_constructible_v<E> is true and
- is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>is true.
constexpr expected& operator=(expected&& rhs) noexcept(_see below_);
Constraints:
- is_move_constructible_v<T> is true and
- is_move_assignable_v<T> is true and
- is_move_constructible_v<E> is true and
- is_move_assignable_v<E> is true and
- is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>is true.
Effects:
- If this->has_value() && rhs.has_value() is true, equivalent to val = std::move(*rhs).
- Otherwise, if this->has_value() is true, equivalent to:reinit-expected(unex, val, std::move(rhs.error()))
- Otherwise, if rhs.has_value() is true, equivalent to:reinit-expected(val, unex, std::move(*rhs))
- Otherwise, equivalent to unex = std::move(rhs.error()).
Then, if no exception was thrown, equivalent to: has_val = rhs.has_value(); return *this;
Remarks: The exception specification is equivalent to:is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
template<class U = remove_cv_t<T>> constexpr expected& operator=(U&& v);
Constraints:
- is_same_v<expected, remove_cvref_t<U>> is false; and
- remove_cvref_t<U> is not a specialization of unexpected; and
- is_constructible_v<T, U> is true; and
- is_assignable_v<T&, U> is true; and
- is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> ||
is_nothrow_move_constructible_v<E>is true.
Effects:
- If has_value() is true, equivalent to: val = std::forward<U>(v);
- Otherwise, equivalent to:reinit-expected(val, unex, std::forward<U>(v));has_val = true;
template<class G> constexpr expected& operator=(const unexpected<G>& e);template<class G> constexpr expected& operator=(unexpected<G>&& e);
Let GF be const G& for the first overload andG for the second overload.
Constraints:
- is_constructible_v<E, GF> is true; and
- is_assignable_v<E&, GF> is true; and
- is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
is_nothrow_move_constructible_v<E> is true.
Effects:
- If has_value() is true, equivalent to:reinit-expected(unex, val, std::forward<GF>(e.error()));has_val = false;
- Otherwise, equivalent to:unex = std::forward<GF>(e.error());
template<class... Args> constexpr T& emplace(Args&&... args) noexcept;
Constraints: is_nothrow_constructible_v<T, Args...> is true.
Effects: Equivalent to:if (has_value()) { destroy_at(addressof(val));} else { destroy_at(addressof(unex));has_val = true;} return *construct_at(addressof(val), std::forward<Args>(args)...);
template<class U, class... Args> constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept;
Constraints: is_nothrow_constructible_v<T, initializer_list<U>&, Args...>is true.
Effects: Equivalent to:if (has_value()) { destroy_at(addressof(val));} else { destroy_at(addressof(unex));has_val = true;} return *construct_at(addressof(val), il, std::forward<Args>(args)...);