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