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