namespace std {
// [optional.optional], class template optional
template<class T>
class optional;
// [optional.nullopt], no-value state indicator
struct nullopt_t{see below};
inline constexpr nullopt_t nullopt(unspecified);
// [optional.bad.access], class bad_optional_access
class bad_optional_access;
// [optional.relops], relational operators
template<class T, class U>
constexpr bool operator==(const optional<T>&, const optional<U>&);
template<class T, class U>
constexpr bool operator!=(const optional<T>&, const optional<U>&);
template<class T, class U>
constexpr bool operator<(const optional<T>&, const optional<U>&);
template<class T, class U>
constexpr bool operator>(const optional<T>&, const optional<U>&);
template<class T, class U>
constexpr bool operator<=(const optional<T>&, const optional<U>&);
template<class T, class U>
constexpr bool operator>=(const optional<T>&, const optional<U>&);
// [optional.nullops], comparison with nullopt
template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
// [optional.comp_with_t], comparison with T
template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
// [optional.specalg], specialized algorithms
template<class T>
void swap(optional<T>&, optional<T>&) noexcept(see below);
template<class T>
constexpr optional<see below> make_optional(T&&);
template<class T, class... Args>
constexpr optional<T> make_optional(Args&&... args);
template<class T, class U, class... Args>
constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
// [optional.hash], hash support
template<class T> struct hash;
template<class T> struct hash<optional<T>>;
}
namespace std {
template<class T>
class optional {
public:
using value_type = T;
// [optional.ctor], constructors
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
constexpr optional(const optional&);
constexpr optional(optional&&) noexcept(see below);
template<class... Args>
constexpr explicit optional(in_place_t, Args&&...);
template<class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
template<class U = T>
explicit(see below) constexpr optional(U&&);
template<class U>
explicit(see below) optional(const optional<U>&);
template<class U>
explicit(see below) optional(optional<U>&&);
// [optional.dtor], destructor
~optional();
// [optional.assign], assignment
optional& operator=(nullopt_t) noexcept;
optional& operator=(const optional&);
optional& operator=(optional&&) noexcept(see below);
template<class U = T> optional& operator=(U&&);
template<class U> optional& operator=(const optional<U>&);
template<class U> optional& operator=(optional<U>&&);
template<class... Args> T& emplace(Args&&...);
template<class U, class... Args> T& emplace(initializer_list<U>, Args&&...);
// [optional.swap], swap
void swap(optional&) noexcept(see below);
// [optional.observe], observers
constexpr const T* operator->() const;
constexpr T* operator->();
constexpr const T& operator*() const&;
constexpr T& operator*() &;
constexpr T&& operator*() &&;
constexpr const T&& operator*() const&&;
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr const T& value() const&;
constexpr T& value() &;
constexpr T&& value() &&;
constexpr const T&& value() const&&;
template<class U> constexpr T value_or(U&&) const&;
template<class U> constexpr T value_or(U&&) &&;
// [optional.mod], modifiers
void reset() noexcept;
private:
T *val; // exposition only
};
template<class T>
optional(T) -> optional<T>;
}constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
constexpr optional(const optional& rhs);
constexpr optional(optional&& rhs) noexcept(see below);
template<class... Args> constexpr explicit optional(in_place_t, Args&&... args);
template<class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
template<class U = T> explicit(see below) constexpr optional(U&& v);
!is_convertible_v<U, T>
template<class U> explicit(see below) optional(const optional<U>& rhs);
!is_convertible_v<const U&, T>
template<class U> explicit(see below) optional(optional<U>&& rhs);
!is_convertible_v<U, T>
~optional();
val->T::~T()
optional<T>& operator=(nullopt_t) noexcept;
optional<T>& operator=(const optional& rhs);
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns *rhs to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with *rhs |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
optional<T>& operator=(optional&& rhs) noexcept(see below);
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns std::move(*rhs) to the contained value | initializes the contained value as if direct-non-list-initializing an object of type T with std::move(*rhs) |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
template<class U = T> optional<T>& operator=(U&& v);
template<class U> optional<T>& operator=(const optional<U>& rhs);
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns *rhs to the contained value | initializes the contained value as if direct-non-list-initializing
an object of type T with *rhs |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
template<class U> optional<T>& operator=(optional<U>&& rhs);
*this contains a value | *this does not contain a value | |
rhs contains a value | assigns std::move(*rhs) to the contained value | initializes the contained value as if direct-non-list-initializing
an object of type T with std::move(*rhs) |
rhs does not contain a value | destroys the contained value by calling val->T::~T() | no effect |
template<class... Args> T& emplace(Args&&... args);
template<class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
void swap(optional& rhs) noexcept(see below);
*this contains a value | *this does not contain a value | |
rhs contains a value | calls swap(*(*this), *rhs) | initializes the contained value of *this as if
direct-non-list-initializing an object of type T with the expression std::move(*rhs),
followed by rhs.val->T::~T();
postcondition is that *this contains a value and rhs does not contain a value |
rhs does not contain a value | initializes the contained value of rhs as if
direct-non-list-initializing an object of type T with the expression std::move(*(*this)),
followed by val->T::~T();
postcondition is that *this does not contain a value and rhs contains a value | no effect |
is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>If any exception is thrown, the results of the expressions bool(*this) and bool(rhs) remain unchanged.
constexpr const T* operator->() const;
constexpr T* operator->();
constexpr const T& operator*() const&;
constexpr T& operator*() &;
constexpr T&& operator*() &&;
constexpr const T&& operator*() const&&;
constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
constexpr const T& value() const&;
constexpr T& value() &;
constexpr T&& value() &&;
constexpr const T&& value() const&&;
template<class U> constexpr T value_or(U&& v) const&;
template<class U> constexpr T value_or(U&& v) &&;
return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
struct nullopt_t{see below};
inline constexpr nullopt_t nullopt(unspecified);
class bad_optional_access : public exception {
public:
bad_optional_access();
};bad_optional_access();
template<class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
template<class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
template<class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
template<class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
template<class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
template<class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
template<class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
template<class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
template<class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator==(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator<(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator>(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x);
template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
template<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x);
template<class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
template<class T> constexpr optional<decay_t<T>> make_optional(T&& v);
template<class T, class...Args>
constexpr optional<T> make_optional(Args&&... args);
template<class T, class U, class... Args>
constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
template<class T> struct hash<optional<T>>;