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 | |
18 | namespace std { |
19 | // [optional.optional], class template optional |
20 | template <class T> |
21 | class optional; |
22 | |
23 | template<class T> |
24 | concept is-derived-from-optional = requires(const T& t) { // exposition only |
25 | []<class U>(const optional<U>&){ }(t); |
26 | }; |
27 | |
28 | // [optional.nullopt], no-value state indicator |
29 | struct nullopt_t{see below }; |
30 | inline constexpr nullopt_t nullopt(unspecified ); |
31 | |
32 | // [optional.bad.access], class bad_optional_access |
33 | class bad_optional_access; |
34 | |
35 | // [optional.relops], relational operators |
36 | template <class T, class U> |
37 | constexpr bool operator==(const optional<T>&, const optional<U>&); |
38 | template <class T, class U> |
39 | constexpr bool operator!=(const optional<T>&, const optional<U>&); |
40 | template <class T, class U> |
41 | constexpr bool operator<(const optional<T>&, const optional<U>&); |
42 | template <class T, class U> |
43 | constexpr bool operator>(const optional<T>&, const optional<U>&); |
44 | template <class T, class U> |
45 | constexpr bool operator<=(const optional<T>&, const optional<U>&); |
46 | template <class T, class U> |
47 | constexpr bool operator>=(const optional<T>&, const optional<U>&); |
48 | template<class T, three_way_comparable_with<T> U> |
49 | constexpr compare_three_way_result_t<T, U> |
50 | operator<=>(const optional<T>&, const optional<U>&); // since C++20 |
51 | |
52 | // [optional.nullops], comparison with nullopt |
53 | template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; |
54 | template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17 |
55 | template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17 |
56 | template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17 |
57 | template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; // until C++17 |
58 | template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; // until C++17 |
59 | template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17 |
60 | template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17 |
61 | template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; // until C++17 |
62 | template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; // until C++17 |
63 | template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17 |
64 | template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17 |
65 | template<class T> |
66 | constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20 |
67 | |
68 | // [optional.comp.with.t], comparison with T |
69 | template<class T, class U> constexpr bool operator==(const optional<T>&, const U&); |
70 | template<class T, class U> constexpr bool operator==(const T&, const optional<U>&); |
71 | template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&); |
72 | template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&); |
73 | template<class T, class U> constexpr bool operator<(const optional<T>&, const U&); |
74 | template<class T, class U> constexpr bool operator<(const T&, const optional<U>&); |
75 | template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&); |
76 | template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&); |
77 | template<class T, class U> constexpr bool operator>(const optional<T>&, const U&); |
78 | template<class T, class U> constexpr bool operator>(const T&, const optional<U>&); |
79 | template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); |
80 | template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); |
81 | template<class T, class U> |
82 | requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U> |
83 | constexpr compare_three_way_result_t<T, U> |
84 | operator<=>(const optional<T>&, const U&); // since C++20 |
85 | |
86 | // [optional.specalg], specialized algorithms |
87 | template<class T> |
88 | void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20 |
89 | |
90 | template<class T> |
91 | constexpr optional<see below > make_optional(T&&); |
92 | template<class T, class... Args> |
93 | constexpr optional<T> make_optional(Args&&... args); |
94 | template<class T, class U, class... Args> |
95 | constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); |
96 | |
97 | // [optional.hash], hash support |
98 | template<class T> struct hash; |
99 | template<class T> struct hash<optional<T>>; |
100 | |
101 | template<class T> |
102 | class optional { |
103 | public: |
104 | using value_type = T; |
105 | |
106 | // [optional.ctor], constructors |
107 | constexpr optional() noexcept; |
108 | constexpr optional(nullopt_t) noexcept; |
109 | constexpr optional(const optional &); |
110 | constexpr optional(optional &&) noexcept(see below); |
111 | template<class... Args> |
112 | constexpr explicit optional(in_place_t, Args &&...); |
113 | template<class U, class... Args> |
114 | constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); |
115 | template<class U = T> |
116 | constexpr explicit(see-below) optional(U &&); |
117 | template<class U> |
118 | explicit(see-below) optional(const optional<U> &); // constexpr in C++20 |
119 | template<class U> |
120 | explicit(see-below) optional(optional<U> &&); // constexpr in C++20 |
121 | |
122 | // [optional.dtor], destructor |
123 | ~optional(); // constexpr in C++20 |
124 | |
125 | // [optional.assign], assignment |
126 | optional &operator=(nullopt_t) noexcept; // constexpr in C++20 |
127 | constexpr optional &operator=(const optional &); |
128 | constexpr optional &operator=(optional &&) noexcept(see below); |
129 | template<class U = T> optional &operator=(U &&); // constexpr in C++20 |
130 | template<class U> optional &operator=(const optional<U> &); // constexpr in C++20 |
131 | template<class U> optional &operator=(optional<U> &&); // constexpr in C++20 |
132 | template<class... Args> T& emplace(Args &&...); // constexpr in C++20 |
133 | template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20 |
134 | |
135 | // [optional.swap], swap |
136 | void swap(optional &) noexcept(see below ); // constexpr in C++20 |
137 | |
138 | // [optional.observe], observers |
139 | constexpr T const *operator->() const noexcept; |
140 | constexpr T *operator->() noexcept; |
141 | constexpr T const &operator*() const & noexcept; |
142 | constexpr T &operator*() & noexcept; |
143 | constexpr T &&operator*() && noexcept; |
144 | constexpr const T &&operator*() const && noexcept; |
145 | constexpr explicit operator bool() const noexcept; |
146 | constexpr bool has_value() const noexcept; |
147 | constexpr T const &value() const &; |
148 | constexpr T &value() &; |
149 | constexpr T &&value() &&; |
150 | constexpr const T &&value() const &&; |
151 | template<class U> constexpr T value_or(U &&) const &; |
152 | template<class U> constexpr T value_or(U &&) &&; |
153 | |
154 | // [optional.monadic], monadic operations |
155 | template<class F> constexpr auto and_then(F&& f) &; // since C++23 |
156 | template<class F> constexpr auto and_then(F&& f) &&; // since C++23 |
157 | template<class F> constexpr auto and_then(F&& f) const&; // since C++23 |
158 | template<class F> constexpr auto and_then(F&& f) const&&; // since C++23 |
159 | template<class F> constexpr auto transform(F&& f) &; // since C++23 |
160 | template<class F> constexpr auto transform(F&& f) &&; // since C++23 |
161 | template<class F> constexpr auto transform(F&& f) const&; // since C++23 |
162 | template<class F> constexpr auto transform(F&& f) const&&; // since C++23 |
163 | template<class F> constexpr optional or_else(F&& f) &&; // since C++23 |
164 | template<class F> constexpr optional or_else(F&& f) const&; // since C++23 |
165 | |
166 | // [optional.mod], modifiers |
167 | void reset() noexcept; // constexpr in C++20 |
168 | |
169 | private: |
170 | T *val; // exposition only |
171 | }; |
172 | |
173 | template<class T> |
174 | optional(T) -> optional<T>; |
175 | |
176 | } // namespace std |
177 | |
178 | */ |
179 | |
180 | #include <__assert> |
181 | #include <__compare/compare_three_way_result.h> |
182 | #include <__compare/three_way_comparable.h> |
183 | #include <__concepts/invocable.h> |
184 | #include <__config> |
185 | #include <__exception/exception.h> |
186 | #include <__functional/hash.h> |
187 | #include <__functional/invoke.h> |
188 | #include <__functional/unary_function.h> |
189 | #include <__fwd/functional.h> |
190 | #include <__memory/addressof.h> |
191 | #include <__memory/construct_at.h> |
192 | #include <__tuple/sfinae_helpers.h> |
193 | #include <__type_traits/add_pointer.h> |
194 | #include <__type_traits/conditional.h> |
195 | #include <__type_traits/conjunction.h> |
196 | #include <__type_traits/decay.h> |
197 | #include <__type_traits/disjunction.h> |
198 | #include <__type_traits/is_array.h> |
199 | #include <__type_traits/is_assignable.h> |
200 | #include <__type_traits/is_constructible.h> |
201 | #include <__type_traits/is_convertible.h> |
202 | #include <__type_traits/is_destructible.h> |
203 | #include <__type_traits/is_nothrow_assignable.h> |
204 | #include <__type_traits/is_nothrow_constructible.h> |
205 | #include <__type_traits/is_object.h> |
206 | #include <__type_traits/is_reference.h> |
207 | #include <__type_traits/is_scalar.h> |
208 | #include <__type_traits/is_swappable.h> |
209 | #include <__type_traits/is_trivially_assignable.h> |
210 | #include <__type_traits/is_trivially_constructible.h> |
211 | #include <__type_traits/is_trivially_destructible.h> |
212 | #include <__type_traits/is_trivially_relocatable.h> |
213 | #include <__type_traits/negation.h> |
214 | #include <__type_traits/remove_const.h> |
215 | #include <__type_traits/remove_cvref.h> |
216 | #include <__type_traits/remove_reference.h> |
217 | #include <__utility/declval.h> |
218 | #include <__utility/forward.h> |
219 | #include <__utility/in_place.h> |
220 | #include <__utility/move.h> |
221 | #include <__utility/swap.h> |
222 | #include <__verbose_abort> |
223 | #include <initializer_list> |
224 | #include <new> |
225 | #include <version> |
226 | |
227 | // standard-mandated includes |
228 | |
229 | // [optional.syn] |
230 | #include <compare> |
231 | |
232 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
233 | # pragma GCC system_header |
234 | #endif |
235 | |
236 | _LIBCPP_PUSH_MACROS |
237 | #include <__undef_macros> |
238 | |
239 | namespace std // purposefully not using versioning namespace |
240 | { |
241 | |
242 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access : public exception { |
243 | public: |
244 | _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT = default; |
245 | _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT = default; |
246 | _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default; |
247 | // Get the key function ~bad_optional_access() into the dylib |
248 | ~bad_optional_access() _NOEXCEPT override; |
249 | const char* what() const _NOEXCEPT override; |
250 | }; |
251 | |
252 | } // namespace std |
253 | |
254 | #if _LIBCPP_STD_VER >= 17 |
255 | |
256 | _LIBCPP_BEGIN_NAMESPACE_STD |
257 | |
258 | _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS void |
259 | __throw_bad_optional_access() { |
260 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
261 | throw bad_optional_access(); |
262 | # else |
263 | _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode" ); |
264 | # endif |
265 | } |
266 | |
267 | struct nullopt_t { |
268 | struct __secret_tag { |
269 | explicit __secret_tag() = default; |
270 | }; |
271 | _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} |
272 | }; |
273 | |
274 | inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; |
275 | |
276 | struct __optional_construct_from_invoke_tag {}; |
277 | |
278 | template <class _Tp, bool = is_trivially_destructible<_Tp>::value> |
279 | struct __optional_destruct_base; |
280 | |
281 | template <class _Tp> |
282 | struct __optional_destruct_base<_Tp, false> { |
283 | typedef _Tp value_type; |
284 | static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior" ); |
285 | union { |
286 | char __null_state_; |
287 | value_type __val_; |
288 | }; |
289 | bool __engaged_; |
290 | |
291 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() { |
292 | if (__engaged_) |
293 | __val_.~value_type(); |
294 | } |
295 | |
296 | _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {} |
297 | |
298 | template <class... _Args> |
299 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) |
300 | : __val_(std::forward<_Args>(__args)...), __engaged_(true) {} |
301 | |
302 | # if _LIBCPP_STD_VER >= 23 |
303 | template <class _Fp, class... _Args> |
304 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base( |
305 | __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) |
306 | : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {} |
307 | # endif |
308 | |
309 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { |
310 | if (__engaged_) { |
311 | __val_.~value_type(); |
312 | __engaged_ = false; |
313 | } |
314 | } |
315 | }; |
316 | |
317 | template <class _Tp> |
318 | struct __optional_destruct_base<_Tp, true> { |
319 | typedef _Tp value_type; |
320 | static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior" ); |
321 | union { |
322 | char __null_state_; |
323 | value_type __val_; |
324 | }; |
325 | bool __engaged_; |
326 | |
327 | _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {} |
328 | |
329 | template <class... _Args> |
330 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) |
331 | : __val_(std::forward<_Args>(__args)...), __engaged_(true) {} |
332 | |
333 | # if _LIBCPP_STD_VER >= 23 |
334 | template <class _Fp, class... _Args> |
335 | _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base( |
336 | __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) |
337 | : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {} |
338 | # endif |
339 | |
340 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { |
341 | if (__engaged_) { |
342 | __engaged_ = false; |
343 | } |
344 | } |
345 | }; |
346 | |
347 | template <class _Tp, bool = is_reference<_Tp>::value> |
348 | struct __optional_storage_base : __optional_destruct_base<_Tp> { |
349 | using __base = __optional_destruct_base<_Tp>; |
350 | using value_type = _Tp; |
351 | using __base::__base; |
352 | |
353 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; } |
354 | |
355 | _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; } |
356 | _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; } |
357 | _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() && noexcept { return std::move(this->__val_); } |
358 | _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& __get() const&& noexcept { return std::move(this->__val_); } |
359 | |
360 | template <class... _Args> |
361 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) { |
362 | _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage" ); |
363 | std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...); |
364 | this->__engaged_ = true; |
365 | } |
366 | |
367 | template <class _That> |
368 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) { |
369 | if (__opt.has_value()) |
370 | __construct(std::forward<_That>(__opt).__get()); |
371 | } |
372 | |
373 | template <class _That> |
374 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) { |
375 | if (this->__engaged_ == __opt.has_value()) { |
376 | if (this->__engaged_) |
377 | this->__val_ = std::forward<_That>(__opt).__get(); |
378 | } else { |
379 | if (this->__engaged_) |
380 | this->reset(); |
381 | else |
382 | __construct(std::forward<_That>(__opt).__get()); |
383 | } |
384 | } |
385 | }; |
386 | |
387 | // optional<T&> is currently required to be ill-formed. However, it may |
388 | // be allowed in the future. For this reason, it has already been implemented |
389 | // to ensure we can make the change in an ABI-compatible manner. |
390 | template <class _Tp> |
391 | struct __optional_storage_base<_Tp, true> { |
392 | using value_type = _Tp; |
393 | using __raw_type = remove_reference_t<_Tp>; |
394 | __raw_type* __value_; |
395 | |
396 | template <class _Up> |
397 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() { |
398 | using _RawUp = __libcpp_remove_reference_t<_Up>; |
399 | using _UpPtr = _RawUp*; |
400 | using _RawTp = __libcpp_remove_reference_t<_Tp>; |
401 | using _TpPtr = _RawTp*; |
402 | using _CheckLValueArg = |
403 | integral_constant<bool, |
404 | (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) || |
405 | is_same<_RawUp, reference_wrapper<_RawTp>>::value || |
406 | is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >; |
407 | return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) || |
408 | (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && |
409 | is_convertible<_UpPtr, _TpPtr>::value); |
410 | } |
411 | |
412 | _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {} |
413 | |
414 | template <class _UArg> |
415 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) |
416 | : __value_(std::addressof(__uarg)) { |
417 | static_assert(__can_bind_reference<_UArg>(), |
418 | "Attempted to construct a reference element in tuple from a " |
419 | "possible temporary" ); |
420 | } |
421 | |
422 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; } |
423 | |
424 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; } |
425 | |
426 | _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const& noexcept { return *__value_; } |
427 | |
428 | _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() const&& noexcept { return std::forward<value_type>(*__value_); } |
429 | |
430 | template <class _UArg> |
431 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) { |
432 | _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage" ); |
433 | static_assert(__can_bind_reference<_UArg>(), |
434 | "Attempted to construct a reference element in tuple from a " |
435 | "possible temporary" ); |
436 | __value_ = std::addressof(__val); |
437 | } |
438 | |
439 | template <class _That> |
440 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) { |
441 | if (__opt.has_value()) |
442 | __construct(std::forward<_That>(__opt).__get()); |
443 | } |
444 | |
445 | template <class _That> |
446 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) { |
447 | if (has_value() == __opt.has_value()) { |
448 | if (has_value()) |
449 | *__value_ = std::forward<_That>(__opt).__get(); |
450 | } else { |
451 | if (has_value()) |
452 | reset(); |
453 | else |
454 | __construct(std::forward<_That>(__opt).__get()); |
455 | } |
456 | } |
457 | }; |
458 | |
459 | template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value> |
460 | struct __optional_copy_base : __optional_storage_base<_Tp> { |
461 | using __optional_storage_base<_Tp>::__optional_storage_base; |
462 | }; |
463 | |
464 | template <class _Tp> |
465 | struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> { |
466 | using __optional_storage_base<_Tp>::__optional_storage_base; |
467 | |
468 | _LIBCPP_HIDE_FROM_ABI __optional_copy_base() = default; |
469 | |
470 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) { |
471 | this->__construct_from(__opt); |
472 | } |
473 | |
474 | _LIBCPP_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default; |
475 | _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default; |
476 | _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default; |
477 | }; |
478 | |
479 | template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value> |
480 | struct __optional_move_base : __optional_copy_base<_Tp> { |
481 | using __optional_copy_base<_Tp>::__optional_copy_base; |
482 | }; |
483 | |
484 | template <class _Tp> |
485 | struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> { |
486 | using value_type = _Tp; |
487 | using __optional_copy_base<_Tp>::__optional_copy_base; |
488 | |
489 | _LIBCPP_HIDE_FROM_ABI __optional_move_base() = default; |
490 | _LIBCPP_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default; |
491 | |
492 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
493 | __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v<value_type>) { |
494 | this->__construct_from(std::move(__opt)); |
495 | } |
496 | |
497 | _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default; |
498 | _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default; |
499 | }; |
500 | |
501 | template <class _Tp, |
502 | bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value && |
503 | is_trivially_copy_assignable<_Tp>::value> |
504 | struct __optional_copy_assign_base : __optional_move_base<_Tp> { |
505 | using __optional_move_base<_Tp>::__optional_move_base; |
506 | }; |
507 | |
508 | template <class _Tp> |
509 | struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> { |
510 | using __optional_move_base<_Tp>::__optional_move_base; |
511 | |
512 | _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base() = default; |
513 | _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default; |
514 | _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default; |
515 | |
516 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& |
517 | operator=(const __optional_copy_assign_base& __opt) { |
518 | this->__assign_from(__opt); |
519 | return *this; |
520 | } |
521 | |
522 | _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default; |
523 | }; |
524 | |
525 | template <class _Tp, |
526 | bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value && |
527 | is_trivially_move_assignable<_Tp>::value> |
528 | struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> { |
529 | using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; |
530 | }; |
531 | |
532 | template <class _Tp> |
533 | struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> { |
534 | using value_type = _Tp; |
535 | using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; |
536 | |
537 | _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base() = default; |
538 | _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default; |
539 | _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default; |
540 | _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default; |
541 | |
542 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& |
543 | operator=(__optional_move_assign_base&& __opt) noexcept( |
544 | is_nothrow_move_assignable_v<value_type> && is_nothrow_move_constructible_v<value_type>) { |
545 | this->__assign_from(std::move(__opt)); |
546 | return *this; |
547 | } |
548 | }; |
549 | |
550 | template <class _Tp> |
551 | using __optional_sfinae_ctor_base_t = |
552 | __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >; |
553 | |
554 | template <class _Tp> |
555 | using __optional_sfinae_assign_base_t = |
556 | __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), |
557 | (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >; |
558 | |
559 | template <class _Tp> |
560 | class optional; |
561 | |
562 | # if _LIBCPP_STD_VER >= 20 |
563 | |
564 | template <class _Tp> |
565 | concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); }; |
566 | |
567 | # endif // _LIBCPP_STD_VER >= 20 |
568 | |
569 | template <class _Tp> |
570 | struct __is_std_optional : false_type {}; |
571 | template <class _Tp> |
572 | struct __is_std_optional<optional<_Tp>> : true_type {}; |
573 | |
574 | template <class _Tp> |
575 | class _LIBCPP_DECLSPEC_EMPTY_BASES optional |
576 | : private __optional_move_assign_base<_Tp>, |
577 | private __optional_sfinae_ctor_base_t<_Tp>, |
578 | private __optional_sfinae_assign_base_t<_Tp> { |
579 | using __base = __optional_move_assign_base<_Tp>; |
580 | |
581 | public: |
582 | using value_type = _Tp; |
583 | |
584 | using __trivially_relocatable = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>; |
585 | |
586 | private: |
587 | // Disable the reference extension using this static assert. |
588 | static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>, |
589 | "instantiation of optional with in_place_t is ill-formed" ); |
590 | static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>, |
591 | "instantiation of optional with nullopt_t is ill-formed" ); |
592 | static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed" ); |
593 | static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed" ); |
594 | static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed" ); |
595 | |
596 | // LWG2756: conditionally explicit conversion from _Up |
597 | struct _CheckOptionalArgsConstructor { |
598 | template <class _Up> |
599 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { |
600 | return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>; |
601 | } |
602 | |
603 | template <class _Up> |
604 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { |
605 | return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>; |
606 | } |
607 | }; |
608 | template <class _Up> |
609 | using _CheckOptionalArgsCtor = |
610 | _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value && |
611 | (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value), |
612 | _CheckOptionalArgsConstructor, |
613 | __check_tuple_constructor_fail >; |
614 | template <class _QualUp> |
615 | struct _CheckOptionalLikeConstructor { |
616 | template <class _Up, class _Opt = optional<_Up>> |
617 | using __check_constructible_from_opt = |
618 | _Or< is_constructible<_Tp, _Opt&>, |
619 | is_constructible<_Tp, _Opt const&>, |
620 | is_constructible<_Tp, _Opt&&>, |
621 | is_constructible<_Tp, _Opt const&&>, |
622 | is_convertible<_Opt&, _Tp>, |
623 | is_convertible<_Opt const&, _Tp>, |
624 | is_convertible<_Opt&&, _Tp>, |
625 | is_convertible<_Opt const&&, _Tp> >; |
626 | template <class _Up, class _Opt = optional<_Up>> |
627 | using __check_assignable_from_opt = |
628 | _Or< is_assignable<_Tp&, _Opt&>, |
629 | is_assignable<_Tp&, _Opt const&>, |
630 | is_assignable<_Tp&, _Opt&&>, |
631 | is_assignable<_Tp&, _Opt const&&> >; |
632 | template <class _Up, class _QUp = _QualUp> |
633 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { |
634 | return is_convertible<_QUp, _Tp>::value && |
635 | (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value); |
636 | } |
637 | template <class _Up, class _QUp = _QualUp> |
638 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { |
639 | return !is_convertible<_QUp, _Tp>::value && |
640 | (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value); |
641 | } |
642 | template <class _Up, class _QUp = _QualUp> |
643 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() { |
644 | // Construction and assignability of _QUp to _Tp has already been |
645 | // checked. |
646 | return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value; |
647 | } |
648 | }; |
649 | |
650 | template <class _Up, class _QualUp> |
651 | using _CheckOptionalLikeCtor = |
652 | _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value, |
653 | _CheckOptionalLikeConstructor<_QualUp>, |
654 | __check_tuple_constructor_fail >; |
655 | template <class _Up, class _QualUp> |
656 | using _CheckOptionalLikeAssign = |
657 | _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value, |
658 | _CheckOptionalLikeConstructor<_QualUp>, |
659 | __check_tuple_constructor_fail >; |
660 | |
661 | public: |
662 | _LIBCPP_HIDE_FROM_ABI constexpr optional() noexcept {} |
663 | _LIBCPP_HIDE_FROM_ABI constexpr optional(const optional&) = default; |
664 | _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&) = default; |
665 | _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {} |
666 | |
667 | template < |
668 | class _InPlaceT, |
669 | class... _Args, |
670 | class = enable_if_t< _And< _IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...> >::value > > |
671 | _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args) |
672 | : __base(in_place, std::forward<_Args>(__args)...) {} |
673 | |
674 | template <class _Up, |
675 | class... _Args, |
676 | class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> > |
677 | _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) |
678 | : __base(in_place, __il, std::forward<_Args>(__args)...) {} |
679 | |
680 | template <class _Up = value_type, |
681 | enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0> |
682 | _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {} |
683 | |
684 | template <class _Up, enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0> |
685 | _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {} |
686 | |
687 | // LWG2756: conditionally explicit conversion from const optional<_Up>& |
688 | template <class _Up, |
689 | enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0> |
690 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) { |
691 | this->__construct_from(__v); |
692 | } |
693 | template <class _Up, |
694 | enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0> |
695 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) { |
696 | this->__construct_from(__v); |
697 | } |
698 | |
699 | // LWG2756: conditionally explicit conversion from optional<_Up>&& |
700 | template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0> |
701 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) { |
702 | this->__construct_from(std::move(__v)); |
703 | } |
704 | template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0> |
705 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) { |
706 | this->__construct_from(std::move(__v)); |
707 | } |
708 | |
709 | # if _LIBCPP_STD_VER >= 23 |
710 | template <class _Tag, |
711 | class _Fp, |
712 | class... _Args, |
713 | __enable_if_t<_IsSame<_Tag, __optional_construct_from_invoke_tag>::value, int> = 0> |
714 | _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Tag, _Fp&& __f, _Args&&... __args) |
715 | : __base(__optional_construct_from_invoke_tag{}, std::forward<_Fp>(__f), std::forward<_Args>(__args)...) {} |
716 | # endif |
717 | |
718 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept { |
719 | reset(); |
720 | return *this; |
721 | } |
722 | |
723 | _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default; |
724 | _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default; |
725 | |
726 | // LWG2756 |
727 | template < |
728 | class _Up = value_type, |
729 | class = enable_if_t< _And< _IsNotSame<__remove_cvref_t<_Up>, optional>, |
730 | _Or< _IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>> >, |
731 | is_constructible<value_type, _Up>, |
732 | is_assignable<value_type&, _Up> >::value> > |
733 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) { |
734 | if (this->has_value()) |
735 | this->__get() = std::forward<_Up>(__v); |
736 | else |
737 | this->__construct(std::forward<_Up>(__v)); |
738 | return *this; |
739 | } |
740 | |
741 | // LWG2756 |
742 | template <class _Up, |
743 | enable_if_t< _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>(), int> = 0> |
744 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(const optional<_Up>& __v) { |
745 | this->__assign_from(__v); |
746 | return *this; |
747 | } |
748 | |
749 | // LWG2756 |
750 | template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_assign<_Up>(), int> = 0> |
751 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(optional<_Up>&& __v) { |
752 | this->__assign_from(std::move(__v)); |
753 | return *this; |
754 | } |
755 | |
756 | template <class... _Args, class = enable_if_t< is_constructible_v<value_type, _Args...> > > |
757 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) { |
758 | reset(); |
759 | this->__construct(std::forward<_Args>(__args)...); |
760 | return this->__get(); |
761 | } |
762 | |
763 | template <class _Up, |
764 | class... _Args, |
765 | class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...> > > |
766 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { |
767 | reset(); |
768 | this->__construct(__il, std::forward<_Args>(__args)...); |
769 | return this->__get(); |
770 | } |
771 | |
772 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void |
773 | swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) { |
774 | if (this->has_value() == __opt.has_value()) { |
775 | using std::swap; |
776 | if (this->has_value()) |
777 | swap(this->__get(), __opt.__get()); |
778 | } else { |
779 | if (this->has_value()) { |
780 | __opt.__construct(std::move(this->__get())); |
781 | reset(); |
782 | } else { |
783 | this->__construct(std::move(__opt.__get())); |
784 | __opt.reset(); |
785 | } |
786 | } |
787 | } |
788 | |
789 | _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept { |
790 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value" ); |
791 | return std::addressof(this->__get()); |
792 | } |
793 | |
794 | _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept { |
795 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value" ); |
796 | return std::addressof(this->__get()); |
797 | } |
798 | |
799 | _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept { |
800 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value" ); |
801 | return this->__get(); |
802 | } |
803 | |
804 | _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept { |
805 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value" ); |
806 | return this->__get(); |
807 | } |
808 | |
809 | _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept { |
810 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value" ); |
811 | return std::move(this->__get()); |
812 | } |
813 | |
814 | _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept { |
815 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value" ); |
816 | return std::move(this->__get()); |
817 | } |
818 | |
819 | _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return has_value(); } |
820 | |
821 | using __base::__get; |
822 | using __base::has_value; |
823 | |
824 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const& value() const& { |
825 | if (!this->has_value()) |
826 | __throw_bad_optional_access(); |
827 | return this->__get(); |
828 | } |
829 | |
830 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type& value() & { |
831 | if (!this->has_value()) |
832 | __throw_bad_optional_access(); |
833 | return this->__get(); |
834 | } |
835 | |
836 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type&& value() && { |
837 | if (!this->has_value()) |
838 | __throw_bad_optional_access(); |
839 | return std::move(this->__get()); |
840 | } |
841 | |
842 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const&& value() const&& { |
843 | if (!this->has_value()) |
844 | __throw_bad_optional_access(); |
845 | return std::move(this->__get()); |
846 | } |
847 | |
848 | template <class _Up> |
849 | _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& { |
850 | static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible" ); |
851 | static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T" ); |
852 | return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v)); |
853 | } |
854 | |
855 | template <class _Up> |
856 | _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && { |
857 | static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible" ); |
858 | static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T" ); |
859 | return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v)); |
860 | } |
861 | |
862 | # if _LIBCPP_STD_VER >= 23 |
863 | template <class _Func> |
864 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) & { |
865 | using _Up = invoke_result_t<_Func, value_type&>; |
866 | static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, |
867 | "Result of f(value()) must be a specialization of std::optional" ); |
868 | if (*this) |
869 | return std::invoke(std::forward<_Func>(__f), value()); |
870 | return remove_cvref_t<_Up>(); |
871 | } |
872 | |
873 | template <class _Func> |
874 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) const& { |
875 | using _Up = invoke_result_t<_Func, const value_type&>; |
876 | static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, |
877 | "Result of f(value()) must be a specialization of std::optional" ); |
878 | if (*this) |
879 | return std::invoke(std::forward<_Func>(__f), value()); |
880 | return remove_cvref_t<_Up>(); |
881 | } |
882 | |
883 | template <class _Func> |
884 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) && { |
885 | using _Up = invoke_result_t<_Func, value_type&&>; |
886 | static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, |
887 | "Result of f(std::move(value())) must be a specialization of std::optional" ); |
888 | if (*this) |
889 | return std::invoke(std::forward<_Func>(__f), std::move(value())); |
890 | return remove_cvref_t<_Up>(); |
891 | } |
892 | |
893 | template <class _Func> |
894 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { |
895 | using _Up = invoke_result_t<_Func, const value_type&&>; |
896 | static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, |
897 | "Result of f(std::move(value())) must be a specialization of std::optional" ); |
898 | if (*this) |
899 | return std::invoke(std::forward<_Func>(__f), std::move(value())); |
900 | return remove_cvref_t<_Up>(); |
901 | } |
902 | |
903 | template <class _Func> |
904 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) & { |
905 | using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>; |
906 | static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array" ); |
907 | static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t" ); |
908 | static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t" ); |
909 | static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type" ); |
910 | if (*this) |
911 | return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value()); |
912 | return optional<_Up>(); |
913 | } |
914 | |
915 | template <class _Func> |
916 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const& { |
917 | using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>; |
918 | static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array" ); |
919 | static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t" ); |
920 | static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t" ); |
921 | static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type" ); |
922 | if (*this) |
923 | return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value()); |
924 | return optional<_Up>(); |
925 | } |
926 | |
927 | template <class _Func> |
928 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) && { |
929 | using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>; |
930 | static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array" ); |
931 | static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t" ); |
932 | static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t" ); |
933 | static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type" ); |
934 | if (*this) |
935 | return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); |
936 | return optional<_Up>(); |
937 | } |
938 | |
939 | template <class _Func> |
940 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const&& { |
941 | using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>; |
942 | static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array" ); |
943 | static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t" ); |
944 | static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t" ); |
945 | static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type" ); |
946 | if (*this) |
947 | return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); |
948 | return optional<_Up>(); |
949 | } |
950 | |
951 | template <invocable _Func> |
952 | _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const& |
953 | requires is_copy_constructible_v<value_type> |
954 | { |
955 | static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, |
956 | "Result of f() should be the same type as this optional" ); |
957 | if (*this) |
958 | return *this; |
959 | return std::forward<_Func>(__f)(); |
960 | } |
961 | |
962 | template <invocable _Func> |
963 | _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) && |
964 | requires is_move_constructible_v<value_type> |
965 | { |
966 | static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, |
967 | "Result of f() should be the same type as this optional" ); |
968 | if (*this) |
969 | return std::move(*this); |
970 | return std::forward<_Func>(__f)(); |
971 | } |
972 | # endif // _LIBCPP_STD_VER >= 23 |
973 | |
974 | using __base::reset; |
975 | }; |
976 | |
977 | # if _LIBCPP_STD_VER >= 17 |
978 | template <class _Tp> |
979 | optional(_Tp) -> optional<_Tp>; |
980 | # endif |
981 | |
982 | // Comparisons between optionals |
983 | template <class _Tp, class _Up> |
984 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
985 | is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, |
986 | bool > |
987 | operator==(const optional<_Tp>& __x, const optional<_Up>& __y) { |
988 | if (static_cast<bool>(__x) != static_cast<bool>(__y)) |
989 | return false; |
990 | if (!static_cast<bool>(__x)) |
991 | return true; |
992 | return *__x == *__y; |
993 | } |
994 | |
995 | template <class _Tp, class _Up> |
996 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
997 | is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, |
998 | bool > |
999 | operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) { |
1000 | if (static_cast<bool>(__x) != static_cast<bool>(__y)) |
1001 | return true; |
1002 | if (!static_cast<bool>(__x)) |
1003 | return false; |
1004 | return *__x != *__y; |
1005 | } |
1006 | |
1007 | template <class _Tp, class _Up> |
1008 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1009 | is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, |
1010 | bool > |
1011 | operator<(const optional<_Tp>& __x, const optional<_Up>& __y) { |
1012 | if (!static_cast<bool>(__y)) |
1013 | return false; |
1014 | if (!static_cast<bool>(__x)) |
1015 | return true; |
1016 | return *__x < *__y; |
1017 | } |
1018 | |
1019 | template <class _Tp, class _Up> |
1020 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1021 | is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, |
1022 | bool > |
1023 | operator>(const optional<_Tp>& __x, const optional<_Up>& __y) { |
1024 | if (!static_cast<bool>(__x)) |
1025 | return false; |
1026 | if (!static_cast<bool>(__y)) |
1027 | return true; |
1028 | return *__x > *__y; |
1029 | } |
1030 | |
1031 | template <class _Tp, class _Up> |
1032 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1033 | is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, |
1034 | bool > |
1035 | operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) { |
1036 | if (!static_cast<bool>(__x)) |
1037 | return true; |
1038 | if (!static_cast<bool>(__y)) |
1039 | return false; |
1040 | return *__x <= *__y; |
1041 | } |
1042 | |
1043 | template <class _Tp, class _Up> |
1044 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1045 | is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, |
1046 | bool > |
1047 | operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) { |
1048 | if (!static_cast<bool>(__y)) |
1049 | return true; |
1050 | if (!static_cast<bool>(__x)) |
1051 | return false; |
1052 | return *__x >= *__y; |
1053 | } |
1054 | |
1055 | # if _LIBCPP_STD_VER >= 20 |
1056 | |
1057 | template <class _Tp, three_way_comparable_with<_Tp> _Up> |
1058 | _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up> |
1059 | operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) { |
1060 | if (__x && __y) |
1061 | return *__x <=> *__y; |
1062 | return __x.has_value() <=> __y.has_value(); |
1063 | } |
1064 | |
1065 | # endif // _LIBCPP_STD_VER >= 20 |
1066 | |
1067 | // Comparisons with nullopt |
1068 | template <class _Tp> |
1069 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept { |
1070 | return !static_cast<bool>(__x); |
1071 | } |
1072 | |
1073 | # if _LIBCPP_STD_VER <= 17 |
1074 | |
1075 | template <class _Tp> |
1076 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept { |
1077 | return !static_cast<bool>(__x); |
1078 | } |
1079 | |
1080 | template <class _Tp> |
1081 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, nullopt_t) noexcept { |
1082 | return static_cast<bool>(__x); |
1083 | } |
1084 | |
1085 | template <class _Tp> |
1086 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullopt_t, const optional<_Tp>& __x) noexcept { |
1087 | return static_cast<bool>(__x); |
1088 | } |
1089 | |
1090 | template <class _Tp> |
1091 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept { |
1092 | return false; |
1093 | } |
1094 | |
1095 | template <class _Tp> |
1096 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(nullopt_t, const optional<_Tp>& __x) noexcept { |
1097 | return static_cast<bool>(__x); |
1098 | } |
1099 | |
1100 | template <class _Tp> |
1101 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, nullopt_t) noexcept { |
1102 | return !static_cast<bool>(__x); |
1103 | } |
1104 | |
1105 | template <class _Tp> |
1106 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept { |
1107 | return true; |
1108 | } |
1109 | |
1110 | template <class _Tp> |
1111 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, nullopt_t) noexcept { |
1112 | return static_cast<bool>(__x); |
1113 | } |
1114 | |
1115 | template <class _Tp> |
1116 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept { |
1117 | return false; |
1118 | } |
1119 | |
1120 | template <class _Tp> |
1121 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept { |
1122 | return true; |
1123 | } |
1124 | |
1125 | template <class _Tp> |
1126 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(nullopt_t, const optional<_Tp>& __x) noexcept { |
1127 | return !static_cast<bool>(__x); |
1128 | } |
1129 | |
1130 | # else // _LIBCPP_STD_VER <= 17 |
1131 | |
1132 | template <class _Tp> |
1133 | _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept { |
1134 | return __x.has_value() <=> false; |
1135 | } |
1136 | |
1137 | # endif // _LIBCPP_STD_VER <= 17 |
1138 | |
1139 | // Comparisons with T |
1140 | template <class _Tp, class _Up> |
1141 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1142 | is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, |
1143 | bool > |
1144 | operator==(const optional<_Tp>& __x, const _Up& __v) { |
1145 | return static_cast<bool>(__x) ? *__x == __v : false; |
1146 | } |
1147 | |
1148 | template <class _Tp, class _Up> |
1149 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1150 | is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, |
1151 | bool > |
1152 | operator==(const _Tp& __v, const optional<_Up>& __x) { |
1153 | return static_cast<bool>(__x) ? __v == *__x : false; |
1154 | } |
1155 | |
1156 | template <class _Tp, class _Up> |
1157 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1158 | is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, |
1159 | bool > |
1160 | operator!=(const optional<_Tp>& __x, const _Up& __v) { |
1161 | return static_cast<bool>(__x) ? *__x != __v : true; |
1162 | } |
1163 | |
1164 | template <class _Tp, class _Up> |
1165 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1166 | is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>, |
1167 | bool > |
1168 | operator!=(const _Tp& __v, const optional<_Up>& __x) { |
1169 | return static_cast<bool>(__x) ? __v != *__x : true; |
1170 | } |
1171 | |
1172 | template <class _Tp, class _Up> |
1173 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1174 | is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, |
1175 | bool > |
1176 | operator<(const optional<_Tp>& __x, const _Up& __v) { |
1177 | return static_cast<bool>(__x) ? *__x < __v : true; |
1178 | } |
1179 | |
1180 | template <class _Tp, class _Up> |
1181 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1182 | is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>, |
1183 | bool > |
1184 | operator<(const _Tp& __v, const optional<_Up>& __x) { |
1185 | return static_cast<bool>(__x) ? __v < *__x : false; |
1186 | } |
1187 | |
1188 | template <class _Tp, class _Up> |
1189 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1190 | is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, |
1191 | bool > |
1192 | operator<=(const optional<_Tp>& __x, const _Up& __v) { |
1193 | return static_cast<bool>(__x) ? *__x <= __v : true; |
1194 | } |
1195 | |
1196 | template <class _Tp, class _Up> |
1197 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1198 | is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>, |
1199 | bool > |
1200 | operator<=(const _Tp& __v, const optional<_Up>& __x) { |
1201 | return static_cast<bool>(__x) ? __v <= *__x : false; |
1202 | } |
1203 | |
1204 | template <class _Tp, class _Up> |
1205 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1206 | is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, |
1207 | bool > |
1208 | operator>(const optional<_Tp>& __x, const _Up& __v) { |
1209 | return static_cast<bool>(__x) ? *__x > __v : false; |
1210 | } |
1211 | |
1212 | template <class _Tp, class _Up> |
1213 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1214 | is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>, |
1215 | bool > |
1216 | operator>(const _Tp& __v, const optional<_Up>& __x) { |
1217 | return static_cast<bool>(__x) ? __v > *__x : true; |
1218 | } |
1219 | |
1220 | template <class _Tp, class _Up> |
1221 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1222 | is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, |
1223 | bool > |
1224 | operator>=(const optional<_Tp>& __x, const _Up& __v) { |
1225 | return static_cast<bool>(__x) ? *__x >= __v : false; |
1226 | } |
1227 | |
1228 | template <class _Tp, class _Up> |
1229 | _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t< |
1230 | is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>, |
1231 | bool > |
1232 | operator>=(const _Tp& __v, const optional<_Up>& __x) { |
1233 | return static_cast<bool>(__x) ? __v >= *__x : true; |
1234 | } |
1235 | |
1236 | # if _LIBCPP_STD_VER >= 20 |
1237 | |
1238 | template <class _Tp, class _Up> |
1239 | requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up> |
1240 | _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up> |
1241 | operator<=>(const optional<_Tp>& __x, const _Up& __v) { |
1242 | return __x.has_value() ? *__x <=> __v : strong_ordering::less; |
1243 | } |
1244 | |
1245 | # endif // _LIBCPP_STD_VER >= 20 |
1246 | |
1247 | template <class _Tp> |
1248 | inline _LIBCPP_HIDE_FROM_ABI |
1249 | _LIBCPP_CONSTEXPR_SINCE_CXX20 enable_if_t< is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, void > |
1250 | swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) { |
1251 | __x.swap(__y); |
1252 | } |
1253 | |
1254 | template <class _Tp> |
1255 | _LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) { |
1256 | return optional<decay_t<_Tp>>(std::forward<_Tp>(__v)); |
1257 | } |
1258 | |
1259 | template <class _Tp, class... _Args> |
1260 | _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) { |
1261 | return optional<_Tp>(in_place, std::forward<_Args>(__args)...); |
1262 | } |
1263 | |
1264 | template <class _Tp, class _Up, class... _Args> |
1265 | _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) { |
1266 | return optional<_Tp>(in_place, __il, std::forward<_Args>(__args)...); |
1267 | } |
1268 | |
1269 | template <class _Tp> |
1270 | struct _LIBCPP_TEMPLATE_VIS hash< __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> > { |
1271 | # if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) |
1272 | _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type; |
1273 | _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; |
1274 | # endif |
1275 | |
1276 | _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const { |
1277 | return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0; |
1278 | } |
1279 | }; |
1280 | |
1281 | _LIBCPP_END_NAMESPACE_STD |
1282 | |
1283 | #endif // _LIBCPP_STD_VER >= 17 |
1284 | |
1285 | _LIBCPP_POP_MACROS |
1286 | |
1287 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
1288 | # include <atomic> |
1289 | # include <climits> |
1290 | # include <concepts> |
1291 | # include <ctime> |
1292 | # include <iterator> |
1293 | # include <limits> |
1294 | # include <memory> |
1295 | # include <ratio> |
1296 | # include <stdexcept> |
1297 | # include <tuple> |
1298 | # include <type_traits> |
1299 | # include <typeinfo> |
1300 | # include <utility> |
1301 | # include <variant> |
1302 | #endif |
1303 | |
1304 | #endif // _LIBCPP_OPTIONAL |
1305 | |