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