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