1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_OPTIONAL
11#define _LIBCPP_OPTIONAL
12
13/*
14 optional synopsis
15
16// C++1z
17
18namespace std {
19 // [optional.optional], class template optional
20 template <class T>
21 class optional;
22
23 template<class T>
24 constexpr bool ranges::enable_view<optional<T>> = true;
25 template<class T>
26 constexpr auto format_kind<optional<T>> = range_format::disabled;
27
28 template<class T>
29 concept is-derived-from-optional = requires(const T& t) { // exposition only
30 []<class U>(const optional<U>&){ }(t);
31 };
32
33 // [optional.nullopt], no-value state indicator
34 struct nullopt_t{see below };
35 inline constexpr nullopt_t nullopt(unspecified );
36
37 // [optional.bad.access], class bad_optional_access
38 class bad_optional_access;
39
40 // [optional.relops], relational operators
41 template <class T, class U>
42 constexpr bool operator==(const optional<T>&, const optional<U>&);
43 template <class T, class U>
44 constexpr bool operator!=(const optional<T>&, const optional<U>&);
45 template <class T, class U>
46 constexpr bool operator<(const optional<T>&, const optional<U>&);
47 template <class T, class U>
48 constexpr bool operator>(const optional<T>&, const optional<U>&);
49 template <class T, class U>
50 constexpr bool operator<=(const optional<T>&, const optional<U>&);
51 template <class T, class U>
52 constexpr bool operator>=(const optional<T>&, const optional<U>&);
53 template<class T, three_way_comparable_with<T> U>
54 constexpr compare_three_way_result_t<T, U>
55 operator<=>(const optional<T>&, const optional<U>&); // since C++20
56
57 // [optional.nullops], comparison with nullopt
58 template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
59 template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17
60 template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17
61 template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17
62 template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; // until C++17
63 template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; // until C++17
64 template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17
65 template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17
66 template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; // until C++17
67 template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; // until C++17
68 template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17
69 template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17
70 template<class T>
71 constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20
72
73 // [optional.comp.with.t], comparison with T
74 template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
75 template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
76 template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
77 template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
78 template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
79 template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
80 template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
81 template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
82 template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
83 template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
84 template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
85 template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
86 template<class T, class U>
87 requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
88 constexpr compare_three_way_result_t<T, U>
89 operator<=>(const optional<T>&, const U&); // since C++20
90
91 // [optional.specalg], specialized algorithms
92 template<class T>
93 void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
94
95 template<class T>
96 constexpr optional<see below > make_optional(T&&);
97 template<class T, class... Args>
98 constexpr optional<T> make_optional(Args&&... args);
99 template<class T, class U, class... Args>
100 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
101
102 // [optional.hash], hash support
103 template<class T> struct hash;
104 template<class T> struct hash<optional<T>>;
105
106 template<class T>
107 class optional {
108 public:
109 using value_type = T;
110 using iterator = implementation-defined; // see [optional.iterators]
111 using const_iterator = implementation-defined; // see [optional.iterators]
112
113 // [optional.ctor], constructors
114 constexpr optional() noexcept;
115 constexpr optional(nullopt_t) noexcept;
116 constexpr optional(const optional &);
117 constexpr optional(optional &&) noexcept(see below);
118 template<class... Args>
119 constexpr explicit optional(in_place_t, Args &&...);
120 template<class U, class... Args>
121 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
122 template<class U = remove_cv_t<T>>
123 constexpr explicit(see-below) optional(U &&);
124 template<class U>
125 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
126 template<class U>
127 explicit(see-below) optional(optional<U> &&); // constexpr in C++20
128
129 // [optional.dtor], destructor
130 ~optional(); // constexpr in C++20
131
132 // [optional.assign], assignment
133 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
134 constexpr optional &operator=(const optional &);
135 constexpr optional &operator=(optional &&) noexcept(see below);
136 template<class U = remove_cv_t<T>> optional &operator=(U &&); // constexpr in C++20
137 template<class U> optional &operator=(const optional<U> &); // constexpr in C++20
138 template<class U> optional &operator=(optional<U> &&); // constexpr in C++20
139 template<class... Args> T& emplace(Args &&...); // constexpr in C++20
140 template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
141
142 // [optional.swap], swap
143 void swap(optional &) noexcept(see below ); // constexpr in C++20
144
145 // [optional.iterators], iterator support
146 constexpr iterator begin() noexcept;
147 constexpr const_iterator begin() const noexcept;
148 constexpr iterator end() noexcept;
149 constexpr const_iterator end() const noexcept;
150
151 // [optional.observe], observers
152 constexpr T const *operator->() const noexcept;
153 constexpr T *operator->() noexcept;
154 constexpr T const &operator*() const & noexcept;
155 constexpr T &operator*() & noexcept;
156 constexpr T &&operator*() && noexcept;
157 constexpr const T &&operator*() const && noexcept;
158 constexpr explicit operator bool() const noexcept;
159 constexpr bool has_value() const noexcept;
160 constexpr T const &value() const &;
161 constexpr T &value() &;
162 constexpr T &&value() &&;
163 constexpr const T &&value() const &&;
164 template<class U = remove_cv_t<T>> constexpr T value_or(U &&) const &;
165 template<class U = remove_cv_t<T>> constexpr T value_or(U &&) &&;
166
167 // [optional.monadic], monadic operations
168 template<class F> constexpr auto and_then(F&& f) &; // since C++23
169 template<class F> constexpr auto and_then(F&& f) &&; // since C++23
170 template<class F> constexpr auto and_then(F&& f) const&; // since C++23
171 template<class F> constexpr auto and_then(F&& f) const&&; // since C++23
172 template<class F> constexpr auto transform(F&& f) &; // since C++23
173 template<class F> constexpr auto transform(F&& f) &&; // since C++23
174 template<class F> constexpr auto transform(F&& f) const&; // since C++23
175 template<class F> constexpr auto transform(F&& f) const&&; // since C++23
176 template<class F> constexpr optional or_else(F&& f) &&; // since C++23
177 template<class F> constexpr optional or_else(F&& f) const&; // since C++23
178
179 // [optional.mod], modifiers
180 void reset() noexcept; // constexpr in C++20
181
182 private:
183 T *val; // exposition only
184 };
185
186 template<class T>
187 optional(T) -> optional<T>;
188
189 template<class T>
190 class optional<T&> { // since C++26
191 public:
192 using value_type = T;
193 using iterator = implementation-defined; // see [optional.ref.iterators]
194
195 public:
196 // [optional.ref.ctor], constructors
197 constexpr optional() noexcept = default;
198 constexpr optional(nullopt_t) noexcept : optional() {}
199 constexpr optional(const optional& rhs) noexcept = default;
200
201 template<class Arg>
202 constexpr explicit optional(in_place_t, Arg&& arg);
203 template<class U>
204 constexpr explicit(see below) optional(U&& u) noexcept(see below);
205 template<class U>
206 constexpr explicit(see below) optional(optional<U>& rhs) noexcept(see below);
207 template<class U>
208 constexpr explicit(see below) optional(const optional<U>& rhs) noexcept(see below);
209 template<class U>
210 constexpr explicit(see below) optional(optional<U>&& rhs) noexcept(see below);
211 template<class U>
212 constexpr explicit(see below) optional(const optional<U>&& rhs) noexcept(see below);
213
214 constexpr ~optional() = default;
215
216 // [optional.ref.assign], assignment
217 constexpr optional& operator=(nullopt_t) noexcept;
218 constexpr optional& operator=(const optional& rhs) noexcept = default;
219
220 template<class U> constexpr T& emplace(U&& u) noexcept(see below);
221
222 // [optional.ref.swap], swap
223 constexpr void swap(optional& rhs) noexcept;
224
225 // [optional.ref.iterators], iterator support
226 constexpr iterator begin() const noexcept;
227 constexpr iterator end() const noexcept;
228
229 // [optional.ref.observe], observers
230 constexpr T* operator->() const noexcept;
231 constexpr T& operator*() const noexcept;
232 constexpr explicit operator bool() const noexcept;
233 constexpr bool has_value() const noexcept;
234 constexpr T& value() const; // freestanding-deleted
235 template<class U = remove_cv_t<T>>
236 constexpr remove_cv_t<T> value_or(U&& u) const;
237
238 // [optional.ref.monadic], monadic operations
239 template<class F> constexpr auto and_then(F&& f) const;
240 template<class F> constexpr optional<invoke_result_t<F, T&>> transform(F&& f) const;
241 template<class F> constexpr optional or_else(F&& f) const;
242
243 // [optional.ref.mod], modifiers
244 constexpr void reset() noexcept;
245
246 private:
247 T* val = nullptr; // exposition only
248
249 // [optional.ref.expos], exposition only helper functions
250 template<class U>
251 constexpr void convert-ref-init-val(U&& u); // exposition only
252 };
253
254} // namespace std
255
256*/
257
258#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
259# include <__cxx03/__config>
260#else
261# include <__config>
262# include <version>
263
264# include <__optional/common.h>
265# include <__optional/comparison.h>
266# include <__optional/hash.h>
267# include <__optional/make_optional.h>
268# include <__optional/optional.h>
269# include <__optional/optional_ref.h>
270# include <__optional/swap.h>
271
272# include <initializer_list>
273
274// standard-mandated includes
275// [optional.syn]
276# include <compare>
277
278# if _LIBCPP_STD_VER >= 26
279// [iterator.range]
280# include <__iterator/access.h>
281# include <__iterator/data.h>
282# include <__iterator/empty.h>
283# include <__iterator/reverse_access.h>
284# include <__iterator/size.h>
285# endif // _LIBCPP_STD_VER >= 26
286
287# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
288# pragma GCC system_header
289# endif
290
291#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
292
293#endif // _LIBCPP_OPTIONAL
294