Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / optional
blobab90cc8ce7f776cdd7ebf2e3d2054df79834eb9c
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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_OPTIONAL
11 #define _LIBCPP_OPTIONAL
14     optional synopsis
16 // C++1z
18 namespace std {
19   // [optional.optional], class template optional
20   template <class T>
21     class optional;
23   template<class T>
24     concept is-derived-from-optional = requires(const T& t) {       // exposition only
25       []<class U>(const optional<U>&){ }(t);
26     };
28   // [optional.nullopt], no-value state indicator
29   struct nullopt_t{see below };
30   inline constexpr nullopt_t nullopt(unspecified );
32   // [optional.bad.access], class bad_optional_access
33   class bad_optional_access;
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
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
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
86   // [optional.specalg], specialized algorithms
87   template<class T>
88     void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
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);
97   // [optional.hash], hash support
98   template<class T> struct hash;
99   template<class T> struct hash<optional<T>>;
101   template<class T>
102   class optional {
103   public:
104     using value_type = T;
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
122     // [optional.dtor], destructor
123     ~optional(); // constexpr in C++20
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
135     // [optional.swap], swap
136     void swap(optional &) noexcept(see below ); // constexpr in C++20
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 &&) &&;
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
166     // [optional.mod], modifiers
167     void reset() noexcept;                                      // constexpr in C++20
169   private:
170     T *val;         // exposition only
171   };
173   template<class T>
174     optional(T) -> optional<T>;
176 } // namespace std
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 <__exception/exception.h>
187 #include <__functional/hash.h>
188 #include <__functional/invoke.h>
189 #include <__functional/reference_wrapper.h>
190 #include <__functional/unary_function.h>
191 #include <__memory/addressof.h>
192 #include <__memory/construct_at.h>
193 #include <__tuple/sfinae_helpers.h>
194 #include <__type_traits/add_pointer.h>
195 #include <__type_traits/conditional.h>
196 #include <__type_traits/conjunction.h>
197 #include <__type_traits/decay.h>
198 #include <__type_traits/disjunction.h>
199 #include <__type_traits/is_array.h>
200 #include <__type_traits/is_assignable.h>
201 #include <__type_traits/is_constructible.h>
202 #include <__type_traits/is_convertible.h>
203 #include <__type_traits/is_copy_assignable.h>
204 #include <__type_traits/is_copy_constructible.h>
205 #include <__type_traits/is_destructible.h>
206 #include <__type_traits/is_move_assignable.h>
207 #include <__type_traits/is_move_constructible.h>
208 #include <__type_traits/is_nothrow_move_assignable.h>
209 #include <__type_traits/is_nothrow_move_constructible.h>
210 #include <__type_traits/is_object.h>
211 #include <__type_traits/is_reference.h>
212 #include <__type_traits/is_scalar.h>
213 #include <__type_traits/is_swappable.h>
214 #include <__type_traits/is_trivially_copy_assignable.h>
215 #include <__type_traits/is_trivially_copy_constructible.h>
216 #include <__type_traits/is_trivially_destructible.h>
217 #include <__type_traits/is_trivially_move_assignable.h>
218 #include <__type_traits/is_trivially_move_constructible.h>
219 #include <__type_traits/negation.h>
220 #include <__type_traits/remove_const.h>
221 #include <__type_traits/remove_cvref.h>
222 #include <__type_traits/remove_reference.h>
223 #include <__utility/declval.h>
224 #include <__utility/forward.h>
225 #include <__utility/in_place.h>
226 #include <__utility/move.h>
227 #include <__utility/swap.h>
228 #include <__verbose_abort>
229 #include <initializer_list>
230 #include <new>
231 #include <version>
233 // standard-mandated includes
235 // [optional.syn]
236 #include <compare>
238 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
239 #  pragma GCC system_header
240 #endif
242 _LIBCPP_PUSH_MACROS
243 #include <__undef_macros>
245 namespace std  // purposefully not using versioning namespace
248 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
249     : public exception
251 public:
252     _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT = default;
253     _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT = default;
254     _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
255     // Get the key function ~bad_optional_access() into the dylib
256     ~bad_optional_access() _NOEXCEPT override;
257     const char* what() const _NOEXCEPT override;
260 } // namespace std
262 #if _LIBCPP_STD_VER >= 17
264 _LIBCPP_BEGIN_NAMESPACE_STD
266 _LIBCPP_NORETURN
267 inline _LIBCPP_INLINE_VISIBILITY
268 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
269 void __throw_bad_optional_access() {
270 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
271         throw bad_optional_access();
272 #else
273     _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
274 #endif
277 struct nullopt_t
279     struct __secret_tag { explicit __secret_tag() = default; };
280     _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
283 inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
285 struct __optional_construct_from_invoke_tag {};
287 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
288 struct __optional_destruct_base;
290 template <class _Tp>
291 struct __optional_destruct_base<_Tp, false>
293     typedef _Tp value_type;
294     static_assert(is_object_v<value_type>,
295         "instantiation of optional with a non-object type is undefined behavior");
296     union
297     {
298         char __null_state_;
299         value_type __val_;
300     };
301     bool __engaged_;
303     _LIBCPP_INLINE_VISIBILITY
304     _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base()
305     {
306         if (__engaged_)
307             __val_.~value_type();
308     }
310     _LIBCPP_INLINE_VISIBILITY
311     constexpr __optional_destruct_base() noexcept
312         :  __null_state_(),
313            __engaged_(false) {}
315     template <class... _Args>
316     _LIBCPP_INLINE_VISIBILITY
317     constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
318         :  __val_(_VSTD::forward<_Args>(__args)...),
319            __engaged_(true) {}
321 #if _LIBCPP_STD_VER >= 23
322   template <class _Fp, class... _Args>
323   _LIBCPP_HIDE_FROM_ABI
324   constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
325       : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
326 #endif
328     _LIBCPP_INLINE_VISIBILITY
329     _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept
330     {
331         if (__engaged_)
332         {
333             __val_.~value_type();
334             __engaged_ = false;
335         }
336     }
339 template <class _Tp>
340 struct __optional_destruct_base<_Tp, true>
342     typedef _Tp value_type;
343     static_assert(is_object_v<value_type>,
344         "instantiation of optional with a non-object type is undefined behavior");
345     union
346     {
347         char __null_state_;
348         value_type __val_;
349     };
350     bool __engaged_;
352     _LIBCPP_INLINE_VISIBILITY
353     constexpr __optional_destruct_base() noexcept
354         :  __null_state_(),
355            __engaged_(false) {}
357     template <class... _Args>
358     _LIBCPP_INLINE_VISIBILITY
359     constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
360         :  __val_(_VSTD::forward<_Args>(__args)...),
361            __engaged_(true) {}
363 #if _LIBCPP_STD_VER >= 23
364   template <class _Fp, class... _Args>
365   _LIBCPP_HIDE_FROM_ABI
366   constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
367       : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
368 #endif
370     _LIBCPP_INLINE_VISIBILITY
371     _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept
372     {
373         if (__engaged_)
374         {
375             __engaged_ = false;
376         }
377     }
380 template <class _Tp, bool = is_reference<_Tp>::value>
381 struct __optional_storage_base : __optional_destruct_base<_Tp>
383     using __base = __optional_destruct_base<_Tp>;
384     using value_type = _Tp;
385     using __base::__base;
387     _LIBCPP_INLINE_VISIBILITY
388     constexpr bool has_value() const noexcept
389     {
390         return this->__engaged_;
391     }
393     _LIBCPP_INLINE_VISIBILITY
394     constexpr value_type& __get() & noexcept
395     {
396         return this->__val_;
397     }
398     _LIBCPP_INLINE_VISIBILITY
399     constexpr const value_type& __get() const& noexcept
400     {
401         return this->__val_;
402     }
403     _LIBCPP_INLINE_VISIBILITY
404     constexpr value_type&& __get() && noexcept
405     {
406         return _VSTD::move(this->__val_);
407     }
408     _LIBCPP_INLINE_VISIBILITY
409     constexpr const value_type&& __get() const&& noexcept
410     {
411         return _VSTD::move(this->__val_);
412     }
414     template <class... _Args>
415     _LIBCPP_INLINE_VISIBILITY
416     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args)
417     {
418         _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
419 #if _LIBCPP_STD_VER >= 20
420         _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
421 #else
422         ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
423 #endif
424         this->__engaged_ = true;
425     }
427     template <class _That>
428     _LIBCPP_INLINE_VISIBILITY
429     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt)
430     {
431         if (__opt.has_value())
432             __construct(_VSTD::forward<_That>(__opt).__get());
433     }
435     template <class _That>
436     _LIBCPP_INLINE_VISIBILITY
437     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt)
438     {
439         if (this->__engaged_ == __opt.has_value())
440         {
441             if (this->__engaged_)
442                 this->__val_ = _VSTD::forward<_That>(__opt).__get();
443         }
444         else
445         {
446             if (this->__engaged_)
447                 this->reset();
448             else
449                 __construct(_VSTD::forward<_That>(__opt).__get());
450         }
451     }
454 // optional<T&> is currently required to be ill-formed. However, it may
455 // be allowed in the future. For this reason, it has already been implemented
456 // to ensure we can make the change in an ABI-compatible manner.
457 template <class _Tp>
458 struct __optional_storage_base<_Tp, true>
460     using value_type = _Tp;
461     using __raw_type = remove_reference_t<_Tp>;
462     __raw_type* __value_;
464     template <class _Up>
465     static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
466         using _RawUp = __libcpp_remove_reference_t<_Up>;
467         using _UpPtr = _RawUp*;
468         using _RawTp = __libcpp_remove_reference_t<_Tp>;
469         using _TpPtr = _RawTp*;
470         using _CheckLValueArg = integral_constant<bool,
471             (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
472         ||  is_same<_RawUp, reference_wrapper<_RawTp>>::value
473         ||  is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value
474         >;
475         return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
476             || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
477                 is_convertible<_UpPtr, _TpPtr>::value);
478     }
480     _LIBCPP_INLINE_VISIBILITY
481     constexpr __optional_storage_base() noexcept
482         :  __value_(nullptr) {}
484     template <class _UArg>
485     _LIBCPP_INLINE_VISIBILITY
486     constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
487         :  __value_(_VSTD::addressof(__uarg))
488     {
489       static_assert(__can_bind_reference<_UArg>(),
490         "Attempted to construct a reference element in tuple from a "
491         "possible temporary");
492     }
494     _LIBCPP_INLINE_VISIBILITY
495     _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
497     _LIBCPP_INLINE_VISIBILITY
498     constexpr bool has_value() const noexcept
499       { return __value_ != nullptr; }
501     _LIBCPP_INLINE_VISIBILITY
502     constexpr value_type& __get() const& noexcept
503       { return *__value_; }
505     _LIBCPP_INLINE_VISIBILITY
506     constexpr value_type&& __get() const&& noexcept
507       { return _VSTD::forward<value_type>(*__value_); }
509     template <class _UArg>
510     _LIBCPP_INLINE_VISIBILITY
511     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val)
512     {
513         _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
514         static_assert(__can_bind_reference<_UArg>(),
515             "Attempted to construct a reference element in tuple from a "
516             "possible temporary");
517         __value_ = _VSTD::addressof(__val);
518     }
520     template <class _That>
521     _LIBCPP_INLINE_VISIBILITY
522     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt)
523     {
524         if (__opt.has_value())
525             __construct(_VSTD::forward<_That>(__opt).__get());
526     }
528     template <class _That>
529     _LIBCPP_INLINE_VISIBILITY
530     _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt)
531     {
532         if (has_value() == __opt.has_value())
533         {
534             if (has_value())
535                 *__value_ = _VSTD::forward<_That>(__opt).__get();
536         }
537         else
538         {
539             if (has_value())
540                 reset();
541             else
542                 __construct(_VSTD::forward<_That>(__opt).__get());
543         }
544     }
547 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
548 struct __optional_copy_base : __optional_storage_base<_Tp>
550     using __optional_storage_base<_Tp>::__optional_storage_base;
553 template <class _Tp>
554 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
556     using __optional_storage_base<_Tp>::__optional_storage_base;
558     _LIBCPP_INLINE_VISIBILITY
559     __optional_copy_base() = default;
561     _LIBCPP_INLINE_VISIBILITY
562     _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt)
563     {
564         this->__construct_from(__opt);
565     }
567     _LIBCPP_INLINE_VISIBILITY
568     __optional_copy_base(__optional_copy_base&&) = default;
569     _LIBCPP_INLINE_VISIBILITY
570     __optional_copy_base& operator=(const __optional_copy_base&) = default;
571     _LIBCPP_INLINE_VISIBILITY
572     __optional_copy_base& operator=(__optional_copy_base&&) = default;
575 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
576 struct __optional_move_base : __optional_copy_base<_Tp>
578     using __optional_copy_base<_Tp>::__optional_copy_base;
581 template <class _Tp>
582 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
584     using value_type = _Tp;
585     using __optional_copy_base<_Tp>::__optional_copy_base;
587     _LIBCPP_INLINE_VISIBILITY
588     __optional_move_base() = default;
589     _LIBCPP_INLINE_VISIBILITY
590     __optional_move_base(const __optional_move_base&) = default;
592     _LIBCPP_INLINE_VISIBILITY
593     _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_base(__optional_move_base&& __opt)
594         noexcept(is_nothrow_move_constructible_v<value_type>)
595     {
596         this->__construct_from(_VSTD::move(__opt));
597     }
599     _LIBCPP_INLINE_VISIBILITY
600     __optional_move_base& operator=(const __optional_move_base&) = default;
601     _LIBCPP_INLINE_VISIBILITY
602     __optional_move_base& operator=(__optional_move_base&&) = default;
605 template <class _Tp, bool =
606     is_trivially_destructible<_Tp>::value &&
607     is_trivially_copy_constructible<_Tp>::value &&
608     is_trivially_copy_assignable<_Tp>::value>
609 struct __optional_copy_assign_base : __optional_move_base<_Tp>
611     using __optional_move_base<_Tp>::__optional_move_base;
614 template <class _Tp>
615 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
617     using __optional_move_base<_Tp>::__optional_move_base;
619     _LIBCPP_INLINE_VISIBILITY
620     __optional_copy_assign_base() = default;
621     _LIBCPP_INLINE_VISIBILITY
622     __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
623     _LIBCPP_INLINE_VISIBILITY
624     __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
626     _LIBCPP_INLINE_VISIBILITY
627     _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
628     {
629         this->__assign_from(__opt);
630         return *this;
631     }
633     _LIBCPP_INLINE_VISIBILITY
634     __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
637 template <class _Tp, bool =
638     is_trivially_destructible<_Tp>::value &&
639     is_trivially_move_constructible<_Tp>::value &&
640     is_trivially_move_assignable<_Tp>::value>
641 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
643     using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
646 template <class _Tp>
647 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
649     using value_type = _Tp;
650     using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
652     _LIBCPP_INLINE_VISIBILITY
653     __optional_move_assign_base() = default;
654     _LIBCPP_INLINE_VISIBILITY
655     __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
656     _LIBCPP_INLINE_VISIBILITY
657     __optional_move_assign_base(__optional_move_assign_base&&) = default;
658     _LIBCPP_INLINE_VISIBILITY
659     __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
661     _LIBCPP_INLINE_VISIBILITY
662     _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
663         noexcept(is_nothrow_move_assignable_v<value_type> &&
664                  is_nothrow_move_constructible_v<value_type>)
665     {
666         this->__assign_from(_VSTD::move(__opt));
667         return *this;
668     }
671 template <class _Tp>
672 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
673     is_copy_constructible<_Tp>::value,
674     is_move_constructible<_Tp>::value
677 template <class _Tp>
678 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
679     (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
680     (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
683 template<class _Tp>
684 class optional;
686 #if _LIBCPP_STD_VER >= 20
688 template <class _Tp>
689 concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
691 #  endif // _LIBCPP_STD_VER >= 20
693 template <class _Tp>
694 struct __is_std_optional : false_type {};
695 template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
697 template <class _Tp>
698 class _LIBCPP_DECLSPEC_EMPTY_BASES optional
699     : private __optional_move_assign_base<_Tp>
700     , private __optional_sfinae_ctor_base_t<_Tp>
701     , private __optional_sfinae_assign_base_t<_Tp>
703     using __base = __optional_move_assign_base<_Tp>;
704 public:
705     using value_type = _Tp;
707 private:
708      // Disable the reference extension using this static assert.
709     static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
710         "instantiation of optional with in_place_t is ill-formed");
711     static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
712         "instantiation of optional with nullopt_t is ill-formed");
713     static_assert(!is_reference_v<value_type>,
714         "instantiation of optional with a reference type is ill-formed");
715     static_assert(is_destructible_v<value_type>,
716         "instantiation of optional with a non-destructible type is ill-formed");
717     static_assert(!is_array_v<value_type>,
718         "instantiation of optional with an array type is ill-formed");
720     // LWG2756: conditionally explicit conversion from _Up
721     struct _CheckOptionalArgsConstructor {
722       template <class _Up>
723       _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
724           return is_constructible_v<_Tp, _Up&&> &&
725                  is_convertible_v<_Up&&, _Tp>;
726       }
728       template <class _Up>
729       _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
730           return is_constructible_v<_Tp, _Up&&> &&
731                  !is_convertible_v<_Up&&, _Tp>;
732       }
733     };
734     template <class _Up>
735     using _CheckOptionalArgsCtor = _If<
736         _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value &&
737         _IsNotSame<__remove_cvref_t<_Up>, optional>::value &&
738         (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value),
739         _CheckOptionalArgsConstructor,
740         __check_tuple_constructor_fail
741     >;
742     template <class _QualUp>
743     struct _CheckOptionalLikeConstructor {
744       template <class _Up, class _Opt = optional<_Up>>
745       using __check_constructible_from_opt = _Or<
746           is_constructible<_Tp, _Opt&>,
747           is_constructible<_Tp, _Opt const&>,
748           is_constructible<_Tp, _Opt&&>,
749           is_constructible<_Tp, _Opt const&&>,
750           is_convertible<_Opt&, _Tp>,
751           is_convertible<_Opt const&, _Tp>,
752           is_convertible<_Opt&&, _Tp>,
753           is_convertible<_Opt const&&, _Tp>
754       >;
755       template <class _Up, class _Opt = optional<_Up>>
756       using __check_assignable_from_opt = _Or<
757           is_assignable<_Tp&, _Opt&>,
758           is_assignable<_Tp&, _Opt const&>,
759           is_assignable<_Tp&, _Opt&&>,
760           is_assignable<_Tp&, _Opt const&&>
761       >;
762       template <class _Up, class _QUp = _QualUp>
763       _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
764           return is_convertible<_QUp, _Tp>::value &&
765                  (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
766       }
767       template <class _Up, class _QUp = _QualUp>
768       _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
769           return !is_convertible<_QUp, _Tp>::value &&
770                  (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
771       }
772       template <class _Up, class _QUp = _QualUp>
773       _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
774           // Construction and assignability of _QUp to _Tp has already been
775           // checked.
776           return !__check_constructible_from_opt<_Up>::value &&
777               !__check_assignable_from_opt<_Up>::value;
778       }
779     };
781     template <class _Up, class _QualUp>
782     using _CheckOptionalLikeCtor = _If<
783       _And<
784          _IsNotSame<_Up, _Tp>,
785           is_constructible<_Tp, _QualUp>
786       >::value,
787       _CheckOptionalLikeConstructor<_QualUp>,
788       __check_tuple_constructor_fail
789     >;
790     template <class _Up, class _QualUp>
791     using _CheckOptionalLikeAssign = _If<
792       _And<
793           _IsNotSame<_Up, _Tp>,
794           is_constructible<_Tp, _QualUp>,
795           is_assignable<_Tp&, _QualUp>
796       >::value,
797       _CheckOptionalLikeConstructor<_QualUp>,
798       __check_tuple_constructor_fail
799     >;
801 public:
803     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
804     _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
805     _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
806     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
808     template <class _InPlaceT, class... _Args, class = enable_if_t<
809           _And<
810               _IsSame<_InPlaceT, in_place_t>,
811               is_constructible<value_type, _Args...>
812             >::value
813         >
814     >
815     _LIBCPP_INLINE_VISIBILITY
816     constexpr explicit optional(_InPlaceT, _Args&&... __args)
817         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
819     template <class _Up, class... _Args, class = enable_if_t<
820         is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
821     >
822     _LIBCPP_INLINE_VISIBILITY
823     constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
824         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
826     template <class _Up = value_type, enable_if_t<
827         _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
828     , int> = 0>
829     _LIBCPP_INLINE_VISIBILITY
830     constexpr optional(_Up&& __v)
831         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
833     template <class _Up, enable_if_t<
834         _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
835     , int> = 0>
836     _LIBCPP_INLINE_VISIBILITY
837     constexpr explicit optional(_Up&& __v)
838         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
840     // LWG2756: conditionally explicit conversion from const optional<_Up>&
841     template <class _Up, enable_if_t<
842         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
843     , int> = 0>
844     _LIBCPP_INLINE_VISIBILITY
845     _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v)
846     {
847         this->__construct_from(__v);
848     }
849     template <class _Up, enable_if_t<
850         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
851     , int> = 0>
852     _LIBCPP_INLINE_VISIBILITY
853     _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v)
854     {
855         this->__construct_from(__v);
856     }
858     // LWG2756: conditionally explicit conversion from optional<_Up>&&
859     template <class _Up, enable_if_t<
860         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
861     , int> = 0>
862     _LIBCPP_INLINE_VISIBILITY
863     _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v)
864     {
865         this->__construct_from(_VSTD::move(__v));
866     }
867     template <class _Up, enable_if_t<
868         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
869     , int> = 0>
870     _LIBCPP_INLINE_VISIBILITY
871     _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v)
872     {
873         this->__construct_from(_VSTD::move(__v));
874     }
876 #if _LIBCPP_STD_VER >= 23
877   template<class _Fp, class... _Args>
878   _LIBCPP_HIDE_FROM_ABI
879   constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
880       : __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) {
881   }
882 #endif
884     _LIBCPP_INLINE_VISIBILITY
885     _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept
886     {
887         reset();
888         return *this;
889     }
891     _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
892     _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
894     // LWG2756
895     template <class _Up = value_type,
896               class = enable_if_t<
897                       _And<
898                           _IsNotSame<__remove_cvref_t<_Up>, optional>,
899                           _Or<
900                               _IsNotSame<__remove_cvref_t<_Up>, value_type>,
901                               _Not<is_scalar<value_type>>
902                           >,
903                           is_constructible<value_type, _Up>,
904                           is_assignable<value_type&, _Up>
905                       >::value>
906              >
907     _LIBCPP_INLINE_VISIBILITY
908     _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
909     operator=(_Up&& __v)
910     {
911         if (this->has_value())
912             this->__get() = _VSTD::forward<_Up>(__v);
913         else
914             this->__construct(_VSTD::forward<_Up>(__v));
915         return *this;
916     }
918     // LWG2756
919     template <class _Up, enable_if_t<
920         _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
921     , int> = 0>
922     _LIBCPP_INLINE_VISIBILITY
923     _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
924     operator=(const optional<_Up>& __v)
925     {
926         this->__assign_from(__v);
927         return *this;
928     }
930     // LWG2756
931     template <class _Up, enable_if_t<
932         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
933     , int> = 0>
934     _LIBCPP_INLINE_VISIBILITY
935     _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
936     operator=(optional<_Up>&& __v)
937     {
938         this->__assign_from(_VSTD::move(__v));
939         return *this;
940     }
942     template <class... _Args,
943               class = enable_if_t
944                       <
945                           is_constructible_v<value_type, _Args...>
946                       >
947              >
948     _LIBCPP_INLINE_VISIBILITY
949     _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &
950     emplace(_Args&&... __args)
951     {
952         reset();
953         this->__construct(_VSTD::forward<_Args>(__args)...);
954         return this->__get();
955     }
957     template <class _Up, class... _Args,
958               class = enable_if_t
959                       <
960                           is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
961                       >
962              >
963     _LIBCPP_INLINE_VISIBILITY
964     _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &
965     emplace(initializer_list<_Up> __il, _Args&&... __args)
966     {
967         reset();
968         this->__construct(__il, _VSTD::forward<_Args>(__args)...);
969         return this->__get();
970     }
972     _LIBCPP_INLINE_VISIBILITY
973     _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt)
974         noexcept(is_nothrow_move_constructible_v<value_type> &&
975                  is_nothrow_swappable_v<value_type>)
976     {
977         if (this->has_value() == __opt.has_value())
978         {
979             using _VSTD::swap;
980             if (this->has_value())
981                 swap(this->__get(), __opt.__get());
982         }
983         else
984         {
985             if (this->has_value())
986             {
987                 __opt.__construct(_VSTD::move(this->__get()));
988                 reset();
989             }
990             else
991             {
992                 this->__construct(_VSTD::move(__opt.__get()));
993                 __opt.reset();
994             }
995         }
996     }
998     _LIBCPP_INLINE_VISIBILITY
999     constexpr
1000     add_pointer_t<value_type const>
1001     operator->() const
1002     {
1003         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
1004         return _VSTD::addressof(this->__get());
1005     }
1007     _LIBCPP_INLINE_VISIBILITY
1008     constexpr
1009     add_pointer_t<value_type>
1010     operator->()
1011     {
1012         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
1013         return _VSTD::addressof(this->__get());
1014     }
1016     _LIBCPP_INLINE_VISIBILITY
1017     constexpr
1018     const value_type&
1019     operator*() const& noexcept
1020     {
1021         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1022         return this->__get();
1023     }
1025     _LIBCPP_INLINE_VISIBILITY
1026     constexpr
1027     value_type&
1028     operator*() & noexcept
1029     {
1030         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1031         return this->__get();
1032     }
1034     _LIBCPP_INLINE_VISIBILITY
1035     constexpr
1036     value_type&&
1037     operator*() && noexcept
1038     {
1039         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1040         return _VSTD::move(this->__get());
1041     }
1043     _LIBCPP_INLINE_VISIBILITY
1044     constexpr
1045     const value_type&&
1046     operator*() const&& noexcept
1047     {
1048         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
1049         return _VSTD::move(this->__get());
1050     }
1052     _LIBCPP_INLINE_VISIBILITY
1053     constexpr explicit operator bool() const noexcept { return has_value(); }
1055     using __base::has_value;
1056     using __base::__get;
1058     _LIBCPP_INLINE_VISIBILITY
1059     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1060     constexpr value_type const& value() const&
1061     {
1062         if (!this->has_value())
1063             __throw_bad_optional_access();
1064         return this->__get();
1065     }
1067     _LIBCPP_INLINE_VISIBILITY
1068     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1069     constexpr value_type& value() &
1070     {
1071         if (!this->has_value())
1072             __throw_bad_optional_access();
1073         return this->__get();
1074     }
1076     _LIBCPP_INLINE_VISIBILITY
1077     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1078     constexpr value_type&& value() &&
1079     {
1080         if (!this->has_value())
1081             __throw_bad_optional_access();
1082         return _VSTD::move(this->__get());
1083     }
1085     _LIBCPP_INLINE_VISIBILITY
1086     _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1087     constexpr value_type const&& value() const&&
1088     {
1089         if (!this->has_value())
1090             __throw_bad_optional_access();
1091         return _VSTD::move(this->__get());
1092     }
1094     template <class _Up>
1095     _LIBCPP_INLINE_VISIBILITY
1096     constexpr value_type value_or(_Up&& __v) const&
1097     {
1098         static_assert(is_copy_constructible_v<value_type>,
1099                       "optional<T>::value_or: T must be copy constructible");
1100         static_assert(is_convertible_v<_Up, value_type>,
1101                       "optional<T>::value_or: U must be convertible to T");
1102         return this->has_value() ? this->__get() :
1103                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
1104     }
1106     template <class _Up>
1107     _LIBCPP_INLINE_VISIBILITY
1108     constexpr value_type value_or(_Up&& __v) &&
1109     {
1110         static_assert(is_move_constructible_v<value_type>,
1111                       "optional<T>::value_or: T must be move constructible");
1112         static_assert(is_convertible_v<_Up, value_type>,
1113                       "optional<T>::value_or: U must be convertible to T");
1114         return this->has_value() ? _VSTD::move(this->__get()) :
1115                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
1116     }
1118 #if _LIBCPP_STD_VER >= 23
1119   template<class _Func>
1120   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1121   constexpr auto and_then(_Func&& __f) & {
1122     using _Up = invoke_result_t<_Func, value_type&>;
1123     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1124                   "Result of f(value()) must be a specialization of std::optional");
1125     if (*this)
1126       return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1127     return remove_cvref_t<_Up>();
1128   }
1130   template<class _Func>
1131   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1132   constexpr auto and_then(_Func&& __f) const& {
1133     using _Up = invoke_result_t<_Func, const value_type&>;
1134     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1135                   "Result of f(value()) must be a specialization of std::optional");
1136     if (*this)
1137       return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1138     return remove_cvref_t<_Up>();
1139   }
1141   template<class _Func>
1142   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1143   constexpr auto and_then(_Func&& __f) && {
1144     using _Up = invoke_result_t<_Func, value_type&&>;
1145     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1146                   "Result of f(std::move(value())) must be a specialization of std::optional");
1147     if (*this)
1148       return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1149     return remove_cvref_t<_Up>();
1150   }
1152   template<class _Func>
1153   _LIBCPP_HIDE_FROM_ABI
1154   constexpr auto and_then(_Func&& __f) const&& {
1155     using _Up = invoke_result_t<_Func, const value_type&&>;
1156     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1157                   "Result of f(std::move(value())) must be a specialization of std::optional");
1158     if (*this)
1159       return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1160     return remove_cvref_t<_Up>();
1161   }
1163   template<class _Func>
1164   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1165   constexpr auto transform(_Func&& __f) & {
1166     using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
1167     static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1168     static_assert(!is_same_v<_Up, in_place_t>,
1169                   "Result of f(value()) should not be std::in_place_t");
1170     static_assert(!is_same_v<_Up, nullopt_t>,
1171                   "Result of f(value()) should not be std::nullopt_t");
1172     static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1173     if (*this)
1174       return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1175     return optional<_Up>();
1176   }
1178   template<class _Func>
1179   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1180   constexpr auto transform(_Func&& __f) const& {
1181     using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
1182     static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1183     static_assert(!is_same_v<_Up, in_place_t>,
1184                   "Result of f(value()) should not be std::in_place_t");
1185     static_assert(!is_same_v<_Up, nullopt_t>,
1186                   "Result of f(value()) should not be std::nullopt_t");
1187     static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1188     if (*this)
1189       return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1190     return optional<_Up>();
1191   }
1193   template<class _Func>
1194   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1195   constexpr auto transform(_Func&& __f) && {
1196     using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
1197     static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1198     static_assert(!is_same_v<_Up, in_place_t>,
1199                   "Result of f(std::move(value())) should not be std::in_place_t");
1200     static_assert(!is_same_v<_Up, nullopt_t>,
1201                   "Result of f(std::move(value())) should not be std::nullopt_t");
1202     static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1203     if (*this)
1204       return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1205     return optional<_Up>();
1206   }
1208   template<class _Func>
1209   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1210   constexpr auto transform(_Func&& __f) const&& {
1211     using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
1212     static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1213     static_assert(!is_same_v<_Up, in_place_t>,
1214                   "Result of f(std::move(value())) should not be std::in_place_t");
1215     static_assert(!is_same_v<_Up, nullopt_t>,
1216                   "Result of f(std::move(value())) should not be std::nullopt_t");
1217     static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1218     if (*this)
1219       return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1220     return optional<_Up>();
1221   }
1223   template<invocable _Func>
1224   _LIBCPP_HIDE_FROM_ABI
1225   constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> {
1226     static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1227                   "Result of f() should be the same type as this optional");
1228     if (*this)
1229       return *this;
1230     return _VSTD::forward<_Func>(__f)();
1231   }
1233   template<invocable _Func>
1234   _LIBCPP_HIDE_FROM_ABI
1235   constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> {
1236     static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1237                   "Result of f() should be the same type as this optional");
1238     if (*this)
1239       return _VSTD::move(*this);
1240     return _VSTD::forward<_Func>(__f)();
1241   }
1242 #endif // _LIBCPP_STD_VER >= 23
1244     using __base::reset;
1247 #if _LIBCPP_STD_VER >= 17
1248 template<class _Tp>
1249     optional(_Tp) -> optional<_Tp>;
1250 #endif
1252 // Comparisons between optionals
1253 template <class _Tp, class _Up>
1254 _LIBCPP_INLINE_VISIBILITY constexpr
1255 enable_if_t<
1256     is_convertible_v<decltype(std::declval<const _Tp&>() ==
1257         std::declval<const _Up&>()), bool>,
1258     bool
1260 operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1262     if (static_cast<bool>(__x) != static_cast<bool>(__y))
1263         return false;
1264     if (!static_cast<bool>(__x))
1265         return true;
1266     return *__x == *__y;
1269 template <class _Tp, class _Up>
1270 _LIBCPP_INLINE_VISIBILITY constexpr
1271 enable_if_t<
1272     is_convertible_v<decltype(std::declval<const _Tp&>() !=
1273         std::declval<const _Up&>()), bool>,
1274     bool
1276 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1278     if (static_cast<bool>(__x) != static_cast<bool>(__y))
1279         return true;
1280     if (!static_cast<bool>(__x))
1281         return false;
1282     return *__x != *__y;
1285 template <class _Tp, class _Up>
1286 _LIBCPP_INLINE_VISIBILITY constexpr
1287 enable_if_t<
1288     is_convertible_v<decltype(std::declval<const _Tp&>() <
1289         std::declval<const _Up&>()), bool>,
1290     bool
1292 operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1294     if (!static_cast<bool>(__y))
1295         return false;
1296     if (!static_cast<bool>(__x))
1297         return true;
1298     return *__x < *__y;
1301 template <class _Tp, class _Up>
1302 _LIBCPP_INLINE_VISIBILITY constexpr
1303 enable_if_t<
1304     is_convertible_v<decltype(std::declval<const _Tp&>() >
1305         std::declval<const _Up&>()), bool>,
1306     bool
1308 operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1310     if (!static_cast<bool>(__x))
1311         return false;
1312     if (!static_cast<bool>(__y))
1313         return true;
1314     return *__x > *__y;
1317 template <class _Tp, class _Up>
1318 _LIBCPP_INLINE_VISIBILITY constexpr
1319 enable_if_t<
1320     is_convertible_v<decltype(std::declval<const _Tp&>() <=
1321         std::declval<const _Up&>()), bool>,
1322     bool
1324 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1326     if (!static_cast<bool>(__x))
1327         return true;
1328     if (!static_cast<bool>(__y))
1329         return false;
1330     return *__x <= *__y;
1333 template <class _Tp, class _Up>
1334 _LIBCPP_INLINE_VISIBILITY constexpr
1335 enable_if_t<
1336     is_convertible_v<decltype(std::declval<const _Tp&>() >=
1337         std::declval<const _Up&>()), bool>,
1338     bool
1340 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1342     if (!static_cast<bool>(__y))
1343         return true;
1344     if (!static_cast<bool>(__x))
1345         return false;
1346     return *__x >= *__y;
1349 #if _LIBCPP_STD_VER >= 20
1351 template <class _Tp, three_way_comparable_with<_Tp> _Up>
1352 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1353 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1354     if (__x && __y)
1355         return *__x <=> *__y;
1356     return __x.has_value() <=> __y.has_value();
1359 #endif // _LIBCPP_STD_VER >= 20
1361 // Comparisons with nullopt
1362 template <class _Tp>
1363 _LIBCPP_INLINE_VISIBILITY constexpr
1364 bool
1365 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1367     return !static_cast<bool>(__x);
1370 #if _LIBCPP_STD_VER <= 17
1372 template <class _Tp>
1373 _LIBCPP_INLINE_VISIBILITY constexpr
1374 bool
1375 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1377     return !static_cast<bool>(__x);
1380 template <class _Tp>
1381 _LIBCPP_INLINE_VISIBILITY constexpr
1382 bool
1383 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1385     return static_cast<bool>(__x);
1388 template <class _Tp>
1389 _LIBCPP_INLINE_VISIBILITY constexpr
1390 bool
1391 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1393     return static_cast<bool>(__x);
1396 template <class _Tp>
1397 _LIBCPP_INLINE_VISIBILITY constexpr
1398 bool
1399 operator<(const optional<_Tp>&, nullopt_t) noexcept
1401     return false;
1404 template <class _Tp>
1405 _LIBCPP_INLINE_VISIBILITY constexpr
1406 bool
1407 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1409     return static_cast<bool>(__x);
1412 template <class _Tp>
1413 _LIBCPP_INLINE_VISIBILITY constexpr
1414 bool
1415 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1417     return !static_cast<bool>(__x);
1420 template <class _Tp>
1421 _LIBCPP_INLINE_VISIBILITY constexpr
1422 bool
1423 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1425     return true;
1428 template <class _Tp>
1429 _LIBCPP_INLINE_VISIBILITY constexpr
1430 bool
1431 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1433     return static_cast<bool>(__x);
1436 template <class _Tp>
1437 _LIBCPP_INLINE_VISIBILITY constexpr
1438 bool
1439 operator>(nullopt_t, const optional<_Tp>&) noexcept
1441     return false;
1444 template <class _Tp>
1445 _LIBCPP_INLINE_VISIBILITY constexpr
1446 bool
1447 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1449     return true;
1452 template <class _Tp>
1453 _LIBCPP_INLINE_VISIBILITY constexpr
1454 bool
1455 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1457     return !static_cast<bool>(__x);
1460 #else // _LIBCPP_STD_VER <= 17
1462 template <class _Tp>
1463 _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
1464     return __x.has_value() <=> false;
1467 #endif // _LIBCPP_STD_VER <= 17
1469 // Comparisons with T
1470 template <class _Tp, class _Up>
1471 _LIBCPP_INLINE_VISIBILITY constexpr
1472 enable_if_t<
1473     is_convertible_v<decltype(std::declval<const _Tp&>() ==
1474         std::declval<const _Up&>()), bool>,
1475     bool
1477 operator==(const optional<_Tp>& __x, const _Up& __v)
1479     return static_cast<bool>(__x) ? *__x == __v : false;
1482 template <class _Tp, class _Up>
1483 _LIBCPP_INLINE_VISIBILITY constexpr
1484 enable_if_t<
1485     is_convertible_v<decltype(std::declval<const _Tp&>() ==
1486         std::declval<const _Up&>()), bool>,
1487     bool
1489 operator==(const _Tp& __v, const optional<_Up>& __x)
1491     return static_cast<bool>(__x) ? __v == *__x : false;
1494 template <class _Tp, class _Up>
1495 _LIBCPP_INLINE_VISIBILITY constexpr
1496 enable_if_t<
1497     is_convertible_v<decltype(std::declval<const _Tp&>() !=
1498         std::declval<const _Up&>()), bool>,
1499     bool
1501 operator!=(const optional<_Tp>& __x, const _Up& __v)
1503     return static_cast<bool>(__x) ? *__x != __v : true;
1506 template <class _Tp, class _Up>
1507 _LIBCPP_INLINE_VISIBILITY constexpr
1508 enable_if_t<
1509     is_convertible_v<decltype(std::declval<const _Tp&>() !=
1510         std::declval<const _Up&>()), bool>,
1511     bool
1513 operator!=(const _Tp& __v, const optional<_Up>& __x)
1515     return static_cast<bool>(__x) ? __v != *__x : true;
1518 template <class _Tp, class _Up>
1519 _LIBCPP_INLINE_VISIBILITY constexpr
1520 enable_if_t<
1521     is_convertible_v<decltype(std::declval<const _Tp&>() <
1522         std::declval<const _Up&>()), bool>,
1523     bool
1525 operator<(const optional<_Tp>& __x, const _Up& __v)
1527     return static_cast<bool>(__x) ? *__x < __v : true;
1530 template <class _Tp, class _Up>
1531 _LIBCPP_INLINE_VISIBILITY constexpr
1532 enable_if_t<
1533     is_convertible_v<decltype(std::declval<const _Tp&>() <
1534         std::declval<const _Up&>()), bool>,
1535     bool
1537 operator<(const _Tp& __v, const optional<_Up>& __x)
1539     return static_cast<bool>(__x) ? __v < *__x : false;
1542 template <class _Tp, class _Up>
1543 _LIBCPP_INLINE_VISIBILITY constexpr
1544 enable_if_t<
1545     is_convertible_v<decltype(std::declval<const _Tp&>() <=
1546         std::declval<const _Up&>()), bool>,
1547     bool
1549 operator<=(const optional<_Tp>& __x, const _Up& __v)
1551     return static_cast<bool>(__x) ? *__x <= __v : true;
1554 template <class _Tp, class _Up>
1555 _LIBCPP_INLINE_VISIBILITY constexpr
1556 enable_if_t<
1557     is_convertible_v<decltype(std::declval<const _Tp&>() <=
1558         std::declval<const _Up&>()), bool>,
1559     bool
1561 operator<=(const _Tp& __v, const optional<_Up>& __x)
1563     return static_cast<bool>(__x) ? __v <= *__x : false;
1566 template <class _Tp, class _Up>
1567 _LIBCPP_INLINE_VISIBILITY constexpr
1568 enable_if_t<
1569     is_convertible_v<decltype(std::declval<const _Tp&>() >
1570         std::declval<const _Up&>()), bool>,
1571     bool
1573 operator>(const optional<_Tp>& __x, const _Up& __v)
1575     return static_cast<bool>(__x) ? *__x > __v : false;
1578 template <class _Tp, class _Up>
1579 _LIBCPP_INLINE_VISIBILITY constexpr
1580 enable_if_t<
1581     is_convertible_v<decltype(std::declval<const _Tp&>() >
1582         std::declval<const _Up&>()), bool>,
1583     bool
1585 operator>(const _Tp& __v, const optional<_Up>& __x)
1587     return static_cast<bool>(__x) ? __v > *__x : true;
1590 template <class _Tp, class _Up>
1591 _LIBCPP_INLINE_VISIBILITY constexpr
1592 enable_if_t<
1593     is_convertible_v<decltype(std::declval<const _Tp&>() >=
1594         std::declval<const _Up&>()), bool>,
1595     bool
1597 operator>=(const optional<_Tp>& __x, const _Up& __v)
1599     return static_cast<bool>(__x) ? *__x >= __v : false;
1602 template <class _Tp, class _Up>
1603 _LIBCPP_INLINE_VISIBILITY constexpr
1604 enable_if_t<
1605     is_convertible_v<decltype(std::declval<const _Tp&>() >=
1606         std::declval<const _Up&>()), bool>,
1607     bool
1609 operator>=(const _Tp& __v, const optional<_Up>& __x)
1611     return static_cast<bool>(__x) ? __v >= *__x : true;
1614 #if _LIBCPP_STD_VER >= 20
1616 template <class _Tp, class _Up>
1617   requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
1618 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1619 operator<=>(const optional<_Tp>& __x, const _Up& __v) {
1620     return __x.has_value() ? *__x <=> __v : strong_ordering::less;
1623 #endif // _LIBCPP_STD_VER >= 20
1626 template <class _Tp>
1627 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1628 enable_if_t<
1629     is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1630     void
1632 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1634     __x.swap(__y);
1637 template <class _Tp>
1638 _LIBCPP_INLINE_VISIBILITY constexpr
1639 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1641     return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1644 template <class _Tp, class... _Args>
1645 _LIBCPP_INLINE_VISIBILITY constexpr
1646 optional<_Tp> make_optional(_Args&&... __args)
1648     return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1651 template <class _Tp, class _Up, class... _Args>
1652 _LIBCPP_INLINE_VISIBILITY constexpr
1653 optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1655     return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1658 template <class _Tp>
1659 struct _LIBCPP_TEMPLATE_VIS hash<
1660     __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1663 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1664     _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1665     _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t        result_type;
1666 #endif
1668     _LIBCPP_INLINE_VISIBILITY
1669     size_t operator()(const optional<_Tp>& __opt) const
1670     {
1671         return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1672     }
1675 _LIBCPP_END_NAMESPACE_STD
1677 #endif // _LIBCPP_STD_VER >= 17
1679 _LIBCPP_POP_MACROS
1681 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1682 #  include <atomic>
1683 #  include <climits>
1684 #  include <concepts>
1685 #  include <ctime>
1686 #  include <iterator>
1687 #  include <memory>
1688 #  include <ratio>
1689 #  include <stdexcept>
1690 #  include <tuple>
1691 #  include <type_traits>
1692 #  include <typeinfo>
1693 #  include <utility>
1694 #  include <variant>
1695 #endif
1697 #endif // _LIBCPP_OPTIONAL