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