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