22 General utilities library [utilities]
namespace std {
template<class T>
class optional<T&> {
public:
using value_type = T;
using iterator = implementation-defined;
public:
constexpr optional() noexcept = default;
constexpr optional(nullopt_t) noexcept : optional() {}
constexpr optional(const optional& rhs) noexcept = default;
template<class Arg>
constexpr explicit optional(in_place_t, Arg&& arg);
template<class U>
constexpr explicit(see below) optional(U&& u) noexcept(see below);
template<class U>
constexpr explicit(see below) optional(optional<U>& rhs) noexcept(see below);
template<class U>
constexpr explicit(see below) optional(const optional<U>& rhs) noexcept(see below);
template<class U>
constexpr explicit(see below) optional(optional<U>&& rhs) noexcept(see below);
template<class U>
constexpr explicit(see below) optional(const optional<U>&& rhs) noexcept(see below);
constexpr ~optional() = default;
constexpr optional& operator=(nullopt_t) noexcept;
constexpr optional& operator=(const optional& rhs) noexcept = default;
template<class U> constexpr T& emplace(U&& u) noexcept(see below);
constexpr void swap(optional& rhs) noexcept;
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
constexpr T* operator->() const noexcept;
constexpr T& operator*() const noexcept;
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr T& value() const;
template<class U = remove_cv_t<T>>
constexpr remove_cv_t<T> value_or(U&& u) const;
template<class F> constexpr auto and_then(F&& f) const;
template<class F> constexpr optional<invoke_result_t<F, T&>> transform(F&& f) const;
template<class F> constexpr optional or_else(F&& f) const;
constexpr void reset() noexcept;
private:
T* val = nullptr;
template<class U>
constexpr void convert-ref-init-val(U&& u);
};
}
An object of type
optional<T&>
contains a value
if and only if
val != nullptr is
true. When an
optional<T&> contains a value,
the
contained value
is a reference to
*val.template<class Arg>
constexpr explicit optional(in_place_t, Arg&& arg);
Constraints:
- is_constructible_v<T&, Arg> is true, and
- reference_constructs_from_temporary_v<T&, Arg> is false.
Effects: Equivalent to:
convert-ref-init-val(std::forward<Arg>(arg)). Postconditions:
*this contains a value
. template<class U>
constexpr explicit(!is_convertible_v<U, T&>)
optional(U&& u) noexcept(is_nothrow_constructible_v<T&, U>);
Constraints:
- is_same_v<remove_cvref_t<U>, optional> is false,
- is_same_v<remove_cvref_t<U>, in_place_t> is false, and
- is_constructible_v<T&, U> is true.
Effects: Equivalent to:
convert-ref-init-val(std::forward<U>(u)). Postconditions:
*this contains a value
. Remarks: This constructor is defined as deleted if
reference_constructs_from_temporary_v<T&, U>
is
true. template<class U>
constexpr explicit(!is_convertible_v<U&, T&>)
optional(optional<U>& rhs) noexcept(is_nothrow_constructible_v<T&, U&>);
Constraints:
- is_same_v<remove_cv_t<T>, optional<U>> is false,
- is_same_v<T&, U> is false, and
- is_constructible_v<T&, U&> is true.
Effects: Equivalent to:
if (rhs.has_value()) convert-ref-init-val(*rhs);
Remarks: This constructor is defined as deleted if
reference_constructs_from_temporary_v<T&, U&>
is
true. template<class U>
constexpr explicit(!is_convertible_v<const U&, T&>)
optional(const optional<U>& rhs) noexcept(is_nothrow_constructible_v<T&, const U&>);
Constraints:
- is_same_v<remove_cv_t<T>, optional<U>> is false,
- is_same_v<T&, U> is false, and
- is_constructible_v<T&, const U&> is true.
Effects: Equivalent to:
if (rhs.has_value()) convert-ref-init-val(*rhs);
Remarks: This constructor is defined as deleted if
reference_constructs_from_temporary_v<T&, const U&>
is
true. template<class U>
constexpr explicit(!is_convertible_v<U, T&>)
optional(optional<U>&& rhs) noexcept(is_nothrow_constructible_v<T&, U>);
Constraints:
- is_same_v<remove_cv_t<T>, optional<U>> is false,
- is_same_v<T&, U> is false, and
- is_constructible_v<T&, U> is true.
Effects: Equivalent to:
if (rhs.has_value()) convert-ref-init-val(*std::move(rhs));
Remarks: This constructor is defined as deleted if
reference_constructs_from_temporary_v<T&, U>
is
true. template<class U>
constexpr explicit(!is_convertible_v<const U, T&>)
optional(const optional<U>&& rhs) noexcept(is_nothrow_constructible_v<T&, const U>);
Constraints:
- is_same_v<remove_cv_t<T>, optional<U>> is false,
- is_same_v<T&, U> is false, and
- is_constructible_v<T&, const U> is true.
Effects: Equivalent to:
if (rhs.has_value()) convert-ref-init-val(*std::move(rhs));
Remarks: This constructor is defined as deleted if
reference_constructs_from_temporary_v<T&, const U>
is
true. constexpr optional& operator=(nullopt_t) noexcept;
Effects: Assigns
nullptr to
val. Postconditions:
*this does not contain a value
. template<class U>
constexpr T& emplace(U&& u) noexcept(is_nothrow_constructible_v<T&, U>);
Constraints:
- is_constructible_v<T&, U> is true, and
- reference_constructs_from_temporary_v<T&, U> is false.
Effects: Equivalent to:
convert-ref-init-val(std::forward<U>(u)). constexpr void swap(optional& rhs) noexcept;
Effects: Equivalent to:
swap(val, rhs.val). using iterator = implementation-defined;
The reference type is
T& for
iterator. constexpr iterator begin() const noexcept;
Returns: If
has_value() is
true,
an iterator referring to
*val. Otherwise, a past-the-end iterator value
.constexpr iterator end() const noexcept;
Returns:
begin() + has_value(). constexpr T* operator->() const noexcept;
Hardened preconditions:
has_value() is
true. constexpr T& operator*() const noexcept;
Hardened preconditions:
has_value() is
true. constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr T& value() const;
Effects: Equivalent to:
return has_value() ? *val : throw bad_optional_access();
template<class U = remove_cv_t<T>> constexpr remove_cv_t<T> value_or(U&& u) const;
Mandates:
is_constructible_v<X, T&> && is_convertible_v<U, X> is
true. Effects: Equivalent to:
return has_value() ? *val : static_cast<X>(std::forward<U>(u));
template<class F> constexpr auto and_then(F&& f) const;
Let
U be
invoke_result_t<F, T&>.Mandates:
remove_cvref_t<U> is a specialization of
optional. Effects: Equivalent to:
if (has_value()) {
return invoke(std::forward<F>(f), *val);
} else {
return remove_cvref_t<U>();
}
template<class F>
constexpr optional<remove_cv_t<invoke_result_t<F, T&>>> transform(F&& f) const;
Let
U be
remove_cv_t<invoke_result_t<F, T&>>.Mandates: The declaration
U u(invoke(std::forward<F>(f), *val));
is well-formed for some invented variable
u. Returns: If
*this contains a value, an
optional<U> object
whose contained value is direct-non-list-initialized with
invoke(std::forward<F>(f), *val);
otherwise,
optional<U>(). template<class F> constexpr optional or_else(F&& f) const;
Mandates:
is_same_v<remove_cvref_t<invoke_result_t<F>>, optional> is
true. Effects: Equivalent to:
if (has_value()) {
return *val;
} else {
return std::forward<F>(f)();
}
constexpr void reset() noexcept;
Effects: Assigns
nullptr to
val. Postconditions:
*this does not contain a value
. template<class U>
constexpr void convert-ref-init-val(U&& u);
Effects: Creates a variable
r as if by
T& r(std::forward<U>(u));
and then initializes
val with
addressof(r).