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