blob: 80146234fc9bffc3d59d889f0b43b98d21b9f4c2 [file] [log] [blame]
Yi Kong878f9942023-12-13 12:55:04 +09001// -*- 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 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;
140 constexpr T *operator->();
141 constexpr T const &operator*() const &;
142 constexpr T &operator*() &;
143 constexpr T &&operator*() &&;
144 constexpr const T &&operator*() const &&;
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> // all public C++ headers provide the assertion handler
181#include <__availability>
182#include <__compare/compare_three_way_result.h>
183#include <__compare/three_way_comparable.h>
184#include <__concepts/invocable.h>
185#include <__config>
186#include <__functional/hash.h>
187#include <__functional/invoke.h>
188#include <__functional/reference_wrapper.h>
189#include <__functional/unary_function.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_copy_assignable.h>
203#include <__type_traits/is_copy_constructible.h>
204#include <__type_traits/is_destructible.h>
205#include <__type_traits/is_move_assignable.h>
206#include <__type_traits/is_move_constructible.h>
207#include <__type_traits/is_nothrow_move_assignable.h>
208#include <__type_traits/is_nothrow_move_constructible.h>
209#include <__type_traits/is_object.h>
210#include <__type_traits/is_reference.h>
211#include <__type_traits/is_scalar.h>
212#include <__type_traits/is_swappable.h>
213#include <__type_traits/is_trivially_copy_assignable.h>
214#include <__type_traits/is_trivially_copy_constructible.h>
215#include <__type_traits/is_trivially_destructible.h>
216#include <__type_traits/is_trivially_move_assignable.h>
217#include <__type_traits/is_trivially_move_constructible.h>
218#include <__type_traits/negation.h>
219#include <__type_traits/remove_const.h>
220#include <__type_traits/remove_cvref.h>
221#include <__type_traits/remove_reference.h>
222#include <__utility/declval.h>
223#include <__utility/forward.h>
224#include <__utility/in_place.h>
225#include <__utility/move.h>
226#include <__utility/swap.h>
227#include <__verbose_abort>
228#include <initializer_list>
229#include <new>
230#include <stdexcept>
231#include <version>
232
233// standard-mandated includes
234
235// [optional.syn]
236#include <compare>
237
238#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
239# pragma GCC system_header
240#endif
241
242_LIBCPP_PUSH_MACROS
243#include <__undef_macros>
244
245namespace std // purposefully not using versioning namespace
246{
247
248class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
249 : public exception
250{
251public:
252 // Get the key function ~bad_optional_access() into the dylib
253 ~bad_optional_access() _NOEXCEPT override;
254 const char* what() const _NOEXCEPT override;
255};
256
257} // namespace std
258
259#if _LIBCPP_STD_VER >= 17
260
261_LIBCPP_BEGIN_NAMESPACE_STD
262
263_LIBCPP_NORETURN
264inline _LIBCPP_INLINE_VISIBILITY
265_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
266void __throw_bad_optional_access() {
267#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
268 throw bad_optional_access();
269#else
270 _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
271#endif
272}
273
274struct nullopt_t
275{
276 struct __secret_tag { explicit __secret_tag() = default; };
277 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
278};
279
280inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
281
282struct __optional_construct_from_invoke_tag {};
283
284template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
285struct __optional_destruct_base;
286
287template <class _Tp>
288struct __optional_destruct_base<_Tp, false>
289{
290 typedef _Tp value_type;
291 static_assert(is_object_v<value_type>,
292 "instantiation of optional with a non-object type is undefined behavior");
293 union
294 {
295 char __null_state_;
296 value_type __val_;
297 };
298 bool __engaged_;
299
300 _LIBCPP_INLINE_VISIBILITY
301 _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base()
302 {
303 if (__engaged_)
304 __val_.~value_type();
305 }
306
307 _LIBCPP_INLINE_VISIBILITY
308 constexpr __optional_destruct_base() noexcept
309 : __null_state_(),
310 __engaged_(false) {}
311
312 template <class... _Args>
313 _LIBCPP_INLINE_VISIBILITY
314 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
315 : __val_(_VSTD::forward<_Args>(__args)...),
316 __engaged_(true) {}
317
318#if _LIBCPP_STD_VER >= 23
319 template <class _Fp, class... _Args>
320 _LIBCPP_HIDE_FROM_ABI
321 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
322 : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
323#endif
324
325 _LIBCPP_INLINE_VISIBILITY
326 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept
327 {
328 if (__engaged_)
329 {
330 __val_.~value_type();
331 __engaged_ = false;
332 }
333 }
334};
335
336template <class _Tp>
337struct __optional_destruct_base<_Tp, true>
338{
339 typedef _Tp value_type;
340 static_assert(is_object_v<value_type>,
341 "instantiation of optional with a non-object type is undefined behavior");
342 union
343 {
344 char __null_state_;
345 value_type __val_;
346 };
347 bool __engaged_;
348
349 _LIBCPP_INLINE_VISIBILITY
350 constexpr __optional_destruct_base() noexcept
351 : __null_state_(),
352 __engaged_(false) {}
353
354 template <class... _Args>
355 _LIBCPP_INLINE_VISIBILITY
356 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
357 : __val_(_VSTD::forward<_Args>(__args)...),
358 __engaged_(true) {}
359
360#if _LIBCPP_STD_VER >= 23
361 template <class _Fp, class... _Args>
362 _LIBCPP_HIDE_FROM_ABI
363 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
364 : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
365#endif
366
367 _LIBCPP_INLINE_VISIBILITY
368 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept
369 {
370 if (__engaged_)
371 {
372 __engaged_ = false;
373 }
374 }
375};
376
377template <class _Tp, bool = is_reference<_Tp>::value>
378struct __optional_storage_base : __optional_destruct_base<_Tp>
379{
380 using __base = __optional_destruct_base<_Tp>;
381 using value_type = _Tp;
382 using __base::__base;
383
384 _LIBCPP_INLINE_VISIBILITY
385 constexpr bool has_value() const noexcept
386 {
387 return this->__engaged_;
388 }
389
390 _LIBCPP_INLINE_VISIBILITY
391 constexpr value_type& __get() & noexcept
392 {
393 return this->__val_;
394 }
395 _LIBCPP_INLINE_VISIBILITY
396 constexpr const value_type& __get() const& noexcept
397 {
398 return this->__val_;
399 }
400 _LIBCPP_INLINE_VISIBILITY
401 constexpr value_type&& __get() && noexcept
402 {
403 return _VSTD::move(this->__val_);
404 }
405 _LIBCPP_INLINE_VISIBILITY
406 constexpr const value_type&& __get() const&& noexcept
407 {
408 return _VSTD::move(this->__val_);
409 }
410
411 template <class... _Args>
412 _LIBCPP_INLINE_VISIBILITY
413 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args)
414 {
415 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
416#if _LIBCPP_STD_VER >= 20
417 _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
418#else
419 ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
420#endif
421 this->__engaged_ = true;
422 }
423
424 template <class _That>
425 _LIBCPP_INLINE_VISIBILITY
426 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt)
427 {
428 if (__opt.has_value())
429 __construct(_VSTD::forward<_That>(__opt).__get());
430 }
431
432 template <class _That>
433 _LIBCPP_INLINE_VISIBILITY
434 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt)
435 {
436 if (this->__engaged_ == __opt.has_value())
437 {
438 if (this->__engaged_)
439 this->__val_ = _VSTD::forward<_That>(__opt).__get();
440 }
441 else
442 {
443 if (this->__engaged_)
444 this->reset();
445 else
446 __construct(_VSTD::forward<_That>(__opt).__get());
447 }
448 }
449};
450
451// optional<T&> is currently required to be ill-formed. However, it may
452// be allowed in the future. For this reason, it has already been implemented
453// to ensure we can make the change in an ABI-compatible manner.
454template <class _Tp>
455struct __optional_storage_base<_Tp, true>
456{
457 using value_type = _Tp;
458 using __raw_type = remove_reference_t<_Tp>;
459 __raw_type* __value_;
460
461 template <class _Up>
462 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
463 using _RawUp = __libcpp_remove_reference_t<_Up>;
464 using _UpPtr = _RawUp*;
465 using _RawTp = __libcpp_remove_reference_t<_Tp>;
466 using _TpPtr = _RawTp*;
467 using _CheckLValueArg = integral_constant<bool,
468 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
469 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
470 || is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value
471 >;
472 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
473 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
474 is_convertible<_UpPtr, _TpPtr>::value);
475 }
476
477 _LIBCPP_INLINE_VISIBILITY
478 constexpr __optional_storage_base() noexcept
479 : __value_(nullptr) {}
480
481 template <class _UArg>
482 _LIBCPP_INLINE_VISIBILITY
483 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
484 : __value_(_VSTD::addressof(__uarg))
485 {
486 static_assert(__can_bind_reference<_UArg>(),
487 "Attempted to construct a reference element in tuple from a "
488 "possible temporary");
489 }
490
491 _LIBCPP_INLINE_VISIBILITY
492 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
493
494 _LIBCPP_INLINE_VISIBILITY
495 constexpr bool has_value() const noexcept
496 { return __value_ != nullptr; }
497
498 _LIBCPP_INLINE_VISIBILITY
499 constexpr value_type& __get() const& noexcept
500 { return *__value_; }
501
502 _LIBCPP_INLINE_VISIBILITY
503 constexpr value_type&& __get() const&& noexcept
504 { return _VSTD::forward<value_type>(*__value_); }
505
506 template <class _UArg>
507 _LIBCPP_INLINE_VISIBILITY
508 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val)
509 {
510 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
511 static_assert(__can_bind_reference<_UArg>(),
512 "Attempted to construct a reference element in tuple from a "
513 "possible temporary");
514 __value_ = _VSTD::addressof(__val);
515 }
516
517 template <class _That>
518 _LIBCPP_INLINE_VISIBILITY
519 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt)
520 {
521 if (__opt.has_value())
522 __construct(_VSTD::forward<_That>(__opt).__get());
523 }
524
525 template <class _That>
526 _LIBCPP_INLINE_VISIBILITY
527 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt)
528 {
529 if (has_value() == __opt.has_value())
530 {
531 if (has_value())
532 *__value_ = _VSTD::forward<_That>(__opt).__get();
533 }
534 else
535 {
536 if (has_value())
537 reset();
538 else
539 __construct(_VSTD::forward<_That>(__opt).__get());
540 }
541 }
542};
543
544template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
545struct __optional_copy_base : __optional_storage_base<_Tp>
546{
547 using __optional_storage_base<_Tp>::__optional_storage_base;
548};
549
550template <class _Tp>
551struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
552{
553 using __optional_storage_base<_Tp>::__optional_storage_base;
554
555 _LIBCPP_INLINE_VISIBILITY
556 __optional_copy_base() = default;
557
558 _LIBCPP_INLINE_VISIBILITY
559 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt)
560 {
561 this->__construct_from(__opt);
562 }
563
564 _LIBCPP_INLINE_VISIBILITY
565 __optional_copy_base(__optional_copy_base&&) = default;
566 _LIBCPP_INLINE_VISIBILITY
567 __optional_copy_base& operator=(const __optional_copy_base&) = default;
568 _LIBCPP_INLINE_VISIBILITY
569 __optional_copy_base& operator=(__optional_copy_base&&) = default;
570};
571
572template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
573struct __optional_move_base : __optional_copy_base<_Tp>
574{
575 using __optional_copy_base<_Tp>::__optional_copy_base;
576};
577
578template <class _Tp>
579struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
580{
581 using value_type = _Tp;
582 using __optional_copy_base<_Tp>::__optional_copy_base;
583
584 _LIBCPP_INLINE_VISIBILITY
585 __optional_move_base() = default;
586 _LIBCPP_INLINE_VISIBILITY
587 __optional_move_base(const __optional_move_base&) = default;
588
589 _LIBCPP_INLINE_VISIBILITY
590 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_base(__optional_move_base&& __opt)
591 noexcept(is_nothrow_move_constructible_v<value_type>)
592 {
593 this->__construct_from(_VSTD::move(__opt));
594 }
595
596 _LIBCPP_INLINE_VISIBILITY
597 __optional_move_base& operator=(const __optional_move_base&) = default;
598 _LIBCPP_INLINE_VISIBILITY
599 __optional_move_base& operator=(__optional_move_base&&) = default;
600};
601
602template <class _Tp, bool =
603 is_trivially_destructible<_Tp>::value &&
604 is_trivially_copy_constructible<_Tp>::value &&
605 is_trivially_copy_assignable<_Tp>::value>
606struct __optional_copy_assign_base : __optional_move_base<_Tp>
607{
608 using __optional_move_base<_Tp>::__optional_move_base;
609};
610
611template <class _Tp>
612struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
613{
614 using __optional_move_base<_Tp>::__optional_move_base;
615
616 _LIBCPP_INLINE_VISIBILITY
617 __optional_copy_assign_base() = default;
618 _LIBCPP_INLINE_VISIBILITY
619 __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
620 _LIBCPP_INLINE_VISIBILITY
621 __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
622
623 _LIBCPP_INLINE_VISIBILITY
624 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
625 {
626 this->__assign_from(__opt);
627 return *this;
628 }
629
630 _LIBCPP_INLINE_VISIBILITY
631 __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
632};
633
634template <class _Tp, bool =
635 is_trivially_destructible<_Tp>::value &&
636 is_trivially_move_constructible<_Tp>::value &&
637 is_trivially_move_assignable<_Tp>::value>
638struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
639{
640 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
641};
642
643template <class _Tp>
644struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
645{
646 using value_type = _Tp;
647 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
648
649 _LIBCPP_INLINE_VISIBILITY
650 __optional_move_assign_base() = default;
651 _LIBCPP_INLINE_VISIBILITY
652 __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
653 _LIBCPP_INLINE_VISIBILITY
654 __optional_move_assign_base(__optional_move_assign_base&&) = default;
655 _LIBCPP_INLINE_VISIBILITY
656 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
657
658 _LIBCPP_INLINE_VISIBILITY
659 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
660 noexcept(is_nothrow_move_assignable_v<value_type> &&
661 is_nothrow_move_constructible_v<value_type>)
662 {
663 this->__assign_from(_VSTD::move(__opt));
664 return *this;
665 }
666};
667
668template <class _Tp>
669using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
670 is_copy_constructible<_Tp>::value,
671 is_move_constructible<_Tp>::value
672>;
673
674template <class _Tp>
675using __optional_sfinae_assign_base_t = __sfinae_assign_base<
676 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
677 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
678>;
679
680template<class _Tp>
681class optional;
682
683#if _LIBCPP_STD_VER >= 20
684
685template <class _Tp>
686concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
687
688# endif // _LIBCPP_STD_VER >= 20
689
690template <class _Tp>
691struct __is_std_optional : false_type {};
692template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
693
694template <class _Tp>
695class _LIBCPP_DECLSPEC_EMPTY_BASES optional
696 : private __optional_move_assign_base<_Tp>
697 , private __optional_sfinae_ctor_base_t<_Tp>
698 , private __optional_sfinae_assign_base_t<_Tp>
699{
700 using __base = __optional_move_assign_base<_Tp>;
701public:
702 using value_type = _Tp;
703
704private:
705 // Disable the reference extension using this static assert.
706 static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
707 "instantiation of optional with in_place_t is ill-formed");
708 static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
709 "instantiation of optional with nullopt_t is ill-formed");
710 static_assert(!is_reference_v<value_type>,
711 "instantiation of optional with a reference type is ill-formed");
712 static_assert(is_destructible_v<value_type>,
713 "instantiation of optional with a non-destructible type is ill-formed");
714 static_assert(!is_array_v<value_type>,
715 "instantiation of optional with an array type is ill-formed");
716
717 // LWG2756: conditionally explicit conversion from _Up
718 struct _CheckOptionalArgsConstructor {
719 template <class _Up>
720 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
721 return is_constructible_v<_Tp, _Up&&> &&
722 is_convertible_v<_Up&&, _Tp>;
723 }
724
725 template <class _Up>
726 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
727 return is_constructible_v<_Tp, _Up&&> &&
728 !is_convertible_v<_Up&&, _Tp>;
729 }
730 };
731 template <class _Up>
732 using _CheckOptionalArgsCtor = _If<
733 _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value &&
734 _IsNotSame<__remove_cvref_t<_Up>, optional>::value &&
735 (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value),
736 _CheckOptionalArgsConstructor,
737 __check_tuple_constructor_fail
738 >;
739 template <class _QualUp>
740 struct _CheckOptionalLikeConstructor {
741 template <class _Up, class _Opt = optional<_Up>>
742 using __check_constructible_from_opt = _Or<
743 is_constructible<_Tp, _Opt&>,
744 is_constructible<_Tp, _Opt const&>,
745 is_constructible<_Tp, _Opt&&>,
746 is_constructible<_Tp, _Opt const&&>,
747 is_convertible<_Opt&, _Tp>,
748 is_convertible<_Opt const&, _Tp>,
749 is_convertible<_Opt&&, _Tp>,
750 is_convertible<_Opt const&&, _Tp>
751 >;
752 template <class _Up, class _Opt = optional<_Up>>
753 using __check_assignable_from_opt = _Or<
754 is_assignable<_Tp&, _Opt&>,
755 is_assignable<_Tp&, _Opt const&>,
756 is_assignable<_Tp&, _Opt&&>,
757 is_assignable<_Tp&, _Opt const&&>
758 >;
759 template <class _Up, class _QUp = _QualUp>
760 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
761 return is_convertible<_QUp, _Tp>::value &&
762 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
763 }
764 template <class _Up, class _QUp = _QualUp>
765 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
766 return !is_convertible<_QUp, _Tp>::value &&
767 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
768 }
769 template <class _Up, class _QUp = _QualUp>
770 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
771 // Construction and assignability of _QUp to _Tp has already been
772 // checked.
773 return !__check_constructible_from_opt<_Up>::value &&
774 !__check_assignable_from_opt<_Up>::value;
775 }
776 };
777
778 template <class _Up, class _QualUp>
779 using _CheckOptionalLikeCtor = _If<
780 _And<
781 _IsNotSame<_Up, _Tp>,
782 is_constructible<_Tp, _QualUp>
783 >::value,
784 _CheckOptionalLikeConstructor<_QualUp>,
785 __check_tuple_constructor_fail
786 >;
787 template <class _Up, class _QualUp>
788 using _CheckOptionalLikeAssign = _If<
789 _And<
790 _IsNotSame<_Up, _Tp>,
791 is_constructible<_Tp, _QualUp>,
792 is_assignable<_Tp&, _QualUp>
793 >::value,
794 _CheckOptionalLikeConstructor<_QualUp>,
795 __check_tuple_constructor_fail
796 >;
797
798public:
799
800 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
801 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
802 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
803 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
804
805 template <class _InPlaceT, class... _Args, class = enable_if_t<
806 _And<
807 _IsSame<_InPlaceT, in_place_t>,
808 is_constructible<value_type, _Args...>
809 >::value
810 >
811 >
812 _LIBCPP_INLINE_VISIBILITY
813 constexpr explicit optional(_InPlaceT, _Args&&... __args)
814 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
815
816 template <class _Up, class... _Args, class = enable_if_t<
817 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
818 >
819 _LIBCPP_INLINE_VISIBILITY
820 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
821 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
822
823 template <class _Up = value_type, enable_if_t<
824 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
825 , int> = 0>
826 _LIBCPP_INLINE_VISIBILITY
827 constexpr optional(_Up&& __v)
828 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
829
830 template <class _Up, enable_if_t<
831 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
832 , int> = 0>
833 _LIBCPP_INLINE_VISIBILITY
834 constexpr explicit optional(_Up&& __v)
835 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
836
837 // LWG2756: conditionally explicit conversion from const optional<_Up>&
838 template <class _Up, enable_if_t<
839 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
840 , int> = 0>
841 _LIBCPP_INLINE_VISIBILITY
842 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v)
843 {
844 this->__construct_from(__v);
845 }
846 template <class _Up, enable_if_t<
847 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
848 , int> = 0>
849 _LIBCPP_INLINE_VISIBILITY
850 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v)
851 {
852 this->__construct_from(__v);
853 }
854
855 // LWG2756: conditionally explicit conversion from optional<_Up>&&
856 template <class _Up, enable_if_t<
857 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
858 , int> = 0>
859 _LIBCPP_INLINE_VISIBILITY
860 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v)
861 {
862 this->__construct_from(_VSTD::move(__v));
863 }
864 template <class _Up, enable_if_t<
865 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
866 , int> = 0>
867 _LIBCPP_INLINE_VISIBILITY
868 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v)
869 {
870 this->__construct_from(_VSTD::move(__v));
871 }
872
873#if _LIBCPP_STD_VER >= 23
874 template<class _Fp, class... _Args>
875 _LIBCPP_HIDE_FROM_ABI
876 constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
877 : __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) {
878 }
879#endif
880
881 _LIBCPP_INLINE_VISIBILITY
882 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept
883 {
884 reset();
885 return *this;
886 }
887
888 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
889 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
890
891 // LWG2756
892 template <class _Up = value_type,
893 class = enable_if_t<
894 _And<
895 _IsNotSame<__remove_cvref_t<_Up>, optional>,
896 _Or<
897 _IsNotSame<__remove_cvref_t<_Up>, value_type>,
898 _Not<is_scalar<value_type>>
899 >,
900 is_constructible<value_type, _Up>,
901 is_assignable<value_type&, _Up>
902 >::value>
903 >
904 _LIBCPP_INLINE_VISIBILITY
905 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
906 operator=(_Up&& __v)
907 {
908 if (this->has_value())
909 this->__get() = _VSTD::forward<_Up>(__v);
910 else
911 this->__construct(_VSTD::forward<_Up>(__v));
912 return *this;
913 }
914
915 // LWG2756
916 template <class _Up, enable_if_t<
917 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
918 , int> = 0>
919 _LIBCPP_INLINE_VISIBILITY
920 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
921 operator=(const optional<_Up>& __v)
922 {
923 this->__assign_from(__v);
924 return *this;
925 }
926
927 // LWG2756
928 template <class _Up, enable_if_t<
929 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
930 , int> = 0>
931 _LIBCPP_INLINE_VISIBILITY
932 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
933 operator=(optional<_Up>&& __v)
934 {
935 this->__assign_from(_VSTD::move(__v));
936 return *this;
937 }
938
939 template <class... _Args,
940 class = enable_if_t
941 <
942 is_constructible_v<value_type, _Args...>
943 >
944 >
945 _LIBCPP_INLINE_VISIBILITY
946 _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &
947 emplace(_Args&&... __args)
948 {
949 reset();
950 this->__construct(_VSTD::forward<_Args>(__args)...);
951 return this->__get();
952 }
953
954 template <class _Up, class... _Args,
955 class = enable_if_t
956 <
957 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
958 >
959 >
960 _LIBCPP_INLINE_VISIBILITY
961 _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &
962 emplace(initializer_list<_Up> __il, _Args&&... __args)
963 {
964 reset();
965 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
966 return this->__get();
967 }
968
969 _LIBCPP_INLINE_VISIBILITY
970 _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt)
971 noexcept(is_nothrow_move_constructible_v<value_type> &&
972 is_nothrow_swappable_v<value_type>)
973 {
974 if (this->has_value() == __opt.has_value())
975 {
976 using _VSTD::swap;
977 if (this->has_value())
978 swap(this->__get(), __opt.__get());
979 }
980 else
981 {
982 if (this->has_value())
983 {
984 __opt.__construct(_VSTD::move(this->__get()));
985 reset();
986 }
987 else
988 {
989 this->__construct(_VSTD::move(__opt.__get()));
990 __opt.reset();
991 }
992 }
993 }
994
995 _LIBCPP_INLINE_VISIBILITY
996 constexpr
997 add_pointer_t<value_type const>
998 operator->() const
999 {
1000 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
1001 return _VSTD::addressof(this->__get());
1002 }
1003
1004 _LIBCPP_INLINE_VISIBILITY
1005 constexpr
1006 add_pointer_t<value_type>
1007 operator->()
1008 {
1009 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
1010 return _VSTD::addressof(this->__get());
1011 }
1012
1013 _LIBCPP_INLINE_VISIBILITY
1014 constexpr
1015 const value_type&
1016 operator*() const& noexcept
1017 {
1018 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1019 return this->__get();
1020 }
1021
1022 _LIBCPP_INLINE_VISIBILITY
1023 constexpr
1024 value_type&
1025 operator*() & noexcept
1026 {
1027 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1028 return this->__get();
1029 }
1030
1031 _LIBCPP_INLINE_VISIBILITY
1032 constexpr
1033 value_type&&
1034 operator*() && noexcept
1035 {
1036 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1037 return _VSTD::move(this->__get());
1038 }
1039
1040 _LIBCPP_INLINE_VISIBILITY
1041 constexpr
1042 const value_type&&
1043 operator*() const&& noexcept
1044 {
1045 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1046 return _VSTD::move(this->__get());
1047 }
1048
1049 _LIBCPP_INLINE_VISIBILITY
1050 constexpr explicit operator bool() const noexcept { return has_value(); }
1051
1052 using __base::has_value;
1053 using __base::__get;
1054
1055 _LIBCPP_INLINE_VISIBILITY
1056 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1057 constexpr value_type const& value() const&
1058 {
1059 if (!this->has_value())
1060 __throw_bad_optional_access();
1061 return this->__get();
1062 }
1063
1064 _LIBCPP_INLINE_VISIBILITY
1065 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1066 constexpr value_type& value() &
1067 {
1068 if (!this->has_value())
1069 __throw_bad_optional_access();
1070 return this->__get();
1071 }
1072
1073 _LIBCPP_INLINE_VISIBILITY
1074 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1075 constexpr value_type&& value() &&
1076 {
1077 if (!this->has_value())
1078 __throw_bad_optional_access();
1079 return _VSTD::move(this->__get());
1080 }
1081
1082 _LIBCPP_INLINE_VISIBILITY
1083 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1084 constexpr value_type const&& value() const&&
1085 {
1086 if (!this->has_value())
1087 __throw_bad_optional_access();
1088 return _VSTD::move(this->__get());
1089 }
1090
1091 template <class _Up>
1092 _LIBCPP_INLINE_VISIBILITY
1093 constexpr value_type value_or(_Up&& __v) const&
1094 {
1095 static_assert(is_copy_constructible_v<value_type>,
1096 "optional<T>::value_or: T must be copy constructible");
1097 static_assert(is_convertible_v<_Up, value_type>,
1098 "optional<T>::value_or: U must be convertible to T");
1099 return this->has_value() ? this->__get() :
1100 static_cast<value_type>(_VSTD::forward<_Up>(__v));
1101 }
1102
1103 template <class _Up>
1104 _LIBCPP_INLINE_VISIBILITY
1105 constexpr value_type value_or(_Up&& __v) &&
1106 {
1107 static_assert(is_move_constructible_v<value_type>,
1108 "optional<T>::value_or: T must be move constructible");
1109 static_assert(is_convertible_v<_Up, value_type>,
1110 "optional<T>::value_or: U must be convertible to T");
1111 return this->has_value() ? _VSTD::move(this->__get()) :
1112 static_cast<value_type>(_VSTD::forward<_Up>(__v));
1113 }
1114
1115#if _LIBCPP_STD_VER >= 23
1116 template<class _Func>
1117 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1118 constexpr auto and_then(_Func&& __f) & {
1119 using _Up = invoke_result_t<_Func, value_type&>;
1120 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1121 "Result of f(value()) must be a specialization of std::optional");
1122 if (*this)
1123 return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1124 return remove_cvref_t<_Up>();
1125 }
1126
1127 template<class _Func>
1128 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1129 constexpr auto and_then(_Func&& __f) const& {
1130 using _Up = invoke_result_t<_Func, const value_type&>;
1131 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1132 "Result of f(value()) must be a specialization of std::optional");
1133 if (*this)
1134 return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1135 return remove_cvref_t<_Up>();
1136 }
1137
1138 template<class _Func>
1139 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1140 constexpr auto and_then(_Func&& __f) && {
1141 using _Up = invoke_result_t<_Func, value_type&&>;
1142 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1143 "Result of f(std::move(value())) must be a specialization of std::optional");
1144 if (*this)
1145 return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1146 return remove_cvref_t<_Up>();
1147 }
1148
1149 template<class _Func>
1150 _LIBCPP_HIDE_FROM_ABI
1151 constexpr auto and_then(_Func&& __f) const&& {
1152 using _Up = invoke_result_t<_Func, const value_type&&>;
1153 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1154 "Result of f(std::move(value())) must be a specialization of std::optional");
1155 if (*this)
1156 return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1157 return remove_cvref_t<_Up>();
1158 }
1159
1160 template<class _Func>
1161 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1162 constexpr auto transform(_Func&& __f) & {
1163 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
1164 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1165 static_assert(!is_same_v<_Up, in_place_t>,
1166 "Result of f(value()) should not be std::in_place_t");
1167 static_assert(!is_same_v<_Up, nullopt_t>,
1168 "Result of f(value()) should not be std::nullopt_t");
1169 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1170 if (*this)
1171 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1172 return optional<_Up>();
1173 }
1174
1175 template<class _Func>
1176 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1177 constexpr auto transform(_Func&& __f) const& {
1178 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
1179 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1180 static_assert(!is_same_v<_Up, in_place_t>,
1181 "Result of f(value()) should not be std::in_place_t");
1182 static_assert(!is_same_v<_Up, nullopt_t>,
1183 "Result of f(value()) should not be std::nullopt_t");
1184 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1185 if (*this)
1186 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1187 return optional<_Up>();
1188 }
1189
1190 template<class _Func>
1191 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1192 constexpr auto transform(_Func&& __f) && {
1193 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
1194 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1195 static_assert(!is_same_v<_Up, in_place_t>,
1196 "Result of f(std::move(value())) should not be std::in_place_t");
1197 static_assert(!is_same_v<_Up, nullopt_t>,
1198 "Result of f(std::move(value())) should not be std::nullopt_t");
1199 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1200 if (*this)
1201 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1202 return optional<_Up>();
1203 }
1204
1205 template<class _Func>
1206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1207 constexpr auto transform(_Func&& __f) const&& {
1208 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
1209 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1210 static_assert(!is_same_v<_Up, in_place_t>,
1211 "Result of f(std::move(value())) should not be std::in_place_t");
1212 static_assert(!is_same_v<_Up, nullopt_t>,
1213 "Result of f(std::move(value())) should not be std::nullopt_t");
1214 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1215 if (*this)
1216 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1217 return optional<_Up>();
1218 }
1219
1220 template<invocable _Func>
1221 _LIBCPP_HIDE_FROM_ABI
1222 constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> {
1223 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1224 "Result of f() should be the same type as this optional");
1225 if (*this)
1226 return *this;
1227 return _VSTD::forward<_Func>(__f)();
1228 }
1229
1230 template<invocable _Func>
1231 _LIBCPP_HIDE_FROM_ABI
1232 constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> {
1233 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1234 "Result of f() should be the same type as this optional");
1235 if (*this)
1236 return _VSTD::move(*this);
1237 return _VSTD::forward<_Func>(__f)();
1238 }
1239#endif // _LIBCPP_STD_VER >= 23
1240
1241 using __base::reset;
1242};
1243
1244#if _LIBCPP_STD_VER >= 17
1245template<class _Tp>
1246 optional(_Tp) -> optional<_Tp>;
1247#endif
1248
1249// Comparisons between optionals
1250template <class _Tp, class _Up>
1251_LIBCPP_INLINE_VISIBILITY constexpr
1252enable_if_t<
1253 is_convertible_v<decltype(std::declval<const _Tp&>() ==
1254 std::declval<const _Up&>()), bool>,
1255 bool
1256>
1257operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1258{
1259 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1260 return false;
1261 if (!static_cast<bool>(__x))
1262 return true;
1263 return *__x == *__y;
1264}
1265
1266template <class _Tp, class _Up>
1267_LIBCPP_INLINE_VISIBILITY constexpr
1268enable_if_t<
1269 is_convertible_v<decltype(std::declval<const _Tp&>() !=
1270 std::declval<const _Up&>()), bool>,
1271 bool
1272>
1273operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1274{
1275 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1276 return true;
1277 if (!static_cast<bool>(__x))
1278 return false;
1279 return *__x != *__y;
1280}
1281
1282template <class _Tp, class _Up>
1283_LIBCPP_INLINE_VISIBILITY constexpr
1284enable_if_t<
1285 is_convertible_v<decltype(std::declval<const _Tp&>() <
1286 std::declval<const _Up&>()), bool>,
1287 bool
1288>
1289operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1290{
1291 if (!static_cast<bool>(__y))
1292 return false;
1293 if (!static_cast<bool>(__x))
1294 return true;
1295 return *__x < *__y;
1296}
1297
1298template <class _Tp, class _Up>
1299_LIBCPP_INLINE_VISIBILITY constexpr
1300enable_if_t<
1301 is_convertible_v<decltype(std::declval<const _Tp&>() >
1302 std::declval<const _Up&>()), bool>,
1303 bool
1304>
1305operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1306{
1307 if (!static_cast<bool>(__x))
1308 return false;
1309 if (!static_cast<bool>(__y))
1310 return true;
1311 return *__x > *__y;
1312}
1313
1314template <class _Tp, class _Up>
1315_LIBCPP_INLINE_VISIBILITY constexpr
1316enable_if_t<
1317 is_convertible_v<decltype(std::declval<const _Tp&>() <=
1318 std::declval<const _Up&>()), bool>,
1319 bool
1320>
1321operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1322{
1323 if (!static_cast<bool>(__x))
1324 return true;
1325 if (!static_cast<bool>(__y))
1326 return false;
1327 return *__x <= *__y;
1328}
1329
1330template <class _Tp, class _Up>
1331_LIBCPP_INLINE_VISIBILITY constexpr
1332enable_if_t<
1333 is_convertible_v<decltype(std::declval<const _Tp&>() >=
1334 std::declval<const _Up&>()), bool>,
1335 bool
1336>
1337operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1338{
1339 if (!static_cast<bool>(__y))
1340 return true;
1341 if (!static_cast<bool>(__x))
1342 return false;
1343 return *__x >= *__y;
1344}
1345
1346#if _LIBCPP_STD_VER >= 20
1347
1348template <class _Tp, three_way_comparable_with<_Tp> _Up>
1349_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1350operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1351 if (__x && __y)
1352 return *__x <=> *__y;
1353 return __x.has_value() <=> __y.has_value();
1354}
1355
1356#endif // _LIBCPP_STD_VER >= 20
1357
1358// Comparisons with nullopt
1359template <class _Tp>
1360_LIBCPP_INLINE_VISIBILITY constexpr
1361bool
1362operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1363{
1364 return !static_cast<bool>(__x);
1365}
1366
1367#if _LIBCPP_STD_VER <= 17
1368
1369template <class _Tp>
1370_LIBCPP_INLINE_VISIBILITY constexpr
1371bool
1372operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1373{
1374 return !static_cast<bool>(__x);
1375}
1376
1377template <class _Tp>
1378_LIBCPP_INLINE_VISIBILITY constexpr
1379bool
1380operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1381{
1382 return static_cast<bool>(__x);
1383}
1384
1385template <class _Tp>
1386_LIBCPP_INLINE_VISIBILITY constexpr
1387bool
1388operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1389{
1390 return static_cast<bool>(__x);
1391}
1392
1393template <class _Tp>
1394_LIBCPP_INLINE_VISIBILITY constexpr
1395bool
1396operator<(const optional<_Tp>&, nullopt_t) noexcept
1397{
1398 return false;
1399}
1400
1401template <class _Tp>
1402_LIBCPP_INLINE_VISIBILITY constexpr
1403bool
1404operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1405{
1406 return static_cast<bool>(__x);
1407}
1408
1409template <class _Tp>
1410_LIBCPP_INLINE_VISIBILITY constexpr
1411bool
1412operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1413{
1414 return !static_cast<bool>(__x);
1415}
1416
1417template <class _Tp>
1418_LIBCPP_INLINE_VISIBILITY constexpr
1419bool
1420operator<=(nullopt_t, const optional<_Tp>&) noexcept
1421{
1422 return true;
1423}
1424
1425template <class _Tp>
1426_LIBCPP_INLINE_VISIBILITY constexpr
1427bool
1428operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1429{
1430 return static_cast<bool>(__x);
1431}
1432
1433template <class _Tp>
1434_LIBCPP_INLINE_VISIBILITY constexpr
1435bool
1436operator>(nullopt_t, const optional<_Tp>&) noexcept
1437{
1438 return false;
1439}
1440
1441template <class _Tp>
1442_LIBCPP_INLINE_VISIBILITY constexpr
1443bool
1444operator>=(const optional<_Tp>&, nullopt_t) noexcept
1445{
1446 return true;
1447}
1448
1449template <class _Tp>
1450_LIBCPP_INLINE_VISIBILITY constexpr
1451bool
1452operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1453{
1454 return !static_cast<bool>(__x);
1455}
1456
1457#else // _LIBCPP_STD_VER <= 17
1458
1459template <class _Tp>
1460_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
1461 return __x.has_value() <=> false;
1462}
1463
1464#endif // _LIBCPP_STD_VER <= 17
1465
1466// Comparisons with T
1467template <class _Tp, class _Up>
1468_LIBCPP_INLINE_VISIBILITY constexpr
1469enable_if_t<
1470 is_convertible_v<decltype(std::declval<const _Tp&>() ==
1471 std::declval<const _Up&>()), bool>,
1472 bool
1473>
1474operator==(const optional<_Tp>& __x, const _Up& __v)
1475{
1476 return static_cast<bool>(__x) ? *__x == __v : false;
1477}
1478
1479template <class _Tp, class _Up>
1480_LIBCPP_INLINE_VISIBILITY constexpr
1481enable_if_t<
1482 is_convertible_v<decltype(std::declval<const _Tp&>() ==
1483 std::declval<const _Up&>()), bool>,
1484 bool
1485>
1486operator==(const _Tp& __v, const optional<_Up>& __x)
1487{
1488 return static_cast<bool>(__x) ? __v == *__x : false;
1489}
1490
1491template <class _Tp, class _Up>
1492_LIBCPP_INLINE_VISIBILITY constexpr
1493enable_if_t<
1494 is_convertible_v<decltype(std::declval<const _Tp&>() !=
1495 std::declval<const _Up&>()), bool>,
1496 bool
1497>
1498operator!=(const optional<_Tp>& __x, const _Up& __v)
1499{
1500 return static_cast<bool>(__x) ? *__x != __v : true;
1501}
1502
1503template <class _Tp, class _Up>
1504_LIBCPP_INLINE_VISIBILITY constexpr
1505enable_if_t<
1506 is_convertible_v<decltype(std::declval<const _Tp&>() !=
1507 std::declval<const _Up&>()), bool>,
1508 bool
1509>
1510operator!=(const _Tp& __v, const optional<_Up>& __x)
1511{
1512 return static_cast<bool>(__x) ? __v != *__x : true;
1513}
1514
1515template <class _Tp, class _Up>
1516_LIBCPP_INLINE_VISIBILITY constexpr
1517enable_if_t<
1518 is_convertible_v<decltype(std::declval<const _Tp&>() <
1519 std::declval<const _Up&>()), bool>,
1520 bool
1521>
1522operator<(const optional<_Tp>& __x, const _Up& __v)
1523{
1524 return static_cast<bool>(__x) ? *__x < __v : true;
1525}
1526
1527template <class _Tp, class _Up>
1528_LIBCPP_INLINE_VISIBILITY constexpr
1529enable_if_t<
1530 is_convertible_v<decltype(std::declval<const _Tp&>() <
1531 std::declval<const _Up&>()), bool>,
1532 bool
1533>
1534operator<(const _Tp& __v, const optional<_Up>& __x)
1535{
1536 return static_cast<bool>(__x) ? __v < *__x : false;
1537}
1538
1539template <class _Tp, class _Up>
1540_LIBCPP_INLINE_VISIBILITY constexpr
1541enable_if_t<
1542 is_convertible_v<decltype(std::declval<const _Tp&>() <=
1543 std::declval<const _Up&>()), bool>,
1544 bool
1545>
1546operator<=(const optional<_Tp>& __x, const _Up& __v)
1547{
1548 return static_cast<bool>(__x) ? *__x <= __v : true;
1549}
1550
1551template <class _Tp, class _Up>
1552_LIBCPP_INLINE_VISIBILITY constexpr
1553enable_if_t<
1554 is_convertible_v<decltype(std::declval<const _Tp&>() <=
1555 std::declval<const _Up&>()), bool>,
1556 bool
1557>
1558operator<=(const _Tp& __v, const optional<_Up>& __x)
1559{
1560 return static_cast<bool>(__x) ? __v <= *__x : false;
1561}
1562
1563template <class _Tp, class _Up>
1564_LIBCPP_INLINE_VISIBILITY constexpr
1565enable_if_t<
1566 is_convertible_v<decltype(std::declval<const _Tp&>() >
1567 std::declval<const _Up&>()), bool>,
1568 bool
1569>
1570operator>(const optional<_Tp>& __x, const _Up& __v)
1571{
1572 return static_cast<bool>(__x) ? *__x > __v : false;
1573}
1574
1575template <class _Tp, class _Up>
1576_LIBCPP_INLINE_VISIBILITY constexpr
1577enable_if_t<
1578 is_convertible_v<decltype(std::declval<const _Tp&>() >
1579 std::declval<const _Up&>()), bool>,
1580 bool
1581>
1582operator>(const _Tp& __v, const optional<_Up>& __x)
1583{
1584 return static_cast<bool>(__x) ? __v > *__x : true;
1585}
1586
1587template <class _Tp, class _Up>
1588_LIBCPP_INLINE_VISIBILITY constexpr
1589enable_if_t<
1590 is_convertible_v<decltype(std::declval<const _Tp&>() >=
1591 std::declval<const _Up&>()), bool>,
1592 bool
1593>
1594operator>=(const optional<_Tp>& __x, const _Up& __v)
1595{
1596 return static_cast<bool>(__x) ? *__x >= __v : false;
1597}
1598
1599template <class _Tp, class _Up>
1600_LIBCPP_INLINE_VISIBILITY constexpr
1601enable_if_t<
1602 is_convertible_v<decltype(std::declval<const _Tp&>() >=
1603 std::declval<const _Up&>()), bool>,
1604 bool
1605>
1606operator>=(const _Tp& __v, const optional<_Up>& __x)
1607{
1608 return static_cast<bool>(__x) ? __v >= *__x : true;
1609}
1610
1611#if _LIBCPP_STD_VER >= 20
1612
1613template <class _Tp, class _Up>
1614 requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
1615_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1616operator<=>(const optional<_Tp>& __x, const _Up& __v) {
1617 return __x.has_value() ? *__x <=> __v : strong_ordering::less;
1618}
1619
1620#endif // _LIBCPP_STD_VER >= 20
1621
1622
1623template <class _Tp>
1624inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1625enable_if_t<
1626 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1627 void
1628>
1629swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1630{
1631 __x.swap(__y);
1632}
1633
1634template <class _Tp>
1635_LIBCPP_INLINE_VISIBILITY constexpr
1636optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1637{
1638 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1639}
1640
1641template <class _Tp, class... _Args>
1642_LIBCPP_INLINE_VISIBILITY constexpr
1643optional<_Tp> make_optional(_Args&&... __args)
1644{
1645 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1646}
1647
1648template <class _Tp, class _Up, class... _Args>
1649_LIBCPP_INLINE_VISIBILITY constexpr
1650optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1651{
1652 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1653}
1654
1655template <class _Tp>
1656struct _LIBCPP_TEMPLATE_VIS hash<
1657 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1658>
1659{
1660#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1661 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1662 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1663#endif
1664
1665 _LIBCPP_INLINE_VISIBILITY
1666 size_t operator()(const optional<_Tp>& __opt) const
1667 {
1668 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1669 }
1670};
1671
1672_LIBCPP_END_NAMESPACE_STD
1673
1674#endif // _LIBCPP_STD_VER >= 17
1675
1676_LIBCPP_POP_MACROS
1677
1678#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1679# include <atomic>
1680# include <climits>
1681# include <concepts>
1682# include <ctime>
1683# include <iterator>
1684# include <memory>
1685# include <ratio>
1686# include <tuple>
1687# include <type_traits>
1688# include <typeinfo>
1689# include <utility>
1690# include <variant>
1691#endif
1692
1693#endif // _LIBCPP_OPTIONAL