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