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