| // -*- C++ -*- |
| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef _LIBCPP_OPTIONAL |
| #define _LIBCPP_OPTIONAL |
| |
| /* |
| optional synopsis |
| |
| // C++1z |
| |
| namespace std { |
| // [optional.optional], class template optional |
| template <class T> |
| class optional; |
| |
| template<class T> |
| constexpr bool ranges::enable_view<optional<T>> = true; |
| template<class T> |
| constexpr auto format_kind<optional<T>> = range_format::disabled; |
| |
| template<class T> |
| concept is-derived-from-optional = requires(const T& t) { // exposition only |
| []<class U>(const optional<U>&){ }(t); |
| }; |
| |
| // [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>&); |
| template<class T, three_way_comparable_with<T> U> |
| constexpr compare_three_way_result_t<T, U> |
| operator<=>(const optional<T>&, const optional<U>&); // since C++20 |
| |
| // [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; // until C++17 |
| template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17 |
| template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17 |
| template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; // until C++17 |
| template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; // until C++17 |
| template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17 |
| template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17 |
| template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; // until C++17 |
| template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; // until C++17 |
| template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17 |
| template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17 |
| template<class T> |
| constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20 |
| |
| // [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>&); |
| template<class T, class U> |
| requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U> |
| constexpr compare_three_way_result_t<T, U> |
| operator<=>(const optional<T>&, const U&); // since C++20 |
| |
| // [optional.specalg], specialized algorithms |
| template<class T> |
| void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20 |
| |
| 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>>; |
| |
| template<class T> |
| class optional { |
| public: |
| using value_type = T; |
| using iterator = implementation-defined; // see [optional.iterators] |
| using const_iterator = implementation-defined; // see [optional.iterators] |
| |
| // [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 = remove_cv_t<T>> |
| constexpr explicit(see-below) optional(U &&); |
| template<class U> |
| explicit(see-below) optional(const optional<U> &); // constexpr in C++20 |
| template<class U> |
| explicit(see-below) optional(optional<U> &&); // constexpr in C++20 |
| |
| // [optional.dtor], destructor |
| ~optional(); // constexpr in C++20 |
| |
| // [optional.assign], assignment |
| optional &operator=(nullopt_t) noexcept; // constexpr in C++20 |
| constexpr optional &operator=(const optional &); |
| constexpr optional &operator=(optional &&) noexcept(see below); |
| template<class U = remove_cv_t<T>> optional &operator=(U &&); // constexpr in C++20 |
| template<class U> optional &operator=(const optional<U> &); // constexpr in C++20 |
| template<class U> optional &operator=(optional<U> &&); // constexpr in C++20 |
| template<class... Args> T& emplace(Args &&...); // constexpr in C++20 |
| template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20 |
| |
| // [optional.swap], swap |
| void swap(optional &) noexcept(see below ); // constexpr in C++20 |
| |
| // [optional.iterators], iterator support |
| constexpr iterator begin() noexcept; |
| constexpr const_iterator begin() const noexcept; |
| constexpr iterator end() noexcept; |
| constexpr const_iterator end() const noexcept; |
| |
| // [optional.observe], observers |
| constexpr T const *operator->() const noexcept; |
| constexpr T *operator->() noexcept; |
| constexpr T const &operator*() const & noexcept; |
| constexpr T &operator*() & noexcept; |
| constexpr T &&operator*() && noexcept; |
| constexpr const T &&operator*() const && noexcept; |
| constexpr explicit operator bool() const noexcept; |
| constexpr bool has_value() const noexcept; |
| constexpr T const &value() const &; |
| constexpr T &value() &; |
| constexpr T &&value() &&; |
| constexpr const T &&value() const &&; |
| template<class U = remove_cv_t<T>> constexpr T value_or(U &&) const &; |
| template<class U = remove_cv_t<T>> constexpr T value_or(U &&) &&; |
| |
| // [optional.monadic], monadic operations |
| template<class F> constexpr auto and_then(F&& f) &; // since C++23 |
| template<class F> constexpr auto and_then(F&& f) &&; // since C++23 |
| template<class F> constexpr auto and_then(F&& f) const&; // since C++23 |
| template<class F> constexpr auto and_then(F&& f) const&&; // since C++23 |
| template<class F> constexpr auto transform(F&& f) &; // since C++23 |
| template<class F> constexpr auto transform(F&& f) &&; // since C++23 |
| template<class F> constexpr auto transform(F&& f) const&; // since C++23 |
| template<class F> constexpr auto transform(F&& f) const&&; // since C++23 |
| template<class F> constexpr optional or_else(F&& f) &&; // since C++23 |
| template<class F> constexpr optional or_else(F&& f) const&; // since C++23 |
| |
| // [optional.mod], modifiers |
| void reset() noexcept; // constexpr in C++20 |
| |
| private: |
| T *val; // exposition only |
| }; |
| |
| template<class T> |
| optional(T) -> optional<T>; |
| |
| template<class T> |
| class optional<T&> { // since C++26 |
| public: |
| using value_type = T; |
| using iterator = implementation-defined; // see [optional.ref.iterators] |
| |
| public: |
| // [optional.ref.ctor], constructors |
| 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; |
| |
| // [optional.ref.assign], assignment |
| 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); |
| |
| // [optional.ref.swap], swap |
| constexpr void swap(optional& rhs) noexcept; |
| |
| // [optional.ref.iterators], iterator support |
| constexpr iterator begin() const noexcept; |
| constexpr iterator end() const noexcept; |
| |
| // [optional.ref.observe], observers |
| 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; // freestanding-deleted |
| template<class U = remove_cv_t<T>> |
| constexpr remove_cv_t<T> value_or(U&& u) const; |
| |
| // [optional.ref.monadic], monadic operations |
| 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; |
| |
| // [optional.ref.mod], modifiers |
| constexpr void reset() noexcept; |
| |
| private: |
| T* val = nullptr; // exposition only |
| |
| // [optional.ref.expos], exposition only helper functions |
| template<class U> |
| constexpr void convert-ref-init-val(U&& u); // exposition only |
| }; |
| |
| } // namespace std |
| |
| */ |
| |
| #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) |
| # include <__cxx03/__config> |
| #else |
| # include <__config> |
| # include <version> |
| |
| # include <__optional/common.h> |
| # include <__optional/comparison.h> |
| # include <__optional/hash.h> |
| # include <__optional/make_optional.h> |
| # include <__optional/optional.h> |
| # include <__optional/optional_ref.h> |
| # include <__optional/swap.h> |
| |
| // TODO: Some headers rely on these transitive includes |
| # include <__cstddef/size_t.h> |
| # include <__type_traits/conditional.h> |
| # include <__type_traits/enable_if.h> |
| # include <__type_traits/invoke.h> |
| # include <__type_traits/is_constructible.h> |
| # include <__type_traits/is_object.h> |
| # include <__type_traits/is_reference.h> |
| # include <__type_traits/remove_const.h> |
| # include <__type_traits/remove_cvref.h> |
| # include <__utility/declval.h> |
| # include <__utility/forward.h> |
| # include <__utility/in_place.h> |
| # include <__utility/move.h> |
| |
| # include <initializer_list> |
| |
| // standard-mandated includes |
| // [optional.syn] |
| # include <compare> |
| |
| # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| # pragma GCC system_header |
| # endif |
| |
| # if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 20 |
| # include <atomic> |
| # include <climits> |
| # include <concepts> |
| # include <ctime> |
| # include <iterator> |
| # include <limits> |
| # include <memory> |
| # include <ratio> |
| # include <stdexcept> |
| # include <tuple> |
| # include <type_traits> |
| # include <typeinfo> |
| # include <utility> |
| # include <variant> |
| # endif |
| #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) |
| |
| #endif // _LIBCPP_OPTIONAL |