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