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