xref: /openbsd-src/gnu/llvm/libcxx/include/optional (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_OPTIONAL
1146035553Spatrick#define _LIBCPP_OPTIONAL
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    optional synopsis
1546035553Spatrick
1646035553Spatrick// C++1z
1746035553Spatrick
1846035553Spatricknamespace std {
1946035553Spatrick  // 23.6.3, optional for object types
2046035553Spatrick  template <class T> class optional;
2146035553Spatrick
2246035553Spatrick  // 23.6.4, no-value state indicator
2346035553Spatrick  struct nullopt_t{see below };
2446035553Spatrick  inline constexpr nullopt_t nullopt(unspecified );
2546035553Spatrick
2646035553Spatrick  // 23.6.5, class bad_optional_access
2746035553Spatrick  class bad_optional_access;
2846035553Spatrick
2946035553Spatrick  // 23.6.6, relational operators
3046035553Spatrick  template <class T, class U>
3146035553Spatrick  constexpr bool operator==(const optional<T>&, const optional<U>&);
3246035553Spatrick  template <class T, class U>
3346035553Spatrick  constexpr bool operator!=(const optional<T>&, const optional<U>&);
3446035553Spatrick  template <class T, class U>
3546035553Spatrick  constexpr bool operator<(const optional<T>&, const optional<U>&);
3646035553Spatrick  template <class T, class U>
3746035553Spatrick  constexpr bool operator>(const optional<T>&, const optional<U>&);
3846035553Spatrick  template <class T, class U>
3946035553Spatrick  constexpr bool operator<=(const optional<T>&, const optional<U>&);
4046035553Spatrick  template <class T, class U>
4146035553Spatrick  constexpr bool operator>=(const optional<T>&, const optional<U>&);
4246035553Spatrick
4346035553Spatrick  // 23.6.7 comparison with nullopt
4446035553Spatrick  template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
4546035553Spatrick  template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
4646035553Spatrick  template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
4746035553Spatrick  template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
4846035553Spatrick  template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
4946035553Spatrick  template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
5046035553Spatrick  template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
5146035553Spatrick  template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
5246035553Spatrick  template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
5346035553Spatrick  template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
5446035553Spatrick  template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
5546035553Spatrick  template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
5646035553Spatrick
5746035553Spatrick  // 23.6.8, comparison with T
5846035553Spatrick  template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
5946035553Spatrick  template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
6046035553Spatrick  template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
6146035553Spatrick  template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
6246035553Spatrick  template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
6346035553Spatrick  template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
6446035553Spatrick  template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
6546035553Spatrick  template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
6646035553Spatrick  template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
6746035553Spatrick  template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
6846035553Spatrick  template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
6946035553Spatrick  template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
7046035553Spatrick
7146035553Spatrick  // 23.6.9, specialized algorithms
7276d0caaeSpatrick  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
7346035553Spatrick  template <class T> constexpr optional<see below > make_optional(T&&);
7446035553Spatrick  template <class T, class... Args>
7546035553Spatrick    constexpr optional<T> make_optional(Args&&... args);
7646035553Spatrick  template <class T, class U, class... Args>
7746035553Spatrick    constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
7846035553Spatrick
7946035553Spatrick  // 23.6.10, hash support
8046035553Spatrick  template <class T> struct hash;
8146035553Spatrick  template <class T> struct hash<optional<T>>;
8246035553Spatrick
8346035553Spatrick  template <class T> class optional {
8446035553Spatrick  public:
8546035553Spatrick    using value_type = T;
8646035553Spatrick
8746035553Spatrick    // 23.6.3.1, constructors
8846035553Spatrick    constexpr optional() noexcept;
8946035553Spatrick    constexpr optional(nullopt_t) noexcept;
90*4bdff4beSrobert    constexpr optional(const optional &);
91*4bdff4beSrobert    constexpr optional(optional &&) noexcept(see below);
9246035553Spatrick    template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
9346035553Spatrick    template <class U, class... Args>
9446035553Spatrick      constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
9546035553Spatrick    template <class U = T>
96*4bdff4beSrobert      constexpr explicit(see-below) optional(U &&);
9746035553Spatrick    template <class U>
98*4bdff4beSrobert      explicit(see-below) optional(const optional<U> &);         // constexpr in C++20
9946035553Spatrick    template <class U>
100*4bdff4beSrobert      explicit(see-below) optional(optional<U> &&);              // constexpr in C++20
10146035553Spatrick
10246035553Spatrick    // 23.6.3.2, destructor
10376d0caaeSpatrick    ~optional(); // constexpr in C++20
10446035553Spatrick
10546035553Spatrick    // 23.6.3.3, assignment
10676d0caaeSpatrick    optional &operator=(nullopt_t) noexcept;                     // constexpr in C++20
107*4bdff4beSrobert    constexpr optional &operator=(const optional &);
108*4bdff4beSrobert    constexpr optional &operator=(optional &&) noexcept(see below);
10976d0caaeSpatrick    template <class U = T> optional &operator=(U &&);            // constexpr in C++20
11076d0caaeSpatrick    template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
11176d0caaeSpatrick    template <class U> optional &operator=(optional<U> &&);      // constexpr in C++20
11276d0caaeSpatrick    template <class... Args> T& emplace(Args &&...);             // constexpr in C++20
11346035553Spatrick    template <class U, class... Args>
11476d0caaeSpatrick      T& emplace(initializer_list<U>, Args &&...);               // constexpr in C++20
11546035553Spatrick
11646035553Spatrick    // 23.6.3.4, swap
11776d0caaeSpatrick    void swap(optional &) noexcept(see below ); // constexpr in C++20
11846035553Spatrick
11946035553Spatrick    // 23.6.3.5, observers
12046035553Spatrick    constexpr T const *operator->() const;
12146035553Spatrick    constexpr T *operator->();
12246035553Spatrick    constexpr T const &operator*() const &;
12346035553Spatrick    constexpr T &operator*() &;
12446035553Spatrick    constexpr T &&operator*() &&;
12546035553Spatrick    constexpr const T &&operator*() const &&;
12646035553Spatrick    constexpr explicit operator bool() const noexcept;
12746035553Spatrick    constexpr bool has_value() const noexcept;
12846035553Spatrick    constexpr T const &value() const &;
12946035553Spatrick    constexpr T &value() &;
13046035553Spatrick    constexpr T &&value() &&;
13146035553Spatrick    constexpr const T &&value() const &&;
13246035553Spatrick    template <class U> constexpr T value_or(U &&) const &;
13346035553Spatrick    template <class U> constexpr T value_or(U &&) &&;
13446035553Spatrick
135*4bdff4beSrobert    // [optional.monadic], monadic operations
136*4bdff4beSrobert    template<class F> constexpr auto and_then(F&& f) &;         // since C++23
137*4bdff4beSrobert    template<class F> constexpr auto and_then(F&& f) &&;        // since C++23
138*4bdff4beSrobert    template<class F> constexpr auto and_then(F&& f) const&;    // since C++23
139*4bdff4beSrobert    template<class F> constexpr auto and_then(F&& f) const&&;   // since C++23
140*4bdff4beSrobert    template<class F> constexpr auto transform(F&& f) &;        // since C++23
141*4bdff4beSrobert    template<class F> constexpr auto transform(F&& f) &&;       // since C++23
142*4bdff4beSrobert    template<class F> constexpr auto transform(F&& f) const&;   // since C++23
143*4bdff4beSrobert    template<class F> constexpr auto transform(F&& f) const&&;  // since C++23
144*4bdff4beSrobert    template<class F> constexpr optional or_else(F&& f) &&;     // since C++23
145*4bdff4beSrobert    template<class F> constexpr optional or_else(F&& f) const&; // since C++23
146*4bdff4beSrobert
14746035553Spatrick    // 23.6.3.6, modifiers
14876d0caaeSpatrick    void reset() noexcept; // constexpr in C++20
14946035553Spatrick
15046035553Spatrick  private:
15146035553Spatrick    T *val; // exposition only
15246035553Spatrick  };
15346035553Spatrick
15446035553Spatricktemplate<class T>
15546035553Spatrick  optional(T) -> optional<T>;
15646035553Spatrick
15746035553Spatrick} // namespace std
15846035553Spatrick
15946035553Spatrick*/
16046035553Spatrick
161*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
16276d0caaeSpatrick#include <__availability>
163*4bdff4beSrobert#include <__concepts/invocable.h>
16446035553Spatrick#include <__config>
165*4bdff4beSrobert#include <__functional/hash.h>
166*4bdff4beSrobert#include <__functional/invoke.h>
167*4bdff4beSrobert#include <__functional/unary_function.h>
168*4bdff4beSrobert#include <__memory/construct_at.h>
169*4bdff4beSrobert#include <__tuple_dir/sfinae_helpers.h>
170*4bdff4beSrobert#include <__utility/forward.h>
171*4bdff4beSrobert#include <__utility/in_place.h>
172*4bdff4beSrobert#include <__utility/move.h>
173*4bdff4beSrobert#include <__utility/swap.h>
17446035553Spatrick#include <initializer_list>
17546035553Spatrick#include <new>
17646035553Spatrick#include <stdexcept>
17746035553Spatrick#include <type_traits>
17846035553Spatrick#include <version>
17946035553Spatrick
180*4bdff4beSrobert// standard-mandated includes
181*4bdff4beSrobert
182*4bdff4beSrobert// [optional.syn]
183*4bdff4beSrobert#include <compare>
184*4bdff4beSrobert
18546035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18646035553Spatrick#  pragma GCC system_header
18746035553Spatrick#endif
18846035553Spatrick
18946035553Spatricknamespace std  // purposefully not using versioning namespace
19046035553Spatrick{
19146035553Spatrick
19246035553Spatrickclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
19346035553Spatrick    : public exception
19446035553Spatrick{
19546035553Spatrickpublic:
19646035553Spatrick    // Get the key function ~bad_optional_access() into the dylib
197*4bdff4beSrobert    ~bad_optional_access() _NOEXCEPT override;
198*4bdff4beSrobert    const char* what() const _NOEXCEPT override;
19946035553Spatrick};
20046035553Spatrick
201*4bdff4beSrobert} // namespace std
20246035553Spatrick
20346035553Spatrick#if _LIBCPP_STD_VER > 14
20446035553Spatrick
20546035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
20646035553Spatrick
20746035553Spatrick_LIBCPP_NORETURN
20846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
20946035553Spatrick_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
21046035553Spatrickvoid __throw_bad_optional_access() {
21146035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS
21246035553Spatrick        throw bad_optional_access();
21346035553Spatrick#else
21446035553Spatrick        _VSTD::abort();
21546035553Spatrick#endif
21646035553Spatrick}
21746035553Spatrick
21846035553Spatrickstruct nullopt_t
21946035553Spatrick{
22046035553Spatrick    struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
22146035553Spatrick    _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
22246035553Spatrick};
22346035553Spatrick
224*4bdff4beSrobertinline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
225*4bdff4beSrobert
226*4bdff4beSrobertstruct __optional_construct_from_invoke_tag {};
22746035553Spatrick
22846035553Spatricktemplate <class _Tp, bool = is_trivially_destructible<_Tp>::value>
22946035553Spatrickstruct __optional_destruct_base;
23046035553Spatrick
23146035553Spatricktemplate <class _Tp>
23246035553Spatrickstruct __optional_destruct_base<_Tp, false>
23346035553Spatrick{
23446035553Spatrick    typedef _Tp value_type;
23546035553Spatrick    static_assert(is_object_v<value_type>,
23646035553Spatrick        "instantiation of optional with a non-object type is undefined behavior");
23746035553Spatrick    union
23846035553Spatrick    {
23946035553Spatrick        char __null_state_;
24046035553Spatrick        value_type __val_;
24146035553Spatrick    };
24246035553Spatrick    bool __engaged_;
24346035553Spatrick
24446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
245*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base()
24646035553Spatrick    {
24746035553Spatrick        if (__engaged_)
24846035553Spatrick            __val_.~value_type();
24946035553Spatrick    }
25046035553Spatrick
25146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
25246035553Spatrick    constexpr __optional_destruct_base() noexcept
25346035553Spatrick        :  __null_state_(),
25446035553Spatrick           __engaged_(false) {}
25546035553Spatrick
25646035553Spatrick    template <class... _Args>
25746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
25846035553Spatrick    constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
25946035553Spatrick        :  __val_(_VSTD::forward<_Args>(__args)...),
26046035553Spatrick           __engaged_(true) {}
26146035553Spatrick
262*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
263*4bdff4beSrobert  template <class _Fp, class... _Args>
264*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI
265*4bdff4beSrobert  constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
266*4bdff4beSrobert      : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
267*4bdff4beSrobert#endif
268*4bdff4beSrobert
26946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
270*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept
27146035553Spatrick    {
27246035553Spatrick        if (__engaged_)
27346035553Spatrick        {
27446035553Spatrick            __val_.~value_type();
27546035553Spatrick            __engaged_ = false;
27646035553Spatrick        }
27746035553Spatrick    }
27846035553Spatrick};
27946035553Spatrick
28046035553Spatricktemplate <class _Tp>
28146035553Spatrickstruct __optional_destruct_base<_Tp, true>
28246035553Spatrick{
28346035553Spatrick    typedef _Tp value_type;
28446035553Spatrick    static_assert(is_object_v<value_type>,
28546035553Spatrick        "instantiation of optional with a non-object type is undefined behavior");
28646035553Spatrick    union
28746035553Spatrick    {
28846035553Spatrick        char __null_state_;
28946035553Spatrick        value_type __val_;
29046035553Spatrick    };
29146035553Spatrick    bool __engaged_;
29246035553Spatrick
29346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
29446035553Spatrick    constexpr __optional_destruct_base() noexcept
29546035553Spatrick        :  __null_state_(),
29646035553Spatrick           __engaged_(false) {}
29746035553Spatrick
29846035553Spatrick    template <class... _Args>
29946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
30046035553Spatrick    constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
30146035553Spatrick        :  __val_(_VSTD::forward<_Args>(__args)...),
30246035553Spatrick           __engaged_(true) {}
30346035553Spatrick
304*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
305*4bdff4beSrobert  template <class _Fp, class... _Args>
306*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI
307*4bdff4beSrobert  constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
308*4bdff4beSrobert      : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
309*4bdff4beSrobert#endif
310*4bdff4beSrobert
31146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
312*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept
31346035553Spatrick    {
31446035553Spatrick        if (__engaged_)
31546035553Spatrick        {
31646035553Spatrick            __engaged_ = false;
31746035553Spatrick        }
31846035553Spatrick    }
31946035553Spatrick};
32046035553Spatrick
32146035553Spatricktemplate <class _Tp, bool = is_reference<_Tp>::value>
32246035553Spatrickstruct __optional_storage_base : __optional_destruct_base<_Tp>
32346035553Spatrick{
32446035553Spatrick    using __base = __optional_destruct_base<_Tp>;
32546035553Spatrick    using value_type = _Tp;
32646035553Spatrick    using __base::__base;
32746035553Spatrick
32846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
32946035553Spatrick    constexpr bool has_value() const noexcept
33046035553Spatrick    {
33146035553Spatrick        return this->__engaged_;
33246035553Spatrick    }
33346035553Spatrick
33446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
33546035553Spatrick    constexpr value_type& __get() & noexcept
33646035553Spatrick    {
33746035553Spatrick        return this->__val_;
33846035553Spatrick    }
33946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
34046035553Spatrick    constexpr const value_type& __get() const& noexcept
34146035553Spatrick    {
34246035553Spatrick        return this->__val_;
34346035553Spatrick    }
34446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
34546035553Spatrick    constexpr value_type&& __get() && noexcept
34646035553Spatrick    {
34746035553Spatrick        return _VSTD::move(this->__val_);
34846035553Spatrick    }
34946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
35046035553Spatrick    constexpr const value_type&& __get() const&& noexcept
35146035553Spatrick    {
35246035553Spatrick        return _VSTD::move(this->__val_);
35346035553Spatrick    }
35446035553Spatrick
35546035553Spatrick    template <class... _Args>
35646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
357*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args)
35846035553Spatrick    {
35946035553Spatrick        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
36076d0caaeSpatrick#if _LIBCPP_STD_VER > 17
36176d0caaeSpatrick        _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
36276d0caaeSpatrick#else
36346035553Spatrick        ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
36476d0caaeSpatrick#endif
36546035553Spatrick        this->__engaged_ = true;
36646035553Spatrick    }
36746035553Spatrick
36846035553Spatrick    template <class _That>
36946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
370*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt)
37146035553Spatrick    {
37246035553Spatrick        if (__opt.has_value())
37346035553Spatrick            __construct(_VSTD::forward<_That>(__opt).__get());
37446035553Spatrick    }
37546035553Spatrick
37646035553Spatrick    template <class _That>
37746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
378*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt)
37946035553Spatrick    {
38046035553Spatrick        if (this->__engaged_ == __opt.has_value())
38146035553Spatrick        {
38246035553Spatrick            if (this->__engaged_)
38346035553Spatrick                this->__val_ = _VSTD::forward<_That>(__opt).__get();
38446035553Spatrick        }
38546035553Spatrick        else
38646035553Spatrick        {
38746035553Spatrick            if (this->__engaged_)
38846035553Spatrick                this->reset();
38946035553Spatrick            else
39046035553Spatrick                __construct(_VSTD::forward<_That>(__opt).__get());
39146035553Spatrick        }
39246035553Spatrick    }
39346035553Spatrick};
39446035553Spatrick
395*4bdff4beSrobert// optional<T&> is currently required to be ill-formed. However, it may
396*4bdff4beSrobert// be allowed in the future. For this reason, it has already been implemented
397*4bdff4beSrobert// to ensure we can make the change in an ABI-compatible manner.
39846035553Spatricktemplate <class _Tp>
39946035553Spatrickstruct __optional_storage_base<_Tp, true>
40046035553Spatrick{
40146035553Spatrick    using value_type = _Tp;
40246035553Spatrick    using __raw_type = remove_reference_t<_Tp>;
40346035553Spatrick    __raw_type* __value_;
40446035553Spatrick
40546035553Spatrick    template <class _Up>
40646035553Spatrick    static constexpr bool __can_bind_reference() {
407*4bdff4beSrobert        using _RawUp = __libcpp_remove_reference_t<_Up>;
40846035553Spatrick        using _UpPtr = _RawUp*;
409*4bdff4beSrobert        using _RawTp = __libcpp_remove_reference_t<_Tp>;
41046035553Spatrick        using _TpPtr = _RawTp*;
41146035553Spatrick        using _CheckLValueArg = integral_constant<bool,
41246035553Spatrick            (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
41346035553Spatrick        ||  is_same<_RawUp, reference_wrapper<_RawTp>>::value
414*4bdff4beSrobert        ||  is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value
41546035553Spatrick        >;
41646035553Spatrick        return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
41746035553Spatrick            || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
41846035553Spatrick                is_convertible<_UpPtr, _TpPtr>::value);
41946035553Spatrick    }
42046035553Spatrick
42146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
42246035553Spatrick    constexpr __optional_storage_base() noexcept
42346035553Spatrick        :  __value_(nullptr) {}
42446035553Spatrick
42546035553Spatrick    template <class _UArg>
42646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
42746035553Spatrick    constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
42846035553Spatrick        :  __value_(_VSTD::addressof(__uarg))
42946035553Spatrick    {
43046035553Spatrick      static_assert(__can_bind_reference<_UArg>(),
43146035553Spatrick        "Attempted to construct a reference element in tuple from a "
43246035553Spatrick        "possible temporary");
43346035553Spatrick    }
43446035553Spatrick
43546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
436*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
43746035553Spatrick
43846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
43946035553Spatrick    constexpr bool has_value() const noexcept
44046035553Spatrick      { return __value_ != nullptr; }
44146035553Spatrick
44246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
44346035553Spatrick    constexpr value_type& __get() const& noexcept
44446035553Spatrick      { return *__value_; }
44546035553Spatrick
44646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
44746035553Spatrick    constexpr value_type&& __get() const&& noexcept
44846035553Spatrick      { return _VSTD::forward<value_type>(*__value_); }
44946035553Spatrick
45046035553Spatrick    template <class _UArg>
45146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
452*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val)
45346035553Spatrick    {
45446035553Spatrick        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
45546035553Spatrick        static_assert(__can_bind_reference<_UArg>(),
45646035553Spatrick            "Attempted to construct a reference element in tuple from a "
45746035553Spatrick            "possible temporary");
45846035553Spatrick        __value_ = _VSTD::addressof(__val);
45946035553Spatrick    }
46046035553Spatrick
46146035553Spatrick    template <class _That>
46246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
463*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt)
46446035553Spatrick    {
46546035553Spatrick        if (__opt.has_value())
46646035553Spatrick            __construct(_VSTD::forward<_That>(__opt).__get());
46746035553Spatrick    }
46846035553Spatrick
46946035553Spatrick    template <class _That>
47046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
471*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt)
47246035553Spatrick    {
47346035553Spatrick        if (has_value() == __opt.has_value())
47446035553Spatrick        {
47546035553Spatrick            if (has_value())
47646035553Spatrick                *__value_ = _VSTD::forward<_That>(__opt).__get();
47746035553Spatrick        }
47846035553Spatrick        else
47946035553Spatrick        {
48046035553Spatrick            if (has_value())
48146035553Spatrick                reset();
48246035553Spatrick            else
48346035553Spatrick                __construct(_VSTD::forward<_That>(__opt).__get());
48446035553Spatrick        }
48546035553Spatrick    }
48646035553Spatrick};
48746035553Spatrick
48846035553Spatricktemplate <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
48946035553Spatrickstruct __optional_copy_base : __optional_storage_base<_Tp>
49046035553Spatrick{
49146035553Spatrick    using __optional_storage_base<_Tp>::__optional_storage_base;
49246035553Spatrick};
49346035553Spatrick
49446035553Spatricktemplate <class _Tp>
49546035553Spatrickstruct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
49646035553Spatrick{
49746035553Spatrick    using __optional_storage_base<_Tp>::__optional_storage_base;
49846035553Spatrick
49946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
50046035553Spatrick    __optional_copy_base() = default;
50146035553Spatrick
50246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
503*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt)
50446035553Spatrick    {
50546035553Spatrick        this->__construct_from(__opt);
50646035553Spatrick    }
50746035553Spatrick
50846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
50946035553Spatrick    __optional_copy_base(__optional_copy_base&&) = default;
51046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
51146035553Spatrick    __optional_copy_base& operator=(const __optional_copy_base&) = default;
51246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
51346035553Spatrick    __optional_copy_base& operator=(__optional_copy_base&&) = default;
51446035553Spatrick};
51546035553Spatrick
51646035553Spatricktemplate <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
51746035553Spatrickstruct __optional_move_base : __optional_copy_base<_Tp>
51846035553Spatrick{
51946035553Spatrick    using __optional_copy_base<_Tp>::__optional_copy_base;
52046035553Spatrick};
52146035553Spatrick
52246035553Spatricktemplate <class _Tp>
52346035553Spatrickstruct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
52446035553Spatrick{
52546035553Spatrick    using value_type = _Tp;
52646035553Spatrick    using __optional_copy_base<_Tp>::__optional_copy_base;
52746035553Spatrick
52846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
52946035553Spatrick    __optional_move_base() = default;
53046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
53146035553Spatrick    __optional_move_base(const __optional_move_base&) = default;
53246035553Spatrick
53346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
534*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_base(__optional_move_base&& __opt)
53546035553Spatrick        noexcept(is_nothrow_move_constructible_v<value_type>)
53646035553Spatrick    {
53746035553Spatrick        this->__construct_from(_VSTD::move(__opt));
53846035553Spatrick    }
53946035553Spatrick
54046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
54146035553Spatrick    __optional_move_base& operator=(const __optional_move_base&) = default;
54246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
54346035553Spatrick    __optional_move_base& operator=(__optional_move_base&&) = default;
54446035553Spatrick};
54546035553Spatrick
54646035553Spatricktemplate <class _Tp, bool =
54746035553Spatrick    is_trivially_destructible<_Tp>::value &&
54846035553Spatrick    is_trivially_copy_constructible<_Tp>::value &&
54946035553Spatrick    is_trivially_copy_assignable<_Tp>::value>
55046035553Spatrickstruct __optional_copy_assign_base : __optional_move_base<_Tp>
55146035553Spatrick{
55246035553Spatrick    using __optional_move_base<_Tp>::__optional_move_base;
55346035553Spatrick};
55446035553Spatrick
55546035553Spatricktemplate <class _Tp>
55646035553Spatrickstruct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
55746035553Spatrick{
55846035553Spatrick    using __optional_move_base<_Tp>::__optional_move_base;
55946035553Spatrick
56046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
56146035553Spatrick    __optional_copy_assign_base() = default;
56246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
56346035553Spatrick    __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
56446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
56546035553Spatrick    __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
56646035553Spatrick
56746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
568*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
56946035553Spatrick    {
57046035553Spatrick        this->__assign_from(__opt);
57146035553Spatrick        return *this;
57246035553Spatrick    }
57346035553Spatrick
57446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
57546035553Spatrick    __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
57646035553Spatrick};
57746035553Spatrick
57846035553Spatricktemplate <class _Tp, bool =
57946035553Spatrick    is_trivially_destructible<_Tp>::value &&
58046035553Spatrick    is_trivially_move_constructible<_Tp>::value &&
58146035553Spatrick    is_trivially_move_assignable<_Tp>::value>
58246035553Spatrickstruct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
58346035553Spatrick{
58446035553Spatrick    using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
58546035553Spatrick};
58646035553Spatrick
58746035553Spatricktemplate <class _Tp>
58846035553Spatrickstruct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
58946035553Spatrick{
59046035553Spatrick    using value_type = _Tp;
59146035553Spatrick    using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
59246035553Spatrick
59346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
59446035553Spatrick    __optional_move_assign_base() = default;
59546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
59646035553Spatrick    __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
59746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
59846035553Spatrick    __optional_move_assign_base(__optional_move_assign_base&&) = default;
59946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
60046035553Spatrick    __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
60146035553Spatrick
60246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
603*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
60446035553Spatrick        noexcept(is_nothrow_move_assignable_v<value_type> &&
60546035553Spatrick                 is_nothrow_move_constructible_v<value_type>)
60646035553Spatrick    {
60746035553Spatrick        this->__assign_from(_VSTD::move(__opt));
60846035553Spatrick        return *this;
60946035553Spatrick    }
61046035553Spatrick};
61146035553Spatrick
61246035553Spatricktemplate <class _Tp>
61346035553Spatrickusing __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
61446035553Spatrick    is_copy_constructible<_Tp>::value,
61546035553Spatrick    is_move_constructible<_Tp>::value
61646035553Spatrick>;
61746035553Spatrick
61846035553Spatricktemplate <class _Tp>
61946035553Spatrickusing __optional_sfinae_assign_base_t = __sfinae_assign_base<
62046035553Spatrick    (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
62146035553Spatrick    (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
62246035553Spatrick>;
62346035553Spatrick
62446035553Spatricktemplate<class _Tp>
625*4bdff4beSrobertclass optional;
626*4bdff4beSroberttemplate <class _Tp>
627*4bdff4beSrobertstruct __is_std_optional : false_type {};
628*4bdff4beSroberttemplate <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
629*4bdff4beSrobert
630*4bdff4beSroberttemplate <class _Tp>
63146035553Spatrickclass optional
63246035553Spatrick    : private __optional_move_assign_base<_Tp>
63346035553Spatrick    , private __optional_sfinae_ctor_base_t<_Tp>
63446035553Spatrick    , private __optional_sfinae_assign_base_t<_Tp>
63546035553Spatrick{
63646035553Spatrick    using __base = __optional_move_assign_base<_Tp>;
63746035553Spatrickpublic:
63846035553Spatrick    using value_type = _Tp;
63946035553Spatrick
64046035553Spatrickprivate:
64146035553Spatrick     // Disable the reference extension using this static assert.
642*4bdff4beSrobert    static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
64346035553Spatrick        "instantiation of optional with in_place_t is ill-formed");
644*4bdff4beSrobert    static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
64546035553Spatrick        "instantiation of optional with nullopt_t is ill-formed");
64646035553Spatrick    static_assert(!is_reference_v<value_type>,
64746035553Spatrick        "instantiation of optional with a reference type is ill-formed");
64846035553Spatrick    static_assert(is_destructible_v<value_type>,
64946035553Spatrick        "instantiation of optional with a non-destructible type is ill-formed");
65046035553Spatrick    static_assert(!is_array_v<value_type>,
65146035553Spatrick        "instantiation of optional with an array type is ill-formed");
65246035553Spatrick
65346035553Spatrick    // LWG2756: conditionally explicit conversion from _Up
65446035553Spatrick    struct _CheckOptionalArgsConstructor {
65546035553Spatrick      template <class _Up>
65646035553Spatrick      static constexpr bool __enable_implicit() {
65746035553Spatrick          return is_constructible_v<_Tp, _Up&&> &&
65846035553Spatrick                 is_convertible_v<_Up&&, _Tp>;
65946035553Spatrick      }
66046035553Spatrick
66146035553Spatrick      template <class _Up>
66246035553Spatrick      static constexpr bool __enable_explicit() {
66346035553Spatrick          return is_constructible_v<_Tp, _Up&&> &&
66446035553Spatrick                 !is_convertible_v<_Up&&, _Tp>;
66546035553Spatrick      }
66646035553Spatrick    };
66746035553Spatrick    template <class _Up>
66846035553Spatrick    using _CheckOptionalArgsCtor = _If<
669*4bdff4beSrobert        _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value &&
670*4bdff4beSrobert        _IsNotSame<__remove_cvref_t<_Up>, optional>::value,
67146035553Spatrick        _CheckOptionalArgsConstructor,
67246035553Spatrick        __check_tuple_constructor_fail
67346035553Spatrick    >;
67446035553Spatrick    template <class _QualUp>
67546035553Spatrick    struct _CheckOptionalLikeConstructor {
67646035553Spatrick      template <class _Up, class _Opt = optional<_Up>>
67746035553Spatrick      using __check_constructible_from_opt = _Or<
67846035553Spatrick          is_constructible<_Tp, _Opt&>,
67946035553Spatrick          is_constructible<_Tp, _Opt const&>,
68046035553Spatrick          is_constructible<_Tp, _Opt&&>,
68146035553Spatrick          is_constructible<_Tp, _Opt const&&>,
68246035553Spatrick          is_convertible<_Opt&, _Tp>,
68346035553Spatrick          is_convertible<_Opt const&, _Tp>,
68446035553Spatrick          is_convertible<_Opt&&, _Tp>,
68546035553Spatrick          is_convertible<_Opt const&&, _Tp>
68646035553Spatrick      >;
68746035553Spatrick      template <class _Up, class _Opt = optional<_Up>>
68846035553Spatrick      using __check_assignable_from_opt = _Or<
68946035553Spatrick          is_assignable<_Tp&, _Opt&>,
69046035553Spatrick          is_assignable<_Tp&, _Opt const&>,
69146035553Spatrick          is_assignable<_Tp&, _Opt&&>,
69246035553Spatrick          is_assignable<_Tp&, _Opt const&&>
69346035553Spatrick      >;
69446035553Spatrick      template <class _Up, class _QUp = _QualUp>
69546035553Spatrick      static constexpr bool __enable_implicit() {
69646035553Spatrick          return is_convertible<_QUp, _Tp>::value &&
69746035553Spatrick              !__check_constructible_from_opt<_Up>::value;
69846035553Spatrick      }
69946035553Spatrick      template <class _Up, class _QUp = _QualUp>
70046035553Spatrick      static constexpr bool __enable_explicit() {
70146035553Spatrick          return !is_convertible<_QUp, _Tp>::value &&
70246035553Spatrick              !__check_constructible_from_opt<_Up>::value;
70346035553Spatrick      }
70446035553Spatrick      template <class _Up, class _QUp = _QualUp>
70546035553Spatrick      static constexpr bool __enable_assign() {
70676d0caaeSpatrick          // Construction and assignability of _QUp to _Tp has already been
70746035553Spatrick          // checked.
70846035553Spatrick          return !__check_constructible_from_opt<_Up>::value &&
70946035553Spatrick              !__check_assignable_from_opt<_Up>::value;
71046035553Spatrick      }
71146035553Spatrick    };
71246035553Spatrick
71346035553Spatrick    template <class _Up, class _QualUp>
71446035553Spatrick    using _CheckOptionalLikeCtor = _If<
71546035553Spatrick      _And<
71646035553Spatrick         _IsNotSame<_Up, _Tp>,
71746035553Spatrick          is_constructible<_Tp, _QualUp>
71846035553Spatrick      >::value,
71946035553Spatrick      _CheckOptionalLikeConstructor<_QualUp>,
72046035553Spatrick      __check_tuple_constructor_fail
72146035553Spatrick    >;
72246035553Spatrick    template <class _Up, class _QualUp>
72346035553Spatrick    using _CheckOptionalLikeAssign = _If<
72446035553Spatrick      _And<
72546035553Spatrick          _IsNotSame<_Up, _Tp>,
72646035553Spatrick          is_constructible<_Tp, _QualUp>,
72746035553Spatrick          is_assignable<_Tp&, _QualUp>
72846035553Spatrick      >::value,
72946035553Spatrick      _CheckOptionalLikeConstructor<_QualUp>,
73046035553Spatrick      __check_tuple_constructor_fail
73146035553Spatrick    >;
732*4bdff4beSrobert
73346035553Spatrickpublic:
73446035553Spatrick
73546035553Spatrick    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
73646035553Spatrick    _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
73746035553Spatrick    _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
73846035553Spatrick    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
73946035553Spatrick
740*4bdff4beSrobert    template <class _InPlaceT, class... _Args, class = enable_if_t<
74146035553Spatrick          _And<
74246035553Spatrick              _IsSame<_InPlaceT, in_place_t>,
74346035553Spatrick              is_constructible<value_type, _Args...>
74446035553Spatrick            >::value
74546035553Spatrick        >
74646035553Spatrick    >
74746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
74846035553Spatrick    constexpr explicit optional(_InPlaceT, _Args&&... __args)
74946035553Spatrick        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
75046035553Spatrick
751*4bdff4beSrobert    template <class _Up, class... _Args, class = enable_if_t<
75246035553Spatrick        is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
75346035553Spatrick    >
75446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
75546035553Spatrick    constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
75646035553Spatrick        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
75746035553Spatrick
758*4bdff4beSrobert    template <class _Up = value_type, enable_if_t<
75946035553Spatrick        _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
76046035553Spatrick    , int> = 0>
76146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
76246035553Spatrick    constexpr optional(_Up&& __v)
76346035553Spatrick        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
76446035553Spatrick
765*4bdff4beSrobert    template <class _Up, enable_if_t<
76646035553Spatrick        _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
76746035553Spatrick    , int> = 0>
76846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
76946035553Spatrick    constexpr explicit optional(_Up&& __v)
77046035553Spatrick        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
77146035553Spatrick
77246035553Spatrick    // LWG2756: conditionally explicit conversion from const optional<_Up>&
773*4bdff4beSrobert    template <class _Up, enable_if_t<
77446035553Spatrick        _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
77546035553Spatrick    , int> = 0>
77646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
777*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v)
77846035553Spatrick    {
77946035553Spatrick        this->__construct_from(__v);
78046035553Spatrick    }
781*4bdff4beSrobert    template <class _Up, enable_if_t<
78246035553Spatrick        _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
78346035553Spatrick    , int> = 0>
78446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
785*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v)
78646035553Spatrick    {
78746035553Spatrick        this->__construct_from(__v);
78846035553Spatrick    }
78946035553Spatrick
79046035553Spatrick    // LWG2756: conditionally explicit conversion from optional<_Up>&&
791*4bdff4beSrobert    template <class _Up, enable_if_t<
79246035553Spatrick        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
79346035553Spatrick    , int> = 0>
79446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
795*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v)
79646035553Spatrick    {
79746035553Spatrick        this->__construct_from(_VSTD::move(__v));
79846035553Spatrick    }
799*4bdff4beSrobert    template <class _Up, enable_if_t<
80046035553Spatrick        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
80146035553Spatrick    , int> = 0>
80246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
803*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v)
80446035553Spatrick    {
80546035553Spatrick        this->__construct_from(_VSTD::move(__v));
80646035553Spatrick    }
80746035553Spatrick
808*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
809*4bdff4beSrobert  template<class _Fp, class... _Args>
810*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI
811*4bdff4beSrobert  constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
812*4bdff4beSrobert      : __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) {
813*4bdff4beSrobert  }
814*4bdff4beSrobert#endif
815*4bdff4beSrobert
81646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
817*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept
81846035553Spatrick    {
81946035553Spatrick        reset();
82046035553Spatrick        return *this;
82146035553Spatrick    }
82246035553Spatrick
823*4bdff4beSrobert    constexpr optional& operator=(const optional&) = default;
824*4bdff4beSrobert    constexpr optional& operator=(optional&&) = default;
82546035553Spatrick
82646035553Spatrick    // LWG2756
82746035553Spatrick    template <class _Up = value_type,
828*4bdff4beSrobert              class = enable_if_t<
82946035553Spatrick                      _And<
830*4bdff4beSrobert                          _IsNotSame<__remove_cvref_t<_Up>, optional>,
83146035553Spatrick                          _Or<
832*4bdff4beSrobert                              _IsNotSame<__remove_cvref_t<_Up>, value_type>,
83346035553Spatrick                              _Not<is_scalar<value_type>>
83446035553Spatrick                          >,
83546035553Spatrick                          is_constructible<value_type, _Up>,
83646035553Spatrick                          is_assignable<value_type&, _Up>
83746035553Spatrick                      >::value>
83846035553Spatrick             >
83946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
840*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
84146035553Spatrick    operator=(_Up&& __v)
84246035553Spatrick    {
84346035553Spatrick        if (this->has_value())
84446035553Spatrick            this->__get() = _VSTD::forward<_Up>(__v);
84546035553Spatrick        else
84646035553Spatrick            this->__construct(_VSTD::forward<_Up>(__v));
84746035553Spatrick        return *this;
84846035553Spatrick    }
84946035553Spatrick
85046035553Spatrick    // LWG2756
851*4bdff4beSrobert    template <class _Up, enable_if_t<
85246035553Spatrick        _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
85346035553Spatrick    , int> = 0>
85446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
855*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
85646035553Spatrick    operator=(const optional<_Up>& __v)
85746035553Spatrick    {
85846035553Spatrick        this->__assign_from(__v);
85946035553Spatrick        return *this;
86046035553Spatrick    }
86146035553Spatrick
86246035553Spatrick    // LWG2756
863*4bdff4beSrobert    template <class _Up, enable_if_t<
86446035553Spatrick        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
86546035553Spatrick    , int> = 0>
86646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
867*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 optional&
86846035553Spatrick    operator=(optional<_Up>&& __v)
86946035553Spatrick    {
87046035553Spatrick        this->__assign_from(_VSTD::move(__v));
87146035553Spatrick        return *this;
87246035553Spatrick    }
87346035553Spatrick
87446035553Spatrick    template <class... _Args,
875*4bdff4beSrobert              class = enable_if_t
87646035553Spatrick                      <
87746035553Spatrick                          is_constructible_v<value_type, _Args...>
87846035553Spatrick                      >
87946035553Spatrick             >
88046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
881*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &
88246035553Spatrick    emplace(_Args&&... __args)
88346035553Spatrick    {
88446035553Spatrick        reset();
88546035553Spatrick        this->__construct(_VSTD::forward<_Args>(__args)...);
88646035553Spatrick        return this->__get();
88746035553Spatrick    }
88846035553Spatrick
88946035553Spatrick    template <class _Up, class... _Args,
890*4bdff4beSrobert              class = enable_if_t
89146035553Spatrick                      <
89246035553Spatrick                          is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
89346035553Spatrick                      >
89446035553Spatrick             >
89546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
896*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp &
89746035553Spatrick    emplace(initializer_list<_Up> __il, _Args&&... __args)
89846035553Spatrick    {
89946035553Spatrick        reset();
90046035553Spatrick        this->__construct(__il, _VSTD::forward<_Args>(__args)...);
90146035553Spatrick        return this->__get();
90246035553Spatrick    }
90346035553Spatrick
90446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
905*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt)
90646035553Spatrick        noexcept(is_nothrow_move_constructible_v<value_type> &&
90746035553Spatrick                 is_nothrow_swappable_v<value_type>)
90846035553Spatrick    {
90946035553Spatrick        if (this->has_value() == __opt.has_value())
91046035553Spatrick        {
91146035553Spatrick            using _VSTD::swap;
91246035553Spatrick            if (this->has_value())
91346035553Spatrick                swap(this->__get(), __opt.__get());
91446035553Spatrick        }
91546035553Spatrick        else
91646035553Spatrick        {
91746035553Spatrick            if (this->has_value())
91846035553Spatrick            {
91946035553Spatrick                __opt.__construct(_VSTD::move(this->__get()));
92046035553Spatrick                reset();
92146035553Spatrick            }
92246035553Spatrick            else
92346035553Spatrick            {
92446035553Spatrick                this->__construct(_VSTD::move(__opt.__get()));
92546035553Spatrick                __opt.reset();
92646035553Spatrick            }
92746035553Spatrick        }
92846035553Spatrick    }
92946035553Spatrick
93046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
93146035553Spatrick    constexpr
93246035553Spatrick    add_pointer_t<value_type const>
93346035553Spatrick    operator->() const
93446035553Spatrick    {
93576d0caaeSpatrick        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
93646035553Spatrick        return _VSTD::addressof(this->__get());
93746035553Spatrick    }
93846035553Spatrick
93946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
94046035553Spatrick    constexpr
94146035553Spatrick    add_pointer_t<value_type>
94246035553Spatrick    operator->()
94346035553Spatrick    {
94476d0caaeSpatrick        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
94546035553Spatrick        return _VSTD::addressof(this->__get());
94646035553Spatrick    }
94746035553Spatrick
94846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
94946035553Spatrick    constexpr
95046035553Spatrick    const value_type&
95176d0caaeSpatrick    operator*() const& noexcept
95246035553Spatrick    {
95376d0caaeSpatrick        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
95446035553Spatrick        return this->__get();
95546035553Spatrick    }
95646035553Spatrick
95746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
95846035553Spatrick    constexpr
95946035553Spatrick    value_type&
96076d0caaeSpatrick    operator*() & noexcept
96146035553Spatrick    {
96276d0caaeSpatrick        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
96346035553Spatrick        return this->__get();
96446035553Spatrick    }
96546035553Spatrick
96646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
96746035553Spatrick    constexpr
96846035553Spatrick    value_type&&
96976d0caaeSpatrick    operator*() && noexcept
97046035553Spatrick    {
97176d0caaeSpatrick        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
97246035553Spatrick        return _VSTD::move(this->__get());
97346035553Spatrick    }
97446035553Spatrick
97546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
97646035553Spatrick    constexpr
97746035553Spatrick    const value_type&&
97876d0caaeSpatrick    operator*() const&& noexcept
97946035553Spatrick    {
98076d0caaeSpatrick        _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
98146035553Spatrick        return _VSTD::move(this->__get());
98246035553Spatrick    }
98346035553Spatrick
98446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
98546035553Spatrick    constexpr explicit operator bool() const noexcept { return has_value(); }
98646035553Spatrick
98746035553Spatrick    using __base::has_value;
98846035553Spatrick    using __base::__get;
98946035553Spatrick
99046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
99146035553Spatrick    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
99246035553Spatrick    constexpr value_type const& value() const&
99346035553Spatrick    {
99446035553Spatrick        if (!this->has_value())
99546035553Spatrick            __throw_bad_optional_access();
99646035553Spatrick        return this->__get();
99746035553Spatrick    }
99846035553Spatrick
99946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
100046035553Spatrick    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
100146035553Spatrick    constexpr value_type& value() &
100246035553Spatrick    {
100346035553Spatrick        if (!this->has_value())
100446035553Spatrick            __throw_bad_optional_access();
100546035553Spatrick        return this->__get();
100646035553Spatrick    }
100746035553Spatrick
100846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
100946035553Spatrick    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
101046035553Spatrick    constexpr value_type&& value() &&
101146035553Spatrick    {
101246035553Spatrick        if (!this->has_value())
101346035553Spatrick            __throw_bad_optional_access();
101446035553Spatrick        return _VSTD::move(this->__get());
101546035553Spatrick    }
101646035553Spatrick
101746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
101846035553Spatrick    _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
101946035553Spatrick    constexpr value_type const&& value() const&&
102046035553Spatrick    {
102146035553Spatrick        if (!this->has_value())
102246035553Spatrick            __throw_bad_optional_access();
102346035553Spatrick        return _VSTD::move(this->__get());
102446035553Spatrick    }
102546035553Spatrick
102646035553Spatrick    template <class _Up>
102746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
102846035553Spatrick    constexpr value_type value_or(_Up&& __v) const&
102946035553Spatrick    {
103046035553Spatrick        static_assert(is_copy_constructible_v<value_type>,
103146035553Spatrick                      "optional<T>::value_or: T must be copy constructible");
103246035553Spatrick        static_assert(is_convertible_v<_Up, value_type>,
103346035553Spatrick                      "optional<T>::value_or: U must be convertible to T");
103446035553Spatrick        return this->has_value() ? this->__get() :
103546035553Spatrick                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
103646035553Spatrick    }
103746035553Spatrick
103846035553Spatrick    template <class _Up>
103946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
104046035553Spatrick    constexpr value_type value_or(_Up&& __v) &&
104146035553Spatrick    {
104246035553Spatrick        static_assert(is_move_constructible_v<value_type>,
104346035553Spatrick                      "optional<T>::value_or: T must be move constructible");
104446035553Spatrick        static_assert(is_convertible_v<_Up, value_type>,
104546035553Spatrick                      "optional<T>::value_or: U must be convertible to T");
104646035553Spatrick        return this->has_value() ? _VSTD::move(this->__get()) :
104746035553Spatrick                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
104846035553Spatrick    }
104946035553Spatrick
1050*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
1051*4bdff4beSrobert  template<class _Func>
1052*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1053*4bdff4beSrobert  constexpr auto and_then(_Func&& __f) & {
1054*4bdff4beSrobert    using _Up = invoke_result_t<_Func, value_type&>;
1055*4bdff4beSrobert    static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1056*4bdff4beSrobert                  "Result of f(value()) must be a specialization of std::optional");
1057*4bdff4beSrobert    if (*this)
1058*4bdff4beSrobert      return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1059*4bdff4beSrobert    return remove_cvref_t<_Up>();
1060*4bdff4beSrobert  }
1061*4bdff4beSrobert
1062*4bdff4beSrobert  template<class _Func>
1063*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1064*4bdff4beSrobert  constexpr auto and_then(_Func&& __f) const& {
1065*4bdff4beSrobert    using _Up = invoke_result_t<_Func, const value_type&>;
1066*4bdff4beSrobert    static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1067*4bdff4beSrobert                  "Result of f(value()) must be a specialization of std::optional");
1068*4bdff4beSrobert    if (*this)
1069*4bdff4beSrobert      return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
1070*4bdff4beSrobert    return remove_cvref_t<_Up>();
1071*4bdff4beSrobert  }
1072*4bdff4beSrobert
1073*4bdff4beSrobert  template<class _Func>
1074*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1075*4bdff4beSrobert  constexpr auto and_then(_Func&& __f) && {
1076*4bdff4beSrobert    using _Up = invoke_result_t<_Func, value_type&&>;
1077*4bdff4beSrobert    static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1078*4bdff4beSrobert                  "Result of f(std::move(value())) must be a specialization of std::optional");
1079*4bdff4beSrobert    if (*this)
1080*4bdff4beSrobert      return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1081*4bdff4beSrobert    return remove_cvref_t<_Up>();
1082*4bdff4beSrobert  }
1083*4bdff4beSrobert
1084*4bdff4beSrobert  template<class _Func>
1085*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI
1086*4bdff4beSrobert  constexpr auto and_then(_Func&& __f) const&& {
1087*4bdff4beSrobert    using _Up = invoke_result_t<_Func, const value_type&&>;
1088*4bdff4beSrobert    static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
1089*4bdff4beSrobert                  "Result of f(std::move(value())) must be a specialization of std::optional");
1090*4bdff4beSrobert    if (*this)
1091*4bdff4beSrobert      return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
1092*4bdff4beSrobert    return remove_cvref_t<_Up>();
1093*4bdff4beSrobert  }
1094*4bdff4beSrobert
1095*4bdff4beSrobert  template<class _Func>
1096*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1097*4bdff4beSrobert  constexpr auto transform(_Func&& __f) & {
1098*4bdff4beSrobert    using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
1099*4bdff4beSrobert    static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1100*4bdff4beSrobert    static_assert(!is_same_v<_Up, in_place_t>,
1101*4bdff4beSrobert                  "Result of f(value()) should not be std::in_place_t");
1102*4bdff4beSrobert    static_assert(!is_same_v<_Up, nullopt_t>,
1103*4bdff4beSrobert                  "Result of f(value()) should not be std::nullopt_t");
1104*4bdff4beSrobert    static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1105*4bdff4beSrobert    if (*this)
1106*4bdff4beSrobert      return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1107*4bdff4beSrobert    return optional<_Up>();
1108*4bdff4beSrobert  }
1109*4bdff4beSrobert
1110*4bdff4beSrobert  template<class _Func>
1111*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1112*4bdff4beSrobert  constexpr auto transform(_Func&& __f) const& {
1113*4bdff4beSrobert    using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
1114*4bdff4beSrobert    static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
1115*4bdff4beSrobert    static_assert(!is_same_v<_Up, in_place_t>,
1116*4bdff4beSrobert                  "Result of f(value()) should not be std::in_place_t");
1117*4bdff4beSrobert    static_assert(!is_same_v<_Up, nullopt_t>,
1118*4bdff4beSrobert                  "Result of f(value()) should not be std::nullopt_t");
1119*4bdff4beSrobert    static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
1120*4bdff4beSrobert    if (*this)
1121*4bdff4beSrobert      return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
1122*4bdff4beSrobert    return optional<_Up>();
1123*4bdff4beSrobert  }
1124*4bdff4beSrobert
1125*4bdff4beSrobert  template<class _Func>
1126*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1127*4bdff4beSrobert  constexpr auto transform(_Func&& __f) && {
1128*4bdff4beSrobert    using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
1129*4bdff4beSrobert    static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1130*4bdff4beSrobert    static_assert(!is_same_v<_Up, in_place_t>,
1131*4bdff4beSrobert                  "Result of f(std::move(value())) should not be std::in_place_t");
1132*4bdff4beSrobert    static_assert(!is_same_v<_Up, nullopt_t>,
1133*4bdff4beSrobert                  "Result of f(std::move(value())) should not be std::nullopt_t");
1134*4bdff4beSrobert    static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1135*4bdff4beSrobert    if (*this)
1136*4bdff4beSrobert      return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1137*4bdff4beSrobert    return optional<_Up>();
1138*4bdff4beSrobert  }
1139*4bdff4beSrobert
1140*4bdff4beSrobert  template<class _Func>
1141*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
1142*4bdff4beSrobert  constexpr auto transform(_Func&& __f) const&& {
1143*4bdff4beSrobert    using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
1144*4bdff4beSrobert    static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
1145*4bdff4beSrobert    static_assert(!is_same_v<_Up, in_place_t>,
1146*4bdff4beSrobert                  "Result of f(std::move(value())) should not be std::in_place_t");
1147*4bdff4beSrobert    static_assert(!is_same_v<_Up, nullopt_t>,
1148*4bdff4beSrobert                  "Result of f(std::move(value())) should not be std::nullopt_t");
1149*4bdff4beSrobert    static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
1150*4bdff4beSrobert    if (*this)
1151*4bdff4beSrobert      return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
1152*4bdff4beSrobert    return optional<_Up>();
1153*4bdff4beSrobert  }
1154*4bdff4beSrobert
1155*4bdff4beSrobert  template<invocable _Func>
1156*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI
1157*4bdff4beSrobert  constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> {
1158*4bdff4beSrobert    static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1159*4bdff4beSrobert                  "Result of f() should be the same type as this optional");
1160*4bdff4beSrobert    if (*this)
1161*4bdff4beSrobert      return *this;
1162*4bdff4beSrobert    return _VSTD::forward<_Func>(__f)();
1163*4bdff4beSrobert  }
1164*4bdff4beSrobert
1165*4bdff4beSrobert  template<invocable _Func>
1166*4bdff4beSrobert  _LIBCPP_HIDE_FROM_ABI
1167*4bdff4beSrobert  constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> {
1168*4bdff4beSrobert    static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
1169*4bdff4beSrobert                  "Result of f() should be the same type as this optional");
1170*4bdff4beSrobert    if (*this)
1171*4bdff4beSrobert      return _VSTD::move(*this);
1172*4bdff4beSrobert    return _VSTD::forward<_Func>(__f)();
1173*4bdff4beSrobert  }
1174*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 20
1175*4bdff4beSrobert
117646035553Spatrick    using __base::reset;
117746035553Spatrick};
117846035553Spatrick
1179*4bdff4beSrobert#if _LIBCPP_STD_VER >= 17
1180*4bdff4beSroberttemplate<class _Tp>
1181*4bdff4beSrobert    optional(_Tp) -> optional<_Tp>;
118246035553Spatrick#endif
118346035553Spatrick
118446035553Spatrick// Comparisons between optionals
118546035553Spatricktemplate <class _Tp, class _Up>
118646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1187*4bdff4beSrobertenable_if_t<
1188*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() ==
1189*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
119046035553Spatrick    bool
119146035553Spatrick>
119246035553Spatrickoperator==(const optional<_Tp>& __x, const optional<_Up>& __y)
119346035553Spatrick{
119446035553Spatrick    if (static_cast<bool>(__x) != static_cast<bool>(__y))
119546035553Spatrick        return false;
119646035553Spatrick    if (!static_cast<bool>(__x))
119746035553Spatrick        return true;
119846035553Spatrick    return *__x == *__y;
119946035553Spatrick}
120046035553Spatrick
120146035553Spatricktemplate <class _Tp, class _Up>
120246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1203*4bdff4beSrobertenable_if_t<
1204*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() !=
1205*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
120646035553Spatrick    bool
120746035553Spatrick>
120846035553Spatrickoperator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
120946035553Spatrick{
121046035553Spatrick    if (static_cast<bool>(__x) != static_cast<bool>(__y))
121146035553Spatrick        return true;
121246035553Spatrick    if (!static_cast<bool>(__x))
121346035553Spatrick        return false;
121446035553Spatrick    return *__x != *__y;
121546035553Spatrick}
121646035553Spatrick
121746035553Spatricktemplate <class _Tp, class _Up>
121846035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1219*4bdff4beSrobertenable_if_t<
1220*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() <
1221*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
122246035553Spatrick    bool
122346035553Spatrick>
122446035553Spatrickoperator<(const optional<_Tp>& __x, const optional<_Up>& __y)
122546035553Spatrick{
122646035553Spatrick    if (!static_cast<bool>(__y))
122746035553Spatrick        return false;
122846035553Spatrick    if (!static_cast<bool>(__x))
122946035553Spatrick        return true;
123046035553Spatrick    return *__x < *__y;
123146035553Spatrick}
123246035553Spatrick
123346035553Spatricktemplate <class _Tp, class _Up>
123446035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1235*4bdff4beSrobertenable_if_t<
1236*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() >
1237*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
123846035553Spatrick    bool
123946035553Spatrick>
124046035553Spatrickoperator>(const optional<_Tp>& __x, const optional<_Up>& __y)
124146035553Spatrick{
124246035553Spatrick    if (!static_cast<bool>(__x))
124346035553Spatrick        return false;
124446035553Spatrick    if (!static_cast<bool>(__y))
124546035553Spatrick        return true;
124646035553Spatrick    return *__x > *__y;
124746035553Spatrick}
124846035553Spatrick
124946035553Spatricktemplate <class _Tp, class _Up>
125046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1251*4bdff4beSrobertenable_if_t<
1252*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() <=
1253*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
125446035553Spatrick    bool
125546035553Spatrick>
125646035553Spatrickoperator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
125746035553Spatrick{
125846035553Spatrick    if (!static_cast<bool>(__x))
125946035553Spatrick        return true;
126046035553Spatrick    if (!static_cast<bool>(__y))
126146035553Spatrick        return false;
126246035553Spatrick    return *__x <= *__y;
126346035553Spatrick}
126446035553Spatrick
126546035553Spatricktemplate <class _Tp, class _Up>
126646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1267*4bdff4beSrobertenable_if_t<
1268*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() >=
1269*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
127046035553Spatrick    bool
127146035553Spatrick>
127246035553Spatrickoperator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
127346035553Spatrick{
127446035553Spatrick    if (!static_cast<bool>(__y))
127546035553Spatrick        return true;
127646035553Spatrick    if (!static_cast<bool>(__x))
127746035553Spatrick        return false;
127846035553Spatrick    return *__x >= *__y;
127946035553Spatrick}
128046035553Spatrick
128146035553Spatrick// Comparisons with nullopt
128246035553Spatricktemplate <class _Tp>
128346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
128446035553Spatrickbool
128546035553Spatrickoperator==(const optional<_Tp>& __x, nullopt_t) noexcept
128646035553Spatrick{
128746035553Spatrick    return !static_cast<bool>(__x);
128846035553Spatrick}
128946035553Spatrick
129046035553Spatricktemplate <class _Tp>
129146035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
129246035553Spatrickbool
129346035553Spatrickoperator==(nullopt_t, const optional<_Tp>& __x) noexcept
129446035553Spatrick{
129546035553Spatrick    return !static_cast<bool>(__x);
129646035553Spatrick}
129746035553Spatrick
129846035553Spatricktemplate <class _Tp>
129946035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
130046035553Spatrickbool
130146035553Spatrickoperator!=(const optional<_Tp>& __x, nullopt_t) noexcept
130246035553Spatrick{
130346035553Spatrick    return static_cast<bool>(__x);
130446035553Spatrick}
130546035553Spatrick
130646035553Spatricktemplate <class _Tp>
130746035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
130846035553Spatrickbool
130946035553Spatrickoperator!=(nullopt_t, const optional<_Tp>& __x) noexcept
131046035553Spatrick{
131146035553Spatrick    return static_cast<bool>(__x);
131246035553Spatrick}
131346035553Spatrick
131446035553Spatricktemplate <class _Tp>
131546035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
131646035553Spatrickbool
131746035553Spatrickoperator<(const optional<_Tp>&, nullopt_t) noexcept
131846035553Spatrick{
131946035553Spatrick    return false;
132046035553Spatrick}
132146035553Spatrick
132246035553Spatricktemplate <class _Tp>
132346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
132446035553Spatrickbool
132546035553Spatrickoperator<(nullopt_t, const optional<_Tp>& __x) noexcept
132646035553Spatrick{
132746035553Spatrick    return static_cast<bool>(__x);
132846035553Spatrick}
132946035553Spatrick
133046035553Spatricktemplate <class _Tp>
133146035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
133246035553Spatrickbool
133346035553Spatrickoperator<=(const optional<_Tp>& __x, nullopt_t) noexcept
133446035553Spatrick{
133546035553Spatrick    return !static_cast<bool>(__x);
133646035553Spatrick}
133746035553Spatrick
133846035553Spatricktemplate <class _Tp>
133946035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
134046035553Spatrickbool
134146035553Spatrickoperator<=(nullopt_t, const optional<_Tp>&) noexcept
134246035553Spatrick{
134346035553Spatrick    return true;
134446035553Spatrick}
134546035553Spatrick
134646035553Spatricktemplate <class _Tp>
134746035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
134846035553Spatrickbool
134946035553Spatrickoperator>(const optional<_Tp>& __x, nullopt_t) noexcept
135046035553Spatrick{
135146035553Spatrick    return static_cast<bool>(__x);
135246035553Spatrick}
135346035553Spatrick
135446035553Spatricktemplate <class _Tp>
135546035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
135646035553Spatrickbool
135746035553Spatrickoperator>(nullopt_t, const optional<_Tp>&) noexcept
135846035553Spatrick{
135946035553Spatrick    return false;
136046035553Spatrick}
136146035553Spatrick
136246035553Spatricktemplate <class _Tp>
136346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
136446035553Spatrickbool
136546035553Spatrickoperator>=(const optional<_Tp>&, nullopt_t) noexcept
136646035553Spatrick{
136746035553Spatrick    return true;
136846035553Spatrick}
136946035553Spatrick
137046035553Spatricktemplate <class _Tp>
137146035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
137246035553Spatrickbool
137346035553Spatrickoperator>=(nullopt_t, const optional<_Tp>& __x) noexcept
137446035553Spatrick{
137546035553Spatrick    return !static_cast<bool>(__x);
137646035553Spatrick}
137746035553Spatrick
137846035553Spatrick// Comparisons with T
137946035553Spatricktemplate <class _Tp, class _Up>
138046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1381*4bdff4beSrobertenable_if_t<
1382*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() ==
1383*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
138446035553Spatrick    bool
138546035553Spatrick>
138646035553Spatrickoperator==(const optional<_Tp>& __x, const _Up& __v)
138746035553Spatrick{
138846035553Spatrick    return static_cast<bool>(__x) ? *__x == __v : false;
138946035553Spatrick}
139046035553Spatrick
139146035553Spatricktemplate <class _Tp, class _Up>
139246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1393*4bdff4beSrobertenable_if_t<
1394*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() ==
1395*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
139646035553Spatrick    bool
139746035553Spatrick>
139846035553Spatrickoperator==(const _Tp& __v, const optional<_Up>& __x)
139946035553Spatrick{
140046035553Spatrick    return static_cast<bool>(__x) ? __v == *__x : false;
140146035553Spatrick}
140246035553Spatrick
140346035553Spatricktemplate <class _Tp, class _Up>
140446035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1405*4bdff4beSrobertenable_if_t<
1406*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() !=
1407*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
140846035553Spatrick    bool
140946035553Spatrick>
141046035553Spatrickoperator!=(const optional<_Tp>& __x, const _Up& __v)
141146035553Spatrick{
141246035553Spatrick    return static_cast<bool>(__x) ? *__x != __v : true;
141346035553Spatrick}
141446035553Spatrick
141546035553Spatricktemplate <class _Tp, class _Up>
141646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1417*4bdff4beSrobertenable_if_t<
1418*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() !=
1419*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
142046035553Spatrick    bool
142146035553Spatrick>
142246035553Spatrickoperator!=(const _Tp& __v, const optional<_Up>& __x)
142346035553Spatrick{
142446035553Spatrick    return static_cast<bool>(__x) ? __v != *__x : true;
142546035553Spatrick}
142646035553Spatrick
142746035553Spatricktemplate <class _Tp, class _Up>
142846035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1429*4bdff4beSrobertenable_if_t<
1430*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() <
1431*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
143246035553Spatrick    bool
143346035553Spatrick>
143446035553Spatrickoperator<(const optional<_Tp>& __x, const _Up& __v)
143546035553Spatrick{
143646035553Spatrick    return static_cast<bool>(__x) ? *__x < __v : true;
143746035553Spatrick}
143846035553Spatrick
143946035553Spatricktemplate <class _Tp, class _Up>
144046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1441*4bdff4beSrobertenable_if_t<
1442*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() <
1443*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
144446035553Spatrick    bool
144546035553Spatrick>
144646035553Spatrickoperator<(const _Tp& __v, const optional<_Up>& __x)
144746035553Spatrick{
144846035553Spatrick    return static_cast<bool>(__x) ? __v < *__x : false;
144946035553Spatrick}
145046035553Spatrick
145146035553Spatricktemplate <class _Tp, class _Up>
145246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1453*4bdff4beSrobertenable_if_t<
1454*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() <=
1455*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
145646035553Spatrick    bool
145746035553Spatrick>
145846035553Spatrickoperator<=(const optional<_Tp>& __x, const _Up& __v)
145946035553Spatrick{
146046035553Spatrick    return static_cast<bool>(__x) ? *__x <= __v : true;
146146035553Spatrick}
146246035553Spatrick
146346035553Spatricktemplate <class _Tp, class _Up>
146446035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1465*4bdff4beSrobertenable_if_t<
1466*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() <=
1467*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
146846035553Spatrick    bool
146946035553Spatrick>
147046035553Spatrickoperator<=(const _Tp& __v, const optional<_Up>& __x)
147146035553Spatrick{
147246035553Spatrick    return static_cast<bool>(__x) ? __v <= *__x : false;
147346035553Spatrick}
147446035553Spatrick
147546035553Spatricktemplate <class _Tp, class _Up>
147646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1477*4bdff4beSrobertenable_if_t<
1478*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() >
1479*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
148046035553Spatrick    bool
148146035553Spatrick>
148246035553Spatrickoperator>(const optional<_Tp>& __x, const _Up& __v)
148346035553Spatrick{
148446035553Spatrick    return static_cast<bool>(__x) ? *__x > __v : false;
148546035553Spatrick}
148646035553Spatrick
148746035553Spatricktemplate <class _Tp, class _Up>
148846035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1489*4bdff4beSrobertenable_if_t<
1490*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() >
1491*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
149246035553Spatrick    bool
149346035553Spatrick>
149446035553Spatrickoperator>(const _Tp& __v, const optional<_Up>& __x)
149546035553Spatrick{
149646035553Spatrick    return static_cast<bool>(__x) ? __v > *__x : true;
149746035553Spatrick}
149846035553Spatrick
149946035553Spatricktemplate <class _Tp, class _Up>
150046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1501*4bdff4beSrobertenable_if_t<
1502*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() >=
1503*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
150446035553Spatrick    bool
150546035553Spatrick>
150646035553Spatrickoperator>=(const optional<_Tp>& __x, const _Up& __v)
150746035553Spatrick{
150846035553Spatrick    return static_cast<bool>(__x) ? *__x >= __v : false;
150946035553Spatrick}
151046035553Spatrick
151146035553Spatricktemplate <class _Tp, class _Up>
151246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
1513*4bdff4beSrobertenable_if_t<
1514*4bdff4beSrobert    is_convertible_v<decltype(std::declval<const _Tp&>() >=
1515*4bdff4beSrobert        std::declval<const _Up&>()), bool>,
151646035553Spatrick    bool
151746035553Spatrick>
151846035553Spatrickoperator>=(const _Tp& __v, const optional<_Up>& __x)
151946035553Spatrick{
152046035553Spatrick    return static_cast<bool>(__x) ? __v >= *__x : true;
152146035553Spatrick}
152246035553Spatrick
152346035553Spatrick
152446035553Spatricktemplate <class _Tp>
1525*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1526*4bdff4beSrobertenable_if_t<
152746035553Spatrick    is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
152846035553Spatrick    void
152946035553Spatrick>
153046035553Spatrickswap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
153146035553Spatrick{
153246035553Spatrick    __x.swap(__y);
153346035553Spatrick}
153446035553Spatrick
153546035553Spatricktemplate <class _Tp>
153646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
153746035553Spatrickoptional<decay_t<_Tp>> make_optional(_Tp&& __v)
153846035553Spatrick{
153946035553Spatrick    return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
154046035553Spatrick}
154146035553Spatrick
154246035553Spatricktemplate <class _Tp, class... _Args>
154346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
154446035553Spatrickoptional<_Tp> make_optional(_Args&&... __args)
154546035553Spatrick{
154646035553Spatrick    return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
154746035553Spatrick}
154846035553Spatrick
154946035553Spatricktemplate <class _Tp, class _Up, class... _Args>
155046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr
155146035553Spatrickoptional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
155246035553Spatrick{
155346035553Spatrick    return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
155446035553Spatrick}
155546035553Spatrick
155646035553Spatricktemplate <class _Tp>
155746035553Spatrickstruct _LIBCPP_TEMPLATE_VIS hash<
155846035553Spatrick    __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
155946035553Spatrick>
156046035553Spatrick{
156176d0caaeSpatrick#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
156276d0caaeSpatrick    _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
156376d0caaeSpatrick    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t        result_type;
156476d0caaeSpatrick#endif
156546035553Spatrick
156646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
156776d0caaeSpatrick    size_t operator()(const optional<_Tp>& __opt) const
156846035553Spatrick    {
156946035553Spatrick        return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
157046035553Spatrick    }
157146035553Spatrick};
157246035553Spatrick
157346035553Spatrick_LIBCPP_END_NAMESPACE_STD
157446035553Spatrick
157546035553Spatrick#endif // _LIBCPP_STD_VER > 14
157646035553Spatrick
1577*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1578*4bdff4beSrobert#  include <atomic>
1579*4bdff4beSrobert#  include <climits>
1580*4bdff4beSrobert#  include <concepts>
1581*4bdff4beSrobert#  include <ctime>
1582*4bdff4beSrobert#  include <iterator>
1583*4bdff4beSrobert#  include <memory>
1584*4bdff4beSrobert#  include <ratio>
1585*4bdff4beSrobert#  include <tuple>
1586*4bdff4beSrobert#  include <typeinfo>
1587*4bdff4beSrobert#  include <utility>
1588*4bdff4beSrobert#  include <variant>
1589*4bdff4beSrobert#endif
159046035553Spatrick
159146035553Spatrick#endif // _LIBCPP_OPTIONAL
1592