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