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