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