• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &);                // constexpr in C++20
109    optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
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#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<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
605    // LWG2756: conditionally explicit conversion from _Up
606    struct _CheckOptionalArgsConstructor {
607      template <class _Up>
608      static constexpr bool __enable_implicit() {
609          return is_constructible_v<_Tp, _Up&&> &&
610                 is_convertible_v<_Up&&, _Tp>;
611      }
612
613      template <class _Up>
614      static constexpr bool __enable_explicit() {
615          return is_constructible_v<_Tp, _Up&&> &&
616                 !is_convertible_v<_Up&&, _Tp>;
617      }
618    };
619    template <class _Up>
620    using _CheckOptionalArgsCtor = conditional_t<
621        !is_same_v<__uncvref_t<_Up>, in_place_t> &&
622        !is_same_v<__uncvref_t<_Up>, optional>,
623        _CheckOptionalArgsConstructor,
624        __check_tuple_constructor_fail
625    >;
626    template <class _QualUp>
627    struct _CheckOptionalLikeConstructor {
628      template <class _Up, class _Opt = optional<_Up>>
629      using __check_constructible_from_opt = __lazy_or<
630          is_constructible<_Tp, _Opt&>,
631          is_constructible<_Tp, _Opt const&>,
632          is_constructible<_Tp, _Opt&&>,
633          is_constructible<_Tp, _Opt const&&>,
634          is_convertible<_Opt&, _Tp>,
635          is_convertible<_Opt const&, _Tp>,
636          is_convertible<_Opt&&, _Tp>,
637          is_convertible<_Opt const&&, _Tp>
638      >;
639      template <class _Up, class _Opt = optional<_Up>>
640      using __check_assignable_from_opt = __lazy_or<
641          is_assignable<_Tp&, _Opt&>,
642          is_assignable<_Tp&, _Opt const&>,
643          is_assignable<_Tp&, _Opt&&>,
644          is_assignable<_Tp&, _Opt const&&>
645      >;
646      template <class _Up, class _QUp = _QualUp>
647      static constexpr bool __enable_implicit() {
648          return is_convertible<_QUp, _Tp>::value &&
649              !__check_constructible_from_opt<_Up>::value;
650      }
651      template <class _Up, class _QUp = _QualUp>
652      static constexpr bool __enable_explicit() {
653          return !is_convertible<_QUp, _Tp>::value &&
654              !__check_constructible_from_opt<_Up>::value;
655      }
656      template <class _Up, class _QUp = _QualUp>
657      static constexpr bool __enable_assign() {
658          // Construction and assignability of _Qup to _Tp has already been
659          // checked.
660          return !__check_constructible_from_opt<_Up>::value &&
661              !__check_assignable_from_opt<_Up>::value;
662      }
663    };
664
665    template <class _Up, class _QualUp>
666    using _CheckOptionalLikeCtor = conditional_t<
667      __lazy_and<
668          __lazy_not<is_same<_Up, _Tp>>,
669          is_constructible<_Tp, _QualUp>
670      >::value,
671      _CheckOptionalLikeConstructor<_QualUp>,
672      __check_tuple_constructor_fail
673    >;
674    template <class _Up, class _QualUp>
675    using _CheckOptionalLikeAssign = conditional_t<
676      __lazy_and<
677          __lazy_not<is_same<_Up, _Tp>>,
678          is_constructible<_Tp, _QualUp>,
679          is_assignable<_Tp&, _QualUp>
680      >::value,
681      _CheckOptionalLikeConstructor<_QualUp>,
682      __check_tuple_constructor_fail
683    >;
684public:
685
686    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
687    _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
688    _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
689    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
690
691    template <class... _Args, class = enable_if_t<
692        is_constructible_v<value_type, _Args...>>
693    >
694    _LIBCPP_INLINE_VISIBILITY
695    constexpr explicit optional(in_place_t, _Args&&... __args)
696        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
697
698    template <class _Up, class... _Args, class = enable_if_t<
699        is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
700    >
701    _LIBCPP_INLINE_VISIBILITY
702    constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
703        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
704
705    template <class _Up = value_type, enable_if_t<
706        _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
707    , int> = 0>
708    _LIBCPP_INLINE_VISIBILITY
709    constexpr optional(_Up&& __v)
710        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
711
712    template <class _Up, enable_if_t<
713        _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
714    , int> = 0>
715    _LIBCPP_INLINE_VISIBILITY
716    constexpr explicit optional(_Up&& __v)
717        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
718
719    // LWG2756: conditionally explicit conversion from const optional<_Up>&
720    template <class _Up, enable_if_t<
721        _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
722    , int> = 0>
723    _LIBCPP_INLINE_VISIBILITY
724    optional(const optional<_Up>& __v)
725    {
726        this->__construct_from(__v);
727    }
728    template <class _Up, enable_if_t<
729        _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
730    , int> = 0>
731    _LIBCPP_INLINE_VISIBILITY
732    explicit optional(const optional<_Up>& __v)
733    {
734        this->__construct_from(__v);
735    }
736
737    // LWG2756: conditionally explicit conversion from optional<_Up>&&
738    template <class _Up, enable_if_t<
739        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
740    , int> = 0>
741    _LIBCPP_INLINE_VISIBILITY
742    optional(optional<_Up>&& __v)
743    {
744        this->__construct_from(_VSTD::move(__v));
745    }
746    template <class _Up, enable_if_t<
747        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
748    , int> = 0>
749    _LIBCPP_INLINE_VISIBILITY
750    explicit optional(optional<_Up>&& __v)
751    {
752        this->__construct_from(_VSTD::move(__v));
753    }
754
755    _LIBCPP_INLINE_VISIBILITY
756    optional& operator=(nullopt_t) noexcept
757    {
758        reset();
759        return *this;
760    }
761
762    _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
763    _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
764
765    // LWG2756
766    template <class _Up = value_type,
767              class = enable_if_t
768                      <__lazy_and<
769                          integral_constant<bool,
770                              !is_same_v<__uncvref_t<_Up>, optional> &&
771                              !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
772                          >,
773                          is_constructible<value_type, _Up>,
774                          is_assignable<value_type&, _Up>
775                      >::value>
776             >
777    _LIBCPP_INLINE_VISIBILITY
778    optional&
779    operator=(_Up&& __v)
780    {
781        if (this->has_value())
782            this->__get() = _VSTD::forward<_Up>(__v);
783        else
784            this->__construct(_VSTD::forward<_Up>(__v));
785        return *this;
786    }
787
788    // LWG2756
789    template <class _Up, enable_if_t<
790        _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
791    , int> = 0>
792    _LIBCPP_INLINE_VISIBILITY
793    optional&
794    operator=(const optional<_Up>& __v)
795    {
796        this->__assign_from(__v);
797        return *this;
798    }
799
800    // LWG2756
801    template <class _Up, enable_if_t<
802        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
803    , int> = 0>
804    _LIBCPP_INLINE_VISIBILITY
805    optional&
806    operator=(optional<_Up>&& __v)
807    {
808        this->__assign_from(_VSTD::move(__v));
809        return *this;
810    }
811
812    template <class... _Args,
813              class = enable_if_t
814                      <
815                          is_constructible_v<value_type, _Args...>
816                      >
817             >
818    _LIBCPP_INLINE_VISIBILITY
819    _Tp &
820    emplace(_Args&&... __args)
821    {
822        reset();
823        this->__construct(_VSTD::forward<_Args>(__args)...);
824        return this->__get();
825    }
826
827    template <class _Up, class... _Args,
828              class = enable_if_t
829                      <
830                          is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
831                      >
832             >
833    _LIBCPP_INLINE_VISIBILITY
834    _Tp &
835    emplace(initializer_list<_Up> __il, _Args&&... __args)
836    {
837        reset();
838        this->__construct(__il, _VSTD::forward<_Args>(__args)...);
839        return this->__get();
840    }
841
842    _LIBCPP_INLINE_VISIBILITY
843    void swap(optional& __opt)
844        noexcept(is_nothrow_move_constructible_v<value_type> &&
845                 is_nothrow_swappable_v<value_type>)
846    {
847        if (this->has_value() == __opt.has_value())
848        {
849            using _VSTD::swap;
850            if (this->has_value())
851                swap(this->__get(), __opt.__get());
852        }
853        else
854        {
855            if (this->has_value())
856            {
857                __opt.__construct(_VSTD::move(this->__get()));
858                reset();
859            }
860            else
861            {
862                this->__construct(_VSTD::move(__opt.__get()));
863                __opt.reset();
864            }
865        }
866    }
867
868    _LIBCPP_INLINE_VISIBILITY
869    constexpr
870    add_pointer_t<value_type const>
871    operator->() const
872    {
873        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
874#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
875        return _VSTD::addressof(this->__get());
876#else
877        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
878#endif
879    }
880
881    _LIBCPP_INLINE_VISIBILITY
882    constexpr
883    add_pointer_t<value_type>
884    operator->()
885    {
886        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
887#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
888        return _VSTD::addressof(this->__get());
889#else
890        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
891#endif
892    }
893
894    _LIBCPP_INLINE_VISIBILITY
895    constexpr
896    const value_type&
897    operator*() const&
898    {
899        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
900        return this->__get();
901    }
902
903    _LIBCPP_INLINE_VISIBILITY
904    constexpr
905    value_type&
906    operator*() &
907    {
908        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
909        return this->__get();
910    }
911
912    _LIBCPP_INLINE_VISIBILITY
913    constexpr
914    value_type&&
915    operator*() &&
916    {
917        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
918        return _VSTD::move(this->__get());
919    }
920
921    _LIBCPP_INLINE_VISIBILITY
922    constexpr
923    const value_type&&
924    operator*() const&&
925    {
926        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
927        return _VSTD::move(this->__get());
928    }
929
930    _LIBCPP_INLINE_VISIBILITY
931    constexpr explicit operator bool() const noexcept { return has_value(); }
932
933    using __base::has_value;
934    using __base::__get;
935
936    _LIBCPP_INLINE_VISIBILITY
937    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
938    constexpr value_type const& value() const&
939    {
940        if (!this->has_value())
941            __throw_bad_optional_access();
942        return this->__get();
943    }
944
945    _LIBCPP_INLINE_VISIBILITY
946    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
947    constexpr value_type& value() &
948    {
949        if (!this->has_value())
950            __throw_bad_optional_access();
951        return this->__get();
952    }
953
954    _LIBCPP_INLINE_VISIBILITY
955    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
956    constexpr value_type&& value() &&
957    {
958        if (!this->has_value())
959            __throw_bad_optional_access();
960        return _VSTD::move(this->__get());
961    }
962
963    _LIBCPP_INLINE_VISIBILITY
964    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
965    constexpr value_type const&& value() const&&
966    {
967        if (!this->has_value())
968            __throw_bad_optional_access();
969        return _VSTD::move(this->__get());
970    }
971
972    template <class _Up>
973    _LIBCPP_INLINE_VISIBILITY
974    constexpr value_type value_or(_Up&& __v) const&
975    {
976        static_assert(is_copy_constructible_v<value_type>,
977                      "optional<T>::value_or: T must be copy constructible");
978        static_assert(is_convertible_v<_Up, value_type>,
979                      "optional<T>::value_or: U must be convertible to T");
980        return this->has_value() ? this->__get() :
981                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
982    }
983
984    template <class _Up>
985    _LIBCPP_INLINE_VISIBILITY
986    constexpr value_type value_or(_Up&& __v) &&
987    {
988        static_assert(is_move_constructible_v<value_type>,
989                      "optional<T>::value_or: T must be move constructible");
990        static_assert(is_convertible_v<_Up, value_type>,
991                      "optional<T>::value_or: U must be convertible to T");
992        return this->has_value() ? _VSTD::move(this->__get()) :
993                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
994    }
995
996    using __base::reset;
997
998private:
999    template <class _Up>
1000    _LIBCPP_INLINE_VISIBILITY
1001    static _Up*
1002    __operator_arrow(true_type, _Up& __x)
1003    {
1004        return _VSTD::addressof(__x);
1005    }
1006
1007    template <class _Up>
1008    _LIBCPP_INLINE_VISIBILITY
1009    static constexpr _Up*
1010    __operator_arrow(false_type, _Up& __x)
1011    {
1012        return &__x;
1013    }
1014};
1015
1016#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1017template<class T>
1018    optional(T) -> optional<T>;
1019#endif
1020
1021// Comparisons between optionals
1022template <class _Tp, class _Up>
1023_LIBCPP_INLINE_VISIBILITY constexpr
1024enable_if_t<
1025    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1026        _VSTD::declval<const _Up&>()), bool>,
1027    bool
1028>
1029operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1030{
1031    if (static_cast<bool>(__x) != static_cast<bool>(__y))
1032        return false;
1033    if (!static_cast<bool>(__x))
1034        return true;
1035    return *__x == *__y;
1036}
1037
1038template <class _Tp, class _Up>
1039_LIBCPP_INLINE_VISIBILITY constexpr
1040enable_if_t<
1041    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1042        _VSTD::declval<const _Up&>()), bool>,
1043    bool
1044>
1045operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1046{
1047    if (static_cast<bool>(__x) != static_cast<bool>(__y))
1048        return true;
1049    if (!static_cast<bool>(__x))
1050        return false;
1051    return *__x != *__y;
1052}
1053
1054template <class _Tp, class _Up>
1055_LIBCPP_INLINE_VISIBILITY constexpr
1056enable_if_t<
1057    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1058        _VSTD::declval<const _Up&>()), bool>,
1059    bool
1060>
1061operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1062{
1063    if (!static_cast<bool>(__y))
1064        return false;
1065    if (!static_cast<bool>(__x))
1066        return true;
1067    return *__x < *__y;
1068}
1069
1070template <class _Tp, class _Up>
1071_LIBCPP_INLINE_VISIBILITY constexpr
1072enable_if_t<
1073    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1074        _VSTD::declval<const _Up&>()), bool>,
1075    bool
1076>
1077operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1078{
1079    if (!static_cast<bool>(__x))
1080        return false;
1081    if (!static_cast<bool>(__y))
1082        return true;
1083    return *__x > *__y;
1084}
1085
1086template <class _Tp, class _Up>
1087_LIBCPP_INLINE_VISIBILITY constexpr
1088enable_if_t<
1089    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1090        _VSTD::declval<const _Up&>()), bool>,
1091    bool
1092>
1093operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1094{
1095    if (!static_cast<bool>(__x))
1096        return true;
1097    if (!static_cast<bool>(__y))
1098        return false;
1099    return *__x <= *__y;
1100}
1101
1102template <class _Tp, class _Up>
1103_LIBCPP_INLINE_VISIBILITY constexpr
1104enable_if_t<
1105    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1106        _VSTD::declval<const _Up&>()), bool>,
1107    bool
1108>
1109operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1110{
1111    if (!static_cast<bool>(__y))
1112        return true;
1113    if (!static_cast<bool>(__x))
1114        return false;
1115    return *__x >= *__y;
1116}
1117
1118// Comparisons with nullopt
1119template <class _Tp>
1120_LIBCPP_INLINE_VISIBILITY constexpr
1121bool
1122operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1123{
1124    return !static_cast<bool>(__x);
1125}
1126
1127template <class _Tp>
1128_LIBCPP_INLINE_VISIBILITY constexpr
1129bool
1130operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1131{
1132    return !static_cast<bool>(__x);
1133}
1134
1135template <class _Tp>
1136_LIBCPP_INLINE_VISIBILITY constexpr
1137bool
1138operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1139{
1140    return static_cast<bool>(__x);
1141}
1142
1143template <class _Tp>
1144_LIBCPP_INLINE_VISIBILITY constexpr
1145bool
1146operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1147{
1148    return static_cast<bool>(__x);
1149}
1150
1151template <class _Tp>
1152_LIBCPP_INLINE_VISIBILITY constexpr
1153bool
1154operator<(const optional<_Tp>&, nullopt_t) noexcept
1155{
1156    return false;
1157}
1158
1159template <class _Tp>
1160_LIBCPP_INLINE_VISIBILITY constexpr
1161bool
1162operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1163{
1164    return static_cast<bool>(__x);
1165}
1166
1167template <class _Tp>
1168_LIBCPP_INLINE_VISIBILITY constexpr
1169bool
1170operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1171{
1172    return !static_cast<bool>(__x);
1173}
1174
1175template <class _Tp>
1176_LIBCPP_INLINE_VISIBILITY constexpr
1177bool
1178operator<=(nullopt_t, const optional<_Tp>&) noexcept
1179{
1180    return true;
1181}
1182
1183template <class _Tp>
1184_LIBCPP_INLINE_VISIBILITY constexpr
1185bool
1186operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1187{
1188    return static_cast<bool>(__x);
1189}
1190
1191template <class _Tp>
1192_LIBCPP_INLINE_VISIBILITY constexpr
1193bool
1194operator>(nullopt_t, const optional<_Tp>&) noexcept
1195{
1196    return false;
1197}
1198
1199template <class _Tp>
1200_LIBCPP_INLINE_VISIBILITY constexpr
1201bool
1202operator>=(const optional<_Tp>&, nullopt_t) noexcept
1203{
1204    return true;
1205}
1206
1207template <class _Tp>
1208_LIBCPP_INLINE_VISIBILITY constexpr
1209bool
1210operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1211{
1212    return !static_cast<bool>(__x);
1213}
1214
1215// Comparisons with T
1216template <class _Tp, class _Up>
1217_LIBCPP_INLINE_VISIBILITY constexpr
1218enable_if_t<
1219    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1220        _VSTD::declval<const _Up&>()), bool>,
1221    bool
1222>
1223operator==(const optional<_Tp>& __x, const _Up& __v)
1224{
1225    return static_cast<bool>(__x) ? *__x == __v : false;
1226}
1227
1228template <class _Tp, class _Up>
1229_LIBCPP_INLINE_VISIBILITY constexpr
1230enable_if_t<
1231    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1232        _VSTD::declval<const _Up&>()), bool>,
1233    bool
1234>
1235operator==(const _Tp& __v, const optional<_Up>& __x)
1236{
1237    return static_cast<bool>(__x) ? __v == *__x : false;
1238}
1239
1240template <class _Tp, class _Up>
1241_LIBCPP_INLINE_VISIBILITY constexpr
1242enable_if_t<
1243    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1244        _VSTD::declval<const _Up&>()), bool>,
1245    bool
1246>
1247operator!=(const optional<_Tp>& __x, const _Up& __v)
1248{
1249    return static_cast<bool>(__x) ? *__x != __v : true;
1250}
1251
1252template <class _Tp, class _Up>
1253_LIBCPP_INLINE_VISIBILITY constexpr
1254enable_if_t<
1255    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1256        _VSTD::declval<const _Up&>()), bool>,
1257    bool
1258>
1259operator!=(const _Tp& __v, const optional<_Up>& __x)
1260{
1261    return static_cast<bool>(__x) ? __v != *__x : true;
1262}
1263
1264template <class _Tp, class _Up>
1265_LIBCPP_INLINE_VISIBILITY constexpr
1266enable_if_t<
1267    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1268        _VSTD::declval<const _Up&>()), bool>,
1269    bool
1270>
1271operator<(const optional<_Tp>& __x, const _Up& __v)
1272{
1273    return static_cast<bool>(__x) ? *__x < __v : true;
1274}
1275
1276template <class _Tp, class _Up>
1277_LIBCPP_INLINE_VISIBILITY constexpr
1278enable_if_t<
1279    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1280        _VSTD::declval<const _Up&>()), bool>,
1281    bool
1282>
1283operator<(const _Tp& __v, const optional<_Up>& __x)
1284{
1285    return static_cast<bool>(__x) ? __v < *__x : false;
1286}
1287
1288template <class _Tp, class _Up>
1289_LIBCPP_INLINE_VISIBILITY constexpr
1290enable_if_t<
1291    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1292        _VSTD::declval<const _Up&>()), bool>,
1293    bool
1294>
1295operator<=(const optional<_Tp>& __x, const _Up& __v)
1296{
1297    return static_cast<bool>(__x) ? *__x <= __v : true;
1298}
1299
1300template <class _Tp, class _Up>
1301_LIBCPP_INLINE_VISIBILITY constexpr
1302enable_if_t<
1303    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1304        _VSTD::declval<const _Up&>()), bool>,
1305    bool
1306>
1307operator<=(const _Tp& __v, const optional<_Up>& __x)
1308{
1309    return static_cast<bool>(__x) ? __v <= *__x : false;
1310}
1311
1312template <class _Tp, class _Up>
1313_LIBCPP_INLINE_VISIBILITY constexpr
1314enable_if_t<
1315    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1316        _VSTD::declval<const _Up&>()), bool>,
1317    bool
1318>
1319operator>(const optional<_Tp>& __x, const _Up& __v)
1320{
1321    return static_cast<bool>(__x) ? *__x > __v : false;
1322}
1323
1324template <class _Tp, class _Up>
1325_LIBCPP_INLINE_VISIBILITY constexpr
1326enable_if_t<
1327    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1328        _VSTD::declval<const _Up&>()), bool>,
1329    bool
1330>
1331operator>(const _Tp& __v, const optional<_Up>& __x)
1332{
1333    return static_cast<bool>(__x) ? __v > *__x : true;
1334}
1335
1336template <class _Tp, class _Up>
1337_LIBCPP_INLINE_VISIBILITY constexpr
1338enable_if_t<
1339    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1340        _VSTD::declval<const _Up&>()), bool>,
1341    bool
1342>
1343operator>=(const optional<_Tp>& __x, const _Up& __v)
1344{
1345    return static_cast<bool>(__x) ? *__x >= __v : false;
1346}
1347
1348template <class _Tp, class _Up>
1349_LIBCPP_INLINE_VISIBILITY constexpr
1350enable_if_t<
1351    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1352        _VSTD::declval<const _Up&>()), bool>,
1353    bool
1354>
1355operator>=(const _Tp& __v, const optional<_Up>& __x)
1356{
1357    return static_cast<bool>(__x) ? __v >= *__x : true;
1358}
1359
1360
1361template <class _Tp>
1362inline _LIBCPP_INLINE_VISIBILITY
1363enable_if_t<
1364    is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1365    void
1366>
1367swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1368{
1369    __x.swap(__y);
1370}
1371
1372template <class _Tp>
1373_LIBCPP_INLINE_VISIBILITY constexpr
1374optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1375{
1376    return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1377}
1378
1379template <class _Tp, class... _Args>
1380_LIBCPP_INLINE_VISIBILITY constexpr
1381optional<_Tp> make_optional(_Args&&... __args)
1382{
1383    return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1384}
1385
1386template <class _Tp, class _Up, class... _Args>
1387_LIBCPP_INLINE_VISIBILITY constexpr
1388optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1389{
1390    return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1391}
1392
1393template <class _Tp>
1394struct _LIBCPP_TEMPLATE_VIS hash<
1395    __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1396>
1397{
1398    typedef optional<_Tp> argument_type;
1399    typedef size_t        result_type;
1400
1401    _LIBCPP_INLINE_VISIBILITY
1402    result_type operator()(const argument_type& __opt) const
1403    {
1404        return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1405    }
1406};
1407
1408_LIBCPP_END_NAMESPACE_STD
1409
1410#endif  // _LIBCPP_STD_VER > 14
1411
1412_LIBCPP_POP_MACROS
1413
1414#endif  // _LIBCPP_OPTIONAL
1415