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