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