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