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