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_copyable<_Tp>::value>
    443 struct __optional_storage;
    444 
    445 template <class _Tp>
    446 struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
    447 {
    448     using __optional_storage_base<_Tp>::__optional_storage_base;
    449 };
    450 
    451 template <class _Tp>
    452 struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
    453 {
    454     using value_type = _Tp;
    455     using __optional_storage_base<_Tp>::__optional_storage_base;
    456 
    457     _LIBCPP_INLINE_VISIBILITY
    458     __optional_storage() = default;
    459 
    460     _LIBCPP_INLINE_VISIBILITY
    461     __optional_storage(const __optional_storage& __opt)
    462     {
    463         this->__construct_from(__opt);
    464     }
    465 
    466     _LIBCPP_INLINE_VISIBILITY
    467     __optional_storage(__optional_storage&& __opt)
    468         noexcept(is_nothrow_move_constructible_v<value_type>)
    469     {
    470         this->__construct_from(_VSTD::move(__opt));
    471     }
    472 
    473     _LIBCPP_INLINE_VISIBILITY
    474     __optional_storage& operator=(const __optional_storage& __opt)
    475     {
    476         this->__assign_from(__opt);
    477         return *this;
    478     }
    479 
    480     _LIBCPP_INLINE_VISIBILITY
    481     __optional_storage& operator=(__optional_storage&& __opt)
    482         noexcept(is_nothrow_move_assignable_v<value_type> &&
    483                  is_nothrow_move_constructible_v<value_type>)
    484     {
    485         this->__assign_from(_VSTD::move(__opt));
    486         return *this;
    487     }
    488 };
    489 
    490 template <class _Tp>
    491 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
    492     is_copy_constructible<_Tp>::value,
    493     is_move_constructible<_Tp>::value
    494 >;
    495 
    496 template <class _Tp>
    497 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
    498     (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
    499     (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
    500 >;
    501 
    502 template <class _Tp>
    503 class optional
    504     : private __optional_storage<_Tp>
    505     , private __optional_sfinae_ctor_base_t<_Tp>
    506     , private __optional_sfinae_assign_base_t<_Tp>
    507 {
    508     using __base = __optional_storage<_Tp>;
    509 public:
    510     using value_type = _Tp;
    511 
    512 private:
    513      // Disable the reference extension using this static assert.
    514     static_assert(!is_same_v<value_type, in_place_t>,
    515         "instantiation of optional with in_place_t is ill-formed");
    516     static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
    517         "instantiation of optional with nullopt_t is ill-formed");
    518     static_assert(!is_reference_v<value_type>,
    519         "instantiation of optional with a reference type is ill-formed");
    520     static_assert(is_destructible_v<value_type>,
    521         "instantiation of optional with a non-destructible type is ill-formed");
    522 
    523     // LWG2756: conditionally explicit conversion from _Up
    524     struct _CheckOptionalArgsConstructor {
    525       template <class _Up>
    526       static constexpr bool __enable_implicit() {
    527           return is_constructible_v<_Tp, _Up&&> &&
    528                  is_convertible_v<_Up&&, _Tp>;
    529       }
    530 
    531       template <class _Up>
    532       static constexpr bool __enable_explicit() {
    533           return is_constructible_v<_Tp, _Up&&> &&
    534                  !is_convertible_v<_Up&&, _Tp>;
    535       }
    536     };
    537     template <class _Up>
    538     using _CheckOptionalArgsCtor = conditional_t<
    539         !is_same_v<decay_t<_Up>, in_place_t> &&
    540         !is_same_v<decay_t<_Up>, optional>,
    541         _CheckOptionalArgsConstructor,
    542         __check_tuple_constructor_fail
    543     >;
    544     template <class _QualUp>
    545     struct _CheckOptionalLikeConstructor {
    546       template <class _Up, class _Opt = optional<_Up>>
    547       using __check_constructible_from_opt = __lazy_or<
    548           is_constructible<_Tp, _Opt&>,
    549           is_constructible<_Tp, _Opt const&>,
    550           is_constructible<_Tp, _Opt&&>,
    551           is_constructible<_Tp, _Opt const&&>,
    552           is_convertible<_Opt&, _Tp>,
    553           is_convertible<_Opt const&, _Tp>,
    554           is_convertible<_Opt&&, _Tp>,
    555           is_convertible<_Opt const&&, _Tp>
    556       >;
    557       template <class _Up, class _Opt = optional<_Up>>
    558       using __check_assignable_from_opt = __lazy_or<
    559           is_assignable<_Tp&, _Opt&>,
    560           is_assignable<_Tp&, _Opt const&>,
    561           is_assignable<_Tp&, _Opt&&>,
    562           is_assignable<_Tp&, _Opt const&&>
    563       >;
    564       template <class _Up, class _QUp = _QualUp>
    565       static constexpr bool __enable_implicit() {
    566           return is_convertible<_QUp, _Tp>::value &&
    567               !__check_constructible_from_opt<_Up>::value;
    568       }
    569       template <class _Up, class _QUp = _QualUp>
    570       static constexpr bool __enable_explicit() {
    571           return !is_convertible<_QUp, _Tp>::value &&
    572               !__check_constructible_from_opt<_Up>::value;
    573       }
    574       template <class _Up, class _QUp = _QualUp>
    575       static constexpr bool __enable_assign() {
    576           // Construction and assignability of _Qup to _Tp has already been
    577           // checked.
    578           return !__check_constructible_from_opt<_Up>::value &&
    579               !__check_assignable_from_opt<_Up>::value;
    580       }
    581     };
    582 
    583     template <class _Up, class _QualUp>
    584     using _CheckOptionalLikeCtor = conditional_t<
    585       __lazy_and<
    586           __lazy_not<is_same<_Up, _Tp>>,
    587           is_constructible<_Tp, _QualUp>
    588       >::value,
    589       _CheckOptionalLikeConstructor<_QualUp>,
    590       __check_tuple_constructor_fail
    591     >;
    592     template <class _Up, class _QualUp>
    593     using _CheckOptionalLikeAssign = conditional_t<
    594       __lazy_and<
    595           __lazy_not<is_same<_Up, _Tp>>,
    596           is_constructible<_Tp, _QualUp>,
    597           is_assignable<_Tp&, _QualUp>
    598       >::value,
    599       _CheckOptionalLikeConstructor<_QualUp>,
    600       __check_tuple_constructor_fail
    601     >;
    602 public:
    603 
    604     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
    605     _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
    606     _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
    607     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
    608 
    609     template <class... _Args, class = enable_if_t<
    610         is_constructible_v<value_type, _Args...>>
    611     >
    612     _LIBCPP_INLINE_VISIBILITY
    613     constexpr explicit optional(in_place_t, _Args&&... __args)
    614         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
    615 
    616     template <class _Up, class... _Args, class = enable_if_t<
    617         is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
    618     >
    619     _LIBCPP_INLINE_VISIBILITY
    620     constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
    621         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
    622 
    623     template <class _Up = value_type, enable_if_t<
    624         _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
    625     , int> = 0>
    626     _LIBCPP_INLINE_VISIBILITY
    627     constexpr optional(_Up&& __v)
    628         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
    629 
    630     template <class _Up, enable_if_t<
    631         _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
    632     , int> = 0>
    633     _LIBCPP_INLINE_VISIBILITY
    634     constexpr explicit optional(_Up&& __v)
    635         : __base(in_place, _VSTD::forward<_Up>(__v)) {}
    636 
    637     // LWG2756: conditionally explicit conversion from const optional<_Up>&
    638     template <class _Up, enable_if_t<
    639         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
    640     , int> = 0>
    641     _LIBCPP_INLINE_VISIBILITY
    642     optional(const optional<_Up>& __v)
    643     {
    644         this->__construct_from(__v);
    645     }
    646     template <class _Up, enable_if_t<
    647         _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
    648     , int> = 0>
    649     _LIBCPP_INLINE_VISIBILITY
    650     explicit optional(const optional<_Up>& __v)
    651     {
    652         this->__construct_from(__v);
    653     }
    654 
    655     // LWG2756: conditionally explicit conversion from optional<_Up>&&
    656     template <class _Up, enable_if_t<
    657         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
    658     , int> = 0>
    659     _LIBCPP_INLINE_VISIBILITY
    660     optional(optional<_Up>&& __v)
    661     {
    662         this->__construct_from(_VSTD::move(__v));
    663     }
    664     template <class _Up, enable_if_t<
    665         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
    666     , int> = 0>
    667     _LIBCPP_INLINE_VISIBILITY
    668     explicit optional(optional<_Up>&& __v)
    669     {
    670         this->__construct_from(_VSTD::move(__v));
    671     }
    672 
    673     _LIBCPP_INLINE_VISIBILITY
    674     optional& operator=(nullopt_t) noexcept
    675     {
    676         reset();
    677         return *this;
    678     }
    679 
    680     _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
    681     _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
    682 
    683     // LWG2756
    684     template <class _Up = value_type,
    685               class = enable_if_t
    686                       <__lazy_and<
    687                           integral_constant<bool,
    688                               !is_same_v<decay_t<_Up>, optional> &&
    689                               !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
    690                           >,
    691                           is_constructible<value_type, _Up>,
    692                           is_assignable<value_type&, _Up>
    693                       >::value>
    694              >
    695     _LIBCPP_INLINE_VISIBILITY
    696     optional&
    697     operator=(_Up&& __v)
    698     {
    699         if (this->has_value())
    700             this->__get() = _VSTD::forward<_Up>(__v);
    701         else
    702             this->__construct(_VSTD::forward<_Up>(__v));
    703         return *this;
    704     }
    705 
    706     // LWG2756
    707     template <class _Up, enable_if_t<
    708         _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
    709     , int> = 0>
    710     _LIBCPP_INLINE_VISIBILITY
    711     optional&
    712     operator=(const optional<_Up>& __v)
    713     {
    714         this->__assign_from(__v);
    715         return *this;
    716     }
    717 
    718     // LWG2756
    719     template <class _Up, enable_if_t<
    720         _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
    721     , int> = 0>
    722     _LIBCPP_INLINE_VISIBILITY
    723     optional&
    724     operator=(optional<_Up>&& __v)
    725     {
    726         this->__assign_from(_VSTD::move(__v));
    727         return *this;
    728     }
    729 
    730     template <class... _Args,
    731               class = enable_if_t
    732                       <
    733                           is_constructible_v<value_type, _Args...>
    734                       >
    735              >
    736     _LIBCPP_INLINE_VISIBILITY
    737     _Tp &
    738     emplace(_Args&&... __args)
    739     {
    740         reset();
    741         this->__construct(_VSTD::forward<_Args>(__args)...);
    742         return this->__get();
    743     }
    744 
    745     template <class _Up, class... _Args,
    746               class = enable_if_t
    747                       <
    748                           is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
    749                       >
    750              >
    751     _LIBCPP_INLINE_VISIBILITY
    752     _Tp &
    753     emplace(initializer_list<_Up> __il, _Args&&... __args)
    754     {
    755         reset();
    756         this->__construct(__il, _VSTD::forward<_Args>(__args)...);
    757         return this->__get();
    758     }
    759 
    760     _LIBCPP_INLINE_VISIBILITY
    761     void swap(optional& __opt)
    762         noexcept(is_nothrow_move_constructible_v<value_type> &&
    763                  is_nothrow_swappable_v<value_type>)
    764     {
    765         if (this->has_value() == __opt.has_value())
    766         {
    767             using _VSTD::swap;
    768             if (this->has_value())
    769                 swap(this->__get(), __opt.__get());
    770         }
    771         else
    772         {
    773             if (this->has_value())
    774             {
    775                 __opt.__construct(_VSTD::move(this->__get()));
    776                 reset();
    777             }
    778             else
    779             {
    780                 this->__construct(_VSTD::move(__opt.__get()));
    781                 __opt.reset();
    782             }
    783         }
    784     }
    785 
    786     _LIBCPP_INLINE_VISIBILITY
    787     constexpr
    788     add_pointer_t<value_type const>
    789     operator->() const
    790     {
    791         _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
    792 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
    793         return _VSTD::addressof(this->__get());
    794 #else
    795         return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
    796 #endif
    797     }
    798 
    799     _LIBCPP_INLINE_VISIBILITY
    800     constexpr
    801     add_pointer_t<value_type>
    802     operator->()
    803     {
    804         _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
    805 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
    806         return _VSTD::addressof(this->__get());
    807 #else
    808         return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
    809 #endif
    810     }
    811 
    812     _LIBCPP_INLINE_VISIBILITY
    813     constexpr
    814     const value_type&
    815     operator*() const&
    816     {
    817         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
    818         return this->__get();
    819     }
    820 
    821     _LIBCPP_INLINE_VISIBILITY
    822     constexpr
    823     value_type&
    824     operator*() &
    825     {
    826         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
    827         return this->__get();
    828     }
    829 
    830     _LIBCPP_INLINE_VISIBILITY
    831     constexpr
    832     value_type&&
    833     operator*() &&
    834     {
    835         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
    836         return _VSTD::move(this->__get());
    837     }
    838 
    839     _LIBCPP_INLINE_VISIBILITY
    840     constexpr
    841     const value_type&&
    842     operator*() const&&
    843     {
    844         _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
    845         return _VSTD::move(this->__get());
    846     }
    847 
    848     _LIBCPP_INLINE_VISIBILITY
    849     constexpr explicit operator bool() const noexcept { return has_value(); }
    850 
    851     using __base::has_value;
    852     using __base::__get;
    853 
    854     _LIBCPP_INLINE_VISIBILITY
    855     constexpr value_type const& value() const&
    856     {
    857         if (!this->has_value())
    858             __throw_bad_optional_access();
    859         return this->__get();
    860     }
    861 
    862     _LIBCPP_INLINE_VISIBILITY
    863     constexpr value_type& value() &
    864     {
    865         if (!this->has_value())
    866             __throw_bad_optional_access();
    867         return this->__get();
    868     }
    869 
    870     _LIBCPP_INLINE_VISIBILITY
    871     constexpr value_type&& value() &&
    872     {
    873         if (!this->has_value())
    874             __throw_bad_optional_access();
    875         return _VSTD::move(this->__get());
    876     }
    877 
    878     _LIBCPP_INLINE_VISIBILITY
    879     constexpr value_type const&& value() const&&
    880     {
    881         if (!this->has_value())
    882             __throw_bad_optional_access();
    883         return _VSTD::move(this->__get());
    884     }
    885 
    886     template <class _Up>
    887     _LIBCPP_INLINE_VISIBILITY
    888     constexpr value_type value_or(_Up&& __v) const&
    889     {
    890         static_assert(is_copy_constructible_v<value_type>,
    891                       "optional<T>::value_or: T must be copy constructible");
    892         static_assert(is_convertible_v<_Up, value_type>,
    893                       "optional<T>::value_or: U must be convertible to T");
    894         return this->has_value() ? this->__get() :
    895                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
    896     }
    897 
    898     template <class _Up>
    899     _LIBCPP_INLINE_VISIBILITY
    900     constexpr value_type value_or(_Up&& __v) &&
    901     {
    902         static_assert(is_move_constructible_v<value_type>,
    903                       "optional<T>::value_or: T must be move constructible");
    904         static_assert(is_convertible_v<_Up, value_type>,
    905                       "optional<T>::value_or: U must be convertible to T");
    906         return this->has_value() ? _VSTD::move(this->__get()) :
    907                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
    908     }
    909 
    910     using __base::reset;
    911 
    912 private:
    913     template <class _Up>
    914     _LIBCPP_INLINE_VISIBILITY
    915     static _Up*
    916     __operator_arrow(true_type, _Up& __x)
    917     {
    918         return _VSTD::addressof(__x);
    919     }
    920 
    921     template <class _Up>
    922     _LIBCPP_INLINE_VISIBILITY
    923     static constexpr _Up*
    924     __operator_arrow(false_type, _Up& __x)
    925     {
    926         return &__x;
    927     }
    928 };
    929 
    930 // Comparisons between optionals
    931 template <class _Tp, class _Up>
    932 _LIBCPP_INLINE_VISIBILITY constexpr
    933 enable_if_t<
    934     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
    935         _VSTD::declval<const _Up&>()), bool>,
    936     bool
    937 >
    938 operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
    939 {
    940     if (static_cast<bool>(__x) != static_cast<bool>(__y))
    941         return false;
    942     if (!static_cast<bool>(__x))
    943         return true;
    944     return *__x == *__y;
    945 }
    946 
    947 template <class _Tp, class _Up>
    948 _LIBCPP_INLINE_VISIBILITY constexpr
    949 enable_if_t<
    950     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
    951         _VSTD::declval<const _Up&>()), bool>,
    952     bool
    953 >
    954 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
    955 {
    956     if (static_cast<bool>(__x) != static_cast<bool>(__y))
    957         return true;
    958     if (!static_cast<bool>(__x))
    959         return false;
    960     return *__x != *__y;
    961 }
    962 
    963 template <class _Tp, class _Up>
    964 _LIBCPP_INLINE_VISIBILITY constexpr
    965 enable_if_t<
    966     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
    967         _VSTD::declval<const _Up&>()), bool>,
    968     bool
    969 >
    970 operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
    971 {
    972     if (!static_cast<bool>(__y))
    973         return false;
    974     if (!static_cast<bool>(__x))
    975         return true;
    976     return *__x < *__y;
    977 }
    978 
    979 template <class _Tp, class _Up>
    980 _LIBCPP_INLINE_VISIBILITY constexpr
    981 enable_if_t<
    982     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
    983         _VSTD::declval<const _Up&>()), bool>,
    984     bool
    985 >
    986 operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
    987 {
    988     if (!static_cast<bool>(__x))
    989         return false;
    990     if (!static_cast<bool>(__y))
    991         return true;
    992     return *__x > *__y;
    993 }
    994 
    995 template <class _Tp, class _Up>
    996 _LIBCPP_INLINE_VISIBILITY constexpr
    997 enable_if_t<
    998     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
    999         _VSTD::declval<const _Up&>()), bool>,
   1000     bool
   1001 >
   1002 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
   1003 {
   1004     if (!static_cast<bool>(__x))
   1005         return true;
   1006     if (!static_cast<bool>(__y))
   1007         return false;
   1008     return *__x <= *__y;
   1009 }
   1010 
   1011 template <class _Tp, class _Up>
   1012 _LIBCPP_INLINE_VISIBILITY constexpr
   1013 enable_if_t<
   1014     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
   1015         _VSTD::declval<const _Up&>()), bool>,
   1016     bool
   1017 >
   1018 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
   1019 {
   1020     if (!static_cast<bool>(__y))
   1021         return true;
   1022     if (!static_cast<bool>(__x))
   1023         return false;
   1024     return *__x >= *__y;
   1025 }
   1026 
   1027 // Comparisons with nullopt
   1028 template <class _Tp>
   1029 _LIBCPP_INLINE_VISIBILITY constexpr
   1030 bool
   1031 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
   1032 {
   1033     return !static_cast<bool>(__x);
   1034 }
   1035 
   1036 template <class _Tp>
   1037 _LIBCPP_INLINE_VISIBILITY constexpr
   1038 bool
   1039 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
   1040 {
   1041     return !static_cast<bool>(__x);
   1042 }
   1043 
   1044 template <class _Tp>
   1045 _LIBCPP_INLINE_VISIBILITY constexpr
   1046 bool
   1047 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
   1048 {
   1049     return static_cast<bool>(__x);
   1050 }
   1051 
   1052 template <class _Tp>
   1053 _LIBCPP_INLINE_VISIBILITY constexpr
   1054 bool
   1055 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
   1056 {
   1057     return static_cast<bool>(__x);
   1058 }
   1059 
   1060 template <class _Tp>
   1061 _LIBCPP_INLINE_VISIBILITY constexpr
   1062 bool
   1063 operator<(const optional<_Tp>&, nullopt_t) noexcept
   1064 {
   1065     return false;
   1066 }
   1067 
   1068 template <class _Tp>
   1069 _LIBCPP_INLINE_VISIBILITY constexpr
   1070 bool
   1071 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
   1072 {
   1073     return static_cast<bool>(__x);
   1074 }
   1075 
   1076 template <class _Tp>
   1077 _LIBCPP_INLINE_VISIBILITY constexpr
   1078 bool
   1079 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
   1080 {
   1081     return !static_cast<bool>(__x);
   1082 }
   1083 
   1084 template <class _Tp>
   1085 _LIBCPP_INLINE_VISIBILITY constexpr
   1086 bool
   1087 operator<=(nullopt_t, const optional<_Tp>&) noexcept
   1088 {
   1089     return true;
   1090 }
   1091 
   1092 template <class _Tp>
   1093 _LIBCPP_INLINE_VISIBILITY constexpr
   1094 bool
   1095 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
   1096 {
   1097     return static_cast<bool>(__x);
   1098 }
   1099 
   1100 template <class _Tp>
   1101 _LIBCPP_INLINE_VISIBILITY constexpr
   1102 bool
   1103 operator>(nullopt_t, const optional<_Tp>&) noexcept
   1104 {
   1105     return false;
   1106 }
   1107 
   1108 template <class _Tp>
   1109 _LIBCPP_INLINE_VISIBILITY constexpr
   1110 bool
   1111 operator>=(const optional<_Tp>&, nullopt_t) noexcept
   1112 {
   1113     return true;
   1114 }
   1115 
   1116 template <class _Tp>
   1117 _LIBCPP_INLINE_VISIBILITY constexpr
   1118 bool
   1119 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
   1120 {
   1121     return !static_cast<bool>(__x);
   1122 }
   1123 
   1124 // Comparisons with T
   1125 template <class _Tp, class _Up>
   1126 _LIBCPP_INLINE_VISIBILITY constexpr
   1127 enable_if_t<
   1128     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
   1129         _VSTD::declval<const _Up&>()), bool>,
   1130     bool
   1131 >
   1132 operator==(const optional<_Tp>& __x, const _Up& __v)
   1133 {
   1134     return static_cast<bool>(__x) ? *__x == __v : false;
   1135 }
   1136 
   1137 template <class _Tp, class _Up>
   1138 _LIBCPP_INLINE_VISIBILITY constexpr
   1139 enable_if_t<
   1140     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
   1141         _VSTD::declval<const _Up&>()), bool>,
   1142     bool
   1143 >
   1144 operator==(const _Tp& __v, const optional<_Up>& __x)
   1145 {
   1146     return static_cast<bool>(__x) ? __v == *__x : false;
   1147 }
   1148 
   1149 template <class _Tp, class _Up>
   1150 _LIBCPP_INLINE_VISIBILITY constexpr
   1151 enable_if_t<
   1152     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
   1153         _VSTD::declval<const _Up&>()), bool>,
   1154     bool
   1155 >
   1156 operator!=(const optional<_Tp>& __x, const _Up& __v)
   1157 {
   1158     return static_cast<bool>(__x) ? *__x != __v : true;
   1159 }
   1160 
   1161 template <class _Tp, class _Up>
   1162 _LIBCPP_INLINE_VISIBILITY constexpr
   1163 enable_if_t<
   1164     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
   1165         _VSTD::declval<const _Up&>()), bool>,
   1166     bool
   1167 >
   1168 operator!=(const _Tp& __v, const optional<_Up>& __x)
   1169 {
   1170     return static_cast<bool>(__x) ? __v != *__x : true;
   1171 }
   1172 
   1173 template <class _Tp, class _Up>
   1174 _LIBCPP_INLINE_VISIBILITY constexpr
   1175 enable_if_t<
   1176     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
   1177         _VSTD::declval<const _Up&>()), bool>,
   1178     bool
   1179 >
   1180 operator<(const optional<_Tp>& __x, const _Up& __v)
   1181 {
   1182     return static_cast<bool>(__x) ? *__x < __v : true;
   1183 }
   1184 
   1185 template <class _Tp, class _Up>
   1186 _LIBCPP_INLINE_VISIBILITY constexpr
   1187 enable_if_t<
   1188     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
   1189         _VSTD::declval<const _Up&>()), bool>,
   1190     bool
   1191 >
   1192 operator<(const _Tp& __v, const optional<_Up>& __x)
   1193 {
   1194     return static_cast<bool>(__x) ? __v < *__x : false;
   1195 }
   1196 
   1197 template <class _Tp, class _Up>
   1198 _LIBCPP_INLINE_VISIBILITY constexpr
   1199 enable_if_t<
   1200     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
   1201         _VSTD::declval<const _Up&>()), bool>,
   1202     bool
   1203 >
   1204 operator<=(const optional<_Tp>& __x, const _Up& __v)
   1205 {
   1206     return static_cast<bool>(__x) ? *__x <= __v : true;
   1207 }
   1208 
   1209 template <class _Tp, class _Up>
   1210 _LIBCPP_INLINE_VISIBILITY constexpr
   1211 enable_if_t<
   1212     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
   1213         _VSTD::declval<const _Up&>()), bool>,
   1214     bool
   1215 >
   1216 operator<=(const _Tp& __v, const optional<_Up>& __x)
   1217 {
   1218     return static_cast<bool>(__x) ? __v <= *__x : false;
   1219 }
   1220 
   1221 template <class _Tp, class _Up>
   1222 _LIBCPP_INLINE_VISIBILITY constexpr
   1223 enable_if_t<
   1224     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
   1225         _VSTD::declval<const _Up&>()), bool>,
   1226     bool
   1227 >
   1228 operator>(const optional<_Tp>& __x, const _Up& __v)
   1229 {
   1230     return static_cast<bool>(__x) ? *__x > __v : false;
   1231 }
   1232 
   1233 template <class _Tp, class _Up>
   1234 _LIBCPP_INLINE_VISIBILITY constexpr
   1235 enable_if_t<
   1236     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
   1237         _VSTD::declval<const _Up&>()), bool>,
   1238     bool
   1239 >
   1240 operator>(const _Tp& __v, const optional<_Up>& __x)
   1241 {
   1242     return static_cast<bool>(__x) ? __v > *__x : true;
   1243 }
   1244 
   1245 template <class _Tp, class _Up>
   1246 _LIBCPP_INLINE_VISIBILITY constexpr
   1247 enable_if_t<
   1248     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
   1249         _VSTD::declval<const _Up&>()), bool>,
   1250     bool
   1251 >
   1252 operator>=(const optional<_Tp>& __x, const _Up& __v)
   1253 {
   1254     return static_cast<bool>(__x) ? *__x >= __v : false;
   1255 }
   1256 
   1257 template <class _Tp, class _Up>
   1258 _LIBCPP_INLINE_VISIBILITY constexpr
   1259 enable_if_t<
   1260     is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
   1261         _VSTD::declval<const _Up&>()), bool>,
   1262     bool
   1263 >
   1264 operator>=(const _Tp& __v, const optional<_Up>& __x)
   1265 {
   1266     return static_cast<bool>(__x) ? __v >= *__x : true;
   1267 }
   1268 
   1269 
   1270 template <class _Tp>
   1271 inline _LIBCPP_INLINE_VISIBILITY
   1272 enable_if_t<
   1273     is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
   1274     void
   1275 >
   1276 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
   1277 {
   1278     __x.swap(__y);
   1279 }
   1280 
   1281 template <class _Tp>
   1282 _LIBCPP_INLINE_VISIBILITY constexpr
   1283 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
   1284 {
   1285     return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
   1286 }
   1287 
   1288 template <class _Tp, class... _Args>
   1289 _LIBCPP_INLINE_VISIBILITY constexpr
   1290 optional<_Tp> make_optional(_Args&&... __args)
   1291 {
   1292     return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
   1293 }
   1294 
   1295 template <class _Tp, class _Up, class... _Args>
   1296 _LIBCPP_INLINE_VISIBILITY constexpr
   1297 optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
   1298 {
   1299     return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
   1300 }
   1301 
   1302 template <class _Tp>
   1303 struct _LIBCPP_TEMPLATE_VIS hash<
   1304     __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
   1305 >
   1306 {
   1307     typedef optional<_Tp> argument_type;
   1308     typedef size_t        result_type;
   1309 
   1310     _LIBCPP_INLINE_VISIBILITY
   1311     result_type operator()(const argument_type& __opt) const
   1312     {
   1313         return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
   1314     }
   1315 };
   1316 
   1317 _LIBCPP_END_NAMESPACE_STD
   1318 
   1319 #endif  // _LIBCPP_STD_VER > 14
   1320 
   1321 _LIBCPP_POP_MACROS
   1322 
   1323 #endif  // _LIBCPP_OPTIONAL
   1324