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