xref: /minix3/external/bsd/libc++/dist/libcxx/include/experimental/optional (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
14684ddb6SLionel Sambuc// -*- C++ -*-
24684ddb6SLionel Sambuc//===-------------------------- optional ----------------------------------===//
34684ddb6SLionel Sambuc//
44684ddb6SLionel Sambuc//                     The LLVM Compiler Infrastructure
54684ddb6SLionel Sambuc//
64684ddb6SLionel Sambuc// This file is dual licensed under the MIT and the University of Illinois Open
74684ddb6SLionel Sambuc// Source Licenses. See LICENSE.TXT for details.
84684ddb6SLionel Sambuc//
94684ddb6SLionel Sambuc//===----------------------------------------------------------------------===//
104684ddb6SLionel Sambuc
114684ddb6SLionel Sambuc#ifndef _LIBCPP_OPTIONAL
124684ddb6SLionel Sambuc#define _LIBCPP_OPTIONAL
134684ddb6SLionel Sambuc
144684ddb6SLionel Sambuc/*
154684ddb6SLionel Sambuc    optional synopsis
164684ddb6SLionel Sambuc
174684ddb6SLionel Sambuc// C++1y
184684ddb6SLionel Sambuc
19*0a6a1f1dSLionel Sambucnamespace std { namespace experimental { inline namespace fundamentals_v1 {
204684ddb6SLionel Sambuc
21*0a6a1f1dSLionel Sambuc    // 5.3, optional for object types
22*0a6a1f1dSLionel Sambuc    template <class T> class optional;
234684ddb6SLionel Sambuc
24*0a6a1f1dSLionel Sambuc    // 5.4, In-place construction
25*0a6a1f1dSLionel Sambuc    struct in_place_t{};
26*0a6a1f1dSLionel Sambuc    constexpr in_place_t in_place{};
27*0a6a1f1dSLionel Sambuc
28*0a6a1f1dSLionel Sambuc    // 5.5, No-value state indicator
29*0a6a1f1dSLionel Sambuc    struct nullopt_t{see below};
30*0a6a1f1dSLionel Sambuc    constexpr nullopt_t nullopt(unspecified);
31*0a6a1f1dSLionel Sambuc
32*0a6a1f1dSLionel Sambuc    // 5.6, Class bad_optional_access
33*0a6a1f1dSLionel Sambuc    class bad_optional_access;
34*0a6a1f1dSLionel Sambuc
35*0a6a1f1dSLionel Sambuc    // 5.7, Relational operators
36*0a6a1f1dSLionel Sambuc    template <class T>
37*0a6a1f1dSLionel Sambuc      constexpr bool operator==(const optional<T>&, const optional<T>&);
38*0a6a1f1dSLionel Sambuc    template <class T>
39*0a6a1f1dSLionel Sambuc      constexpr bool operator!=(const optional<T>&, const optional<T>&);
40*0a6a1f1dSLionel Sambuc    template <class T>
41*0a6a1f1dSLionel Sambuc      constexpr bool operator<(const optional<T>&, const optional<T>&);
42*0a6a1f1dSLionel Sambuc    template <class T>
43*0a6a1f1dSLionel Sambuc      constexpr bool operator>(const optional<T>&, const optional<T>&);
44*0a6a1f1dSLionel Sambuc    template <class T>
45*0a6a1f1dSLionel Sambuc      constexpr bool operator<=(const optional<T>&, const optional<T>&);
46*0a6a1f1dSLionel Sambuc    template <class T>
47*0a6a1f1dSLionel Sambuc      constexpr bool operator>=(const optional<T>&, const optional<T>&);
48*0a6a1f1dSLionel Sambuc
49*0a6a1f1dSLionel Sambuc    // 5.8, Comparison with nullopt
50*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
51*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
52*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
53*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
54*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
55*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
56*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
57*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
58*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
59*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
60*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
61*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
62*0a6a1f1dSLionel Sambuc
63*0a6a1f1dSLionel Sambuc    // 5.9, Comparison with T
64*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator==(const optional<T>&, const T&);
65*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator==(const T&, const optional<T>&);
66*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator!=(const optional<T>&, const T&);
67*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator!=(const T&, const optional<T>&);
68*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<(const optional<T>&, const T&);
69*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<(const T&, const optional<T>&);
70*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<=(const optional<T>&, const T&);
71*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator<=(const T&, const optional<T>&);
72*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>(const optional<T>&, const T&);
73*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>(const T&, const optional<T>&);
74*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>=(const optional<T>&, const T&);
75*0a6a1f1dSLionel Sambuc    template <class T> constexpr bool operator>=(const T&, const optional<T>&);
76*0a6a1f1dSLionel Sambuc
77*0a6a1f1dSLionel Sambuc    // 5.10, Specialized algorithms
78*0a6a1f1dSLionel Sambuc    template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
79*0a6a1f1dSLionel Sambuc    template <class T> constexpr optional<see below> make_optional(T&&);
80*0a6a1f1dSLionel Sambuc
814684ddb6SLionel Sambuc	template <class T>
824684ddb6SLionel Sambuc	class optional
834684ddb6SLionel Sambuc	{
844684ddb6SLionel Sambuc	public:
854684ddb6SLionel Sambuc	  typedef T value_type;
864684ddb6SLionel Sambuc
87*0a6a1f1dSLionel Sambuc	  // 5.3.1, Constructors
884684ddb6SLionel Sambuc	  constexpr optional() noexcept;
894684ddb6SLionel Sambuc	  constexpr optional(nullopt_t) noexcept;
904684ddb6SLionel Sambuc	  optional(const optional&);
91*0a6a1f1dSLionel Sambuc	  optional(optional&&) noexcept(see below);
924684ddb6SLionel Sambuc	  constexpr optional(const T&);
934684ddb6SLionel Sambuc	  constexpr optional(T&&);
944684ddb6SLionel Sambuc	  template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
954684ddb6SLionel Sambuc	  template <class U, class... Args>
964684ddb6SLionel Sambuc		constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
974684ddb6SLionel Sambuc
98*0a6a1f1dSLionel Sambuc	  // 5.3.2, Destructor
994684ddb6SLionel Sambuc	  ~optional();
1004684ddb6SLionel Sambuc
101*0a6a1f1dSLionel Sambuc	  // 5.3.3, Assignment
1024684ddb6SLionel Sambuc	  optional& operator=(nullopt_t) noexcept;
1034684ddb6SLionel Sambuc	  optional& operator=(const optional&);
104*0a6a1f1dSLionel Sambuc	  optional& operator=(optional&&) noexcept(see below);
1054684ddb6SLionel Sambuc	  template <class U> optional& operator=(U&&);
1064684ddb6SLionel Sambuc	  template <class... Args> void emplace(Args&&...);
107*0a6a1f1dSLionel Sambuc	  template <class U, class... Args>
108*0a6a1f1dSLionel Sambuc		void emplace(initializer_list<U>, Args&&...);
1094684ddb6SLionel Sambuc
110*0a6a1f1dSLionel Sambuc	  // 5.3.4, Swap
111*0a6a1f1dSLionel Sambuc	  void swap(optional&) noexcept(see below);
1124684ddb6SLionel Sambuc
113*0a6a1f1dSLionel Sambuc	  // 5.3.5, Observers
1144684ddb6SLionel Sambuc	  constexpr T const* operator ->() const;
115*0a6a1f1dSLionel Sambuc	  constexpr T* operator ->();
116*0a6a1f1dSLionel Sambuc	  constexpr T const& operator *() const &;
117*0a6a1f1dSLionel Sambuc	  constexpr T& operator *() &;
118*0a6a1f1dSLionel Sambuc	  constexpr T&& operator *() &&;
119*0a6a1f1dSLionel Sambuc	  constexpr const T&& operator *() const &&;
1204684ddb6SLionel Sambuc	  constexpr explicit operator bool() const noexcept;
121*0a6a1f1dSLionel Sambuc	  constexpr T const& value() const &;
122*0a6a1f1dSLionel Sambuc	  constexpr T& value() &;
123*0a6a1f1dSLionel Sambuc	  constexpr T&& value() &&;
124*0a6a1f1dSLionel Sambuc	  constexpr const T&& value() const &&;
1254684ddb6SLionel Sambuc	  template <class U> constexpr T value_or(U&&) const &;
126*0a6a1f1dSLionel Sambuc	  template <class U> constexpr T value_or(U&&) &&;
127*0a6a1f1dSLionel Sambuc
128*0a6a1f1dSLionel Sambuc	private:
129*0a6a1f1dSLionel Sambuc	  T*   val;  // exposition only
1304684ddb6SLionel Sambuc	};
1314684ddb6SLionel Sambuc
132*0a6a1f1dSLionel Sambuc  } // namespace fundamentals_v1
133*0a6a1f1dSLionel Sambuc  } // namespace experimental
1344684ddb6SLionel Sambuc
135*0a6a1f1dSLionel Sambuc  // 5.11, Hash support
1364684ddb6SLionel Sambuc  template <class T> struct hash;
137*0a6a1f1dSLionel Sambuc  template <class T> struct hash<experimental::optional<T>>;
1384684ddb6SLionel Sambuc
139*0a6a1f1dSLionel Sambuc} // namespace std
1404684ddb6SLionel Sambuc
1414684ddb6SLionel Sambuc*/
1424684ddb6SLionel Sambuc
143*0a6a1f1dSLionel Sambuc#include <experimental/__config>
1444684ddb6SLionel Sambuc#include <functional>
1454684ddb6SLionel Sambuc#include <stdexcept>
1464684ddb6SLionel Sambuc
147*0a6a1f1dSLionel Sambuc_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
1484684ddb6SLionel Sambucclass _LIBCPP_EXCEPTION_ABI bad_optional_access
149*0a6a1f1dSLionel Sambuc    : public std::logic_error
1504684ddb6SLionel Sambuc{
1514684ddb6SLionel Sambucpublic:
152*0a6a1f1dSLionel Sambuc	bad_optional_access() : std::logic_error("Bad optional Access") {}
153*0a6a1f1dSLionel Sambuc
154*0a6a1f1dSLionel Sambuc//	Get the key function ~bad_optional_access() into the dylib
1554684ddb6SLionel Sambuc    virtual ~bad_optional_access() _NOEXCEPT;
1564684ddb6SLionel Sambuc};
1574684ddb6SLionel Sambuc
158*0a6a1f1dSLionel Sambuc_LIBCPP_END_NAMESPACE_EXPERIMENTAL
159*0a6a1f1dSLionel Sambuc
1604684ddb6SLionel Sambuc
1614684ddb6SLionel Sambuc#if _LIBCPP_STD_VER > 11
1624684ddb6SLionel Sambuc
1634684ddb6SLionel Sambuc#include <initializer_list>
1644684ddb6SLionel Sambuc#include <type_traits>
1654684ddb6SLionel Sambuc#include <new>
1664684ddb6SLionel Sambuc#include <__functional_base>
1674684ddb6SLionel Sambuc#include <__undef_min_max>
1684684ddb6SLionel Sambuc#include <__debug>
1694684ddb6SLionel Sambuc
1704684ddb6SLionel Sambuc#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1714684ddb6SLionel Sambuc#pragma GCC system_header
1724684ddb6SLionel Sambuc#endif
1734684ddb6SLionel Sambuc
174*0a6a1f1dSLionel Sambuc_LIBCPP_BEGIN_NAMESPACE_LFTS
1754684ddb6SLionel Sambuc
1764684ddb6SLionel Sambucstruct in_place_t {};
1774684ddb6SLionel Sambucconstexpr in_place_t in_place{};
1784684ddb6SLionel Sambuc
1794684ddb6SLionel Sambucstruct nullopt_t
1804684ddb6SLionel Sambuc{
1814684ddb6SLionel Sambuc    explicit constexpr nullopt_t(int) noexcept {}
1824684ddb6SLionel Sambuc};
1834684ddb6SLionel Sambuc
1844684ddb6SLionel Sambucconstexpr nullopt_t nullopt{0};
1854684ddb6SLionel Sambuc
1864684ddb6SLionel Sambuctemplate <class _Tp, bool = is_trivially_destructible<_Tp>::value>
1874684ddb6SLionel Sambucclass __optional_storage
1884684ddb6SLionel Sambuc{
1894684ddb6SLionel Sambucprotected:
1904684ddb6SLionel Sambuc    typedef _Tp value_type;
1914684ddb6SLionel Sambuc    union
1924684ddb6SLionel Sambuc    {
1934684ddb6SLionel Sambuc        char __null_state_;
1944684ddb6SLionel Sambuc        value_type __val_;
1954684ddb6SLionel Sambuc    };
1964684ddb6SLionel Sambuc    bool __engaged_ = false;
1974684ddb6SLionel Sambuc
1984684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
1994684ddb6SLionel Sambuc    ~__optional_storage()
2004684ddb6SLionel Sambuc    {
2014684ddb6SLionel Sambuc        if (__engaged_)
2024684ddb6SLionel Sambuc            __val_.~value_type();
2034684ddb6SLionel Sambuc    }
2044684ddb6SLionel Sambuc
2054684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2064684ddb6SLionel Sambuc    constexpr __optional_storage() noexcept
2074684ddb6SLionel Sambuc        :  __null_state_('\0') {}
2084684ddb6SLionel Sambuc
2094684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2104684ddb6SLionel Sambuc    __optional_storage(const __optional_storage& __x)
2114684ddb6SLionel Sambuc        :  __engaged_(__x.__engaged_)
2124684ddb6SLionel Sambuc        {
2134684ddb6SLionel Sambuc            if (__engaged_)
2144684ddb6SLionel Sambuc                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
2154684ddb6SLionel Sambuc        }
2164684ddb6SLionel Sambuc
2174684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2184684ddb6SLionel Sambuc    __optional_storage(__optional_storage&& __x)
2194684ddb6SLionel Sambuc                      noexcept(is_nothrow_move_constructible<value_type>::value)
2204684ddb6SLionel Sambuc        :  __engaged_(__x.__engaged_)
2214684ddb6SLionel Sambuc        {
2224684ddb6SLionel Sambuc            if (__engaged_)
2234684ddb6SLionel Sambuc                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
2244684ddb6SLionel Sambuc        }
2254684ddb6SLionel Sambuc
2264684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2274684ddb6SLionel Sambuc    constexpr __optional_storage(const value_type& __v)
2284684ddb6SLionel Sambuc        :  __val_(__v),
2294684ddb6SLionel Sambuc           __engaged_(true) {}
2304684ddb6SLionel Sambuc
2314684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2324684ddb6SLionel Sambuc    constexpr __optional_storage(value_type&& __v)
2334684ddb6SLionel Sambuc        :  __val_(_VSTD::move(__v)),
2344684ddb6SLionel Sambuc           __engaged_(true) {}
2354684ddb6SLionel Sambuc
2364684ddb6SLionel Sambuc    template <class... _Args>
2374684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2384684ddb6SLionel Sambuc    constexpr
2394684ddb6SLionel Sambuc    explicit __optional_storage(in_place_t, _Args&&... __args)
2404684ddb6SLionel Sambuc       :  __val_(_VSTD::forward<_Args>(__args)...),
2414684ddb6SLionel Sambuc           __engaged_(true) {}
2424684ddb6SLionel Sambuc};
2434684ddb6SLionel Sambuc
2444684ddb6SLionel Sambuctemplate <class _Tp>
2454684ddb6SLionel Sambucclass __optional_storage<_Tp, true>
2464684ddb6SLionel Sambuc{
2474684ddb6SLionel Sambucprotected:
2484684ddb6SLionel Sambuc    typedef _Tp value_type;
2494684ddb6SLionel Sambuc    union
2504684ddb6SLionel Sambuc    {
2514684ddb6SLionel Sambuc        char __null_state_;
2524684ddb6SLionel Sambuc        value_type __val_;
2534684ddb6SLionel Sambuc    };
2544684ddb6SLionel Sambuc    bool __engaged_ = false;
2554684ddb6SLionel Sambuc
2564684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2574684ddb6SLionel Sambuc    constexpr __optional_storage() noexcept
2584684ddb6SLionel Sambuc        :  __null_state_('\0') {}
2594684ddb6SLionel Sambuc
2604684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2614684ddb6SLionel Sambuc    __optional_storage(const __optional_storage& __x)
2624684ddb6SLionel Sambuc        :  __engaged_(__x.__engaged_)
2634684ddb6SLionel Sambuc        {
2644684ddb6SLionel Sambuc            if (__engaged_)
2654684ddb6SLionel Sambuc                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
2664684ddb6SLionel Sambuc        }
2674684ddb6SLionel Sambuc
2684684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2694684ddb6SLionel Sambuc    __optional_storage(__optional_storage&& __x)
2704684ddb6SLionel Sambuc                      noexcept(is_nothrow_move_constructible<value_type>::value)
2714684ddb6SLionel Sambuc        :  __engaged_(__x.__engaged_)
2724684ddb6SLionel Sambuc        {
2734684ddb6SLionel Sambuc            if (__engaged_)
2744684ddb6SLionel Sambuc                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
2754684ddb6SLionel Sambuc        }
2764684ddb6SLionel Sambuc
2774684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2784684ddb6SLionel Sambuc    constexpr __optional_storage(const value_type& __v)
2794684ddb6SLionel Sambuc        :  __val_(__v),
2804684ddb6SLionel Sambuc           __engaged_(true) {}
2814684ddb6SLionel Sambuc
2824684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2834684ddb6SLionel Sambuc    constexpr __optional_storage(value_type&& __v)
2844684ddb6SLionel Sambuc        :  __val_(_VSTD::move(__v)),
2854684ddb6SLionel Sambuc           __engaged_(true) {}
2864684ddb6SLionel Sambuc
2874684ddb6SLionel Sambuc    template <class... _Args>
2884684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
2894684ddb6SLionel Sambuc    constexpr
2904684ddb6SLionel Sambuc    explicit __optional_storage(in_place_t, _Args&&... __args)
2914684ddb6SLionel Sambuc       :  __val_(_VSTD::forward<_Args>(__args)...),
2924684ddb6SLionel Sambuc           __engaged_(true) {}
2934684ddb6SLionel Sambuc};
2944684ddb6SLionel Sambuc
2954684ddb6SLionel Sambuctemplate <class _Tp>
2964684ddb6SLionel Sambucclass optional
2974684ddb6SLionel Sambuc    : private __optional_storage<_Tp>
2984684ddb6SLionel Sambuc{
2994684ddb6SLionel Sambuc    typedef __optional_storage<_Tp> __base;
3004684ddb6SLionel Sambucpublic:
3014684ddb6SLionel Sambuc    typedef _Tp value_type;
3024684ddb6SLionel Sambuc
3034684ddb6SLionel Sambuc    static_assert(!is_reference<value_type>::value,
3044684ddb6SLionel Sambuc              "Instantiation of optional with a reference type is ill-formed.");
3054684ddb6SLionel Sambuc    static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
3064684ddb6SLionel Sambuc              "Instantiation of optional with a in_place_t type is ill-formed.");
3074684ddb6SLionel Sambuc    static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
3084684ddb6SLionel Sambuc              "Instantiation of optional with a nullopt_t type is ill-formed.");
3094684ddb6SLionel Sambuc    static_assert(is_object<value_type>::value,
3104684ddb6SLionel Sambuc        "Instantiation of optional with a non-object type is undefined behavior.");
3114684ddb6SLionel Sambuc    static_assert(is_nothrow_destructible<value_type>::value,
3124684ddb6SLionel Sambuc        "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
3134684ddb6SLionel Sambuc
3144684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
3154684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
3164684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
3174684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY ~optional() = default;
3184684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
3194684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
3204684ddb6SLionel Sambuc        : __base(__v) {}
3214684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
3224684ddb6SLionel Sambuc        : __base(_VSTD::move(__v)) {}
3234684ddb6SLionel Sambuc
3244684ddb6SLionel Sambuc    template <class... _Args,
3254684ddb6SLionel Sambuc              class = typename enable_if
3264684ddb6SLionel Sambuc                      <
3274684ddb6SLionel Sambuc                           is_constructible<value_type, _Args...>::value
3284684ddb6SLionel Sambuc                      >::type
3294684ddb6SLionel Sambuc             >
3304684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
3314684ddb6SLionel Sambuc    constexpr
3324684ddb6SLionel Sambuc    explicit optional(in_place_t, _Args&&... __args)
3334684ddb6SLionel Sambuc        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
3344684ddb6SLionel Sambuc
3354684ddb6SLionel Sambuc    template <class _Up, class... _Args,
3364684ddb6SLionel Sambuc              class = typename enable_if
3374684ddb6SLionel Sambuc                      <
3384684ddb6SLionel Sambuc                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
3394684ddb6SLionel Sambuc                      >::type
3404684ddb6SLionel Sambuc             >
3414684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
3424684ddb6SLionel Sambuc    constexpr
3434684ddb6SLionel Sambuc    explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
3444684ddb6SLionel Sambuc        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
3454684ddb6SLionel Sambuc
3464684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
3474684ddb6SLionel Sambuc    optional& operator=(nullopt_t) noexcept
3484684ddb6SLionel Sambuc    {
3494684ddb6SLionel Sambuc        if (this->__engaged_)
3504684ddb6SLionel Sambuc        {
3514684ddb6SLionel Sambuc            this->__val_.~value_type();
3524684ddb6SLionel Sambuc            this->__engaged_ = false;
3534684ddb6SLionel Sambuc        }
3544684ddb6SLionel Sambuc        return *this;
3554684ddb6SLionel Sambuc    }
3564684ddb6SLionel Sambuc
3574684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
3584684ddb6SLionel Sambuc    optional&
3594684ddb6SLionel Sambuc    operator=(const optional& __opt)
3604684ddb6SLionel Sambuc    {
3614684ddb6SLionel Sambuc        if (this->__engaged_ == __opt.__engaged_)
3624684ddb6SLionel Sambuc        {
3634684ddb6SLionel Sambuc            if (this->__engaged_)
3644684ddb6SLionel Sambuc                this->__val_ = __opt.__val_;
3654684ddb6SLionel Sambuc        }
3664684ddb6SLionel Sambuc        else
3674684ddb6SLionel Sambuc        {
3684684ddb6SLionel Sambuc            if (this->__engaged_)
3694684ddb6SLionel Sambuc                this->__val_.~value_type();
3704684ddb6SLionel Sambuc            else
3714684ddb6SLionel Sambuc                ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
3724684ddb6SLionel Sambuc            this->__engaged_ = __opt.__engaged_;
3734684ddb6SLionel Sambuc        }
3744684ddb6SLionel Sambuc        return *this;
3754684ddb6SLionel Sambuc    }
3764684ddb6SLionel Sambuc
3774684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
3784684ddb6SLionel Sambuc    optional&
3794684ddb6SLionel Sambuc    operator=(optional&& __opt)
3804684ddb6SLionel Sambuc        noexcept(is_nothrow_move_assignable<value_type>::value &&
3814684ddb6SLionel Sambuc                 is_nothrow_move_constructible<value_type>::value)
3824684ddb6SLionel Sambuc    {
3834684ddb6SLionel Sambuc        if (this->__engaged_ == __opt.__engaged_)
3844684ddb6SLionel Sambuc        {
3854684ddb6SLionel Sambuc            if (this->__engaged_)
3864684ddb6SLionel Sambuc                this->__val_ = _VSTD::move(__opt.__val_);
3874684ddb6SLionel Sambuc        }
3884684ddb6SLionel Sambuc        else
3894684ddb6SLionel Sambuc        {
3904684ddb6SLionel Sambuc            if (this->__engaged_)
3914684ddb6SLionel Sambuc                this->__val_.~value_type();
3924684ddb6SLionel Sambuc            else
3934684ddb6SLionel Sambuc                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
3944684ddb6SLionel Sambuc            this->__engaged_ = __opt.__engaged_;
3954684ddb6SLionel Sambuc        }
3964684ddb6SLionel Sambuc        return *this;
3974684ddb6SLionel Sambuc    }
3984684ddb6SLionel Sambuc
3994684ddb6SLionel Sambuc    template <class _Up,
4004684ddb6SLionel Sambuc              class = typename enable_if
4014684ddb6SLionel Sambuc                      <
4024684ddb6SLionel Sambuc                          is_same<typename remove_reference<_Up>::type, value_type>::value &&
4034684ddb6SLionel Sambuc                          is_constructible<value_type, _Up>::value &&
4044684ddb6SLionel Sambuc                          is_assignable<value_type&, _Up>::value
4054684ddb6SLionel Sambuc                      >::type
4064684ddb6SLionel Sambuc             >
4074684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4084684ddb6SLionel Sambuc    optional&
4094684ddb6SLionel Sambuc    operator=(_Up&& __v)
4104684ddb6SLionel Sambuc    {
4114684ddb6SLionel Sambuc        if (this->__engaged_)
4124684ddb6SLionel Sambuc            this->__val_ = _VSTD::forward<_Up>(__v);
4134684ddb6SLionel Sambuc        else
4144684ddb6SLionel Sambuc        {
4154684ddb6SLionel Sambuc            ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
4164684ddb6SLionel Sambuc            this->__engaged_ = true;
4174684ddb6SLionel Sambuc        }
4184684ddb6SLionel Sambuc        return *this;
4194684ddb6SLionel Sambuc    }
4204684ddb6SLionel Sambuc
4214684ddb6SLionel Sambuc    template <class... _Args,
4224684ddb6SLionel Sambuc              class = typename enable_if
4234684ddb6SLionel Sambuc                      <
4244684ddb6SLionel Sambuc                          is_constructible<value_type, _Args...>::value
4254684ddb6SLionel Sambuc                      >::type
4264684ddb6SLionel Sambuc             >
4274684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4284684ddb6SLionel Sambuc    void
4294684ddb6SLionel Sambuc    emplace(_Args&&... __args)
4304684ddb6SLionel Sambuc    {
4314684ddb6SLionel Sambuc        *this = nullopt;
4324684ddb6SLionel Sambuc        ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
4334684ddb6SLionel Sambuc        this->__engaged_ = true;
4344684ddb6SLionel Sambuc    }
4354684ddb6SLionel Sambuc
4364684ddb6SLionel Sambuc    template <class _Up, class... _Args,
4374684ddb6SLionel Sambuc              class = typename enable_if
4384684ddb6SLionel Sambuc                      <
4394684ddb6SLionel Sambuc                          is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
4404684ddb6SLionel Sambuc                      >::type
4414684ddb6SLionel Sambuc             >
4424684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4434684ddb6SLionel Sambuc    void
4444684ddb6SLionel Sambuc    emplace(initializer_list<_Up> __il, _Args&&... __args)
4454684ddb6SLionel Sambuc    {
4464684ddb6SLionel Sambuc        *this = nullopt;
4474684ddb6SLionel Sambuc        ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
4484684ddb6SLionel Sambuc        this->__engaged_ = true;
4494684ddb6SLionel Sambuc    }
4504684ddb6SLionel Sambuc
4514684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4524684ddb6SLionel Sambuc    void
4534684ddb6SLionel Sambuc    swap(optional& __opt)
4544684ddb6SLionel Sambuc        noexcept(is_nothrow_move_constructible<value_type>::value &&
4554684ddb6SLionel Sambuc                 __is_nothrow_swappable<value_type>::value)
4564684ddb6SLionel Sambuc    {
4574684ddb6SLionel Sambuc        using _VSTD::swap;
4584684ddb6SLionel Sambuc        if (this->__engaged_ == __opt.__engaged_)
4594684ddb6SLionel Sambuc        {
4604684ddb6SLionel Sambuc            if (this->__engaged_)
4614684ddb6SLionel Sambuc                swap(this->__val_, __opt.__val_);
4624684ddb6SLionel Sambuc        }
4634684ddb6SLionel Sambuc        else
4644684ddb6SLionel Sambuc        {
4654684ddb6SLionel Sambuc            if (this->__engaged_)
4664684ddb6SLionel Sambuc            {
4674684ddb6SLionel Sambuc                ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
4684684ddb6SLionel Sambuc                this->__val_.~value_type();
4694684ddb6SLionel Sambuc            }
4704684ddb6SLionel Sambuc            else
4714684ddb6SLionel Sambuc            {
4724684ddb6SLionel Sambuc                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
4734684ddb6SLionel Sambuc                __opt.__val_.~value_type();
4744684ddb6SLionel Sambuc            }
4754684ddb6SLionel Sambuc            swap(this->__engaged_, __opt.__engaged_);
4764684ddb6SLionel Sambuc        }
4774684ddb6SLionel Sambuc    }
4784684ddb6SLionel Sambuc
4794684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4804684ddb6SLionel Sambuc    constexpr
4814684ddb6SLionel Sambuc    value_type const*
4824684ddb6SLionel Sambuc    operator->() const
4834684ddb6SLionel Sambuc    {
4844684ddb6SLionel Sambuc        _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
4854684ddb6SLionel Sambuc        return __operator_arrow(__has_operator_addressof<value_type>{});
4864684ddb6SLionel Sambuc    }
4874684ddb6SLionel Sambuc
4884684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4894684ddb6SLionel Sambuc    value_type*
4904684ddb6SLionel Sambuc    operator->()
4914684ddb6SLionel Sambuc    {
4924684ddb6SLionel Sambuc        _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
4934684ddb6SLionel Sambuc        return _VSTD::addressof(this->__val_);
4944684ddb6SLionel Sambuc    }
4954684ddb6SLionel Sambuc
4964684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
4974684ddb6SLionel Sambuc    constexpr
4984684ddb6SLionel Sambuc    const value_type&
4994684ddb6SLionel Sambuc    operator*() const
5004684ddb6SLionel Sambuc    {
5014684ddb6SLionel Sambuc        _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
5024684ddb6SLionel Sambuc        return this->__val_;
5034684ddb6SLionel Sambuc    }
5044684ddb6SLionel Sambuc
5054684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5064684ddb6SLionel Sambuc    value_type&
5074684ddb6SLionel Sambuc    operator*()
5084684ddb6SLionel Sambuc    {
5094684ddb6SLionel Sambuc        _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
5104684ddb6SLionel Sambuc        return this->__val_;
5114684ddb6SLionel Sambuc    }
5124684ddb6SLionel Sambuc
5134684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5144684ddb6SLionel Sambuc    constexpr explicit operator bool() const noexcept {return this->__engaged_;}
5154684ddb6SLionel Sambuc
5164684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5174684ddb6SLionel Sambuc    constexpr value_type const& value() const
5184684ddb6SLionel Sambuc    {
5194684ddb6SLionel Sambuc        if (!this->__engaged_)
520*0a6a1f1dSLionel Sambuc            throw bad_optional_access();
5214684ddb6SLionel Sambuc        return this->__val_;
5224684ddb6SLionel Sambuc    }
5234684ddb6SLionel Sambuc
5244684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5254684ddb6SLionel Sambuc    value_type& value()
5264684ddb6SLionel Sambuc    {
5274684ddb6SLionel Sambuc        if (!this->__engaged_)
528*0a6a1f1dSLionel Sambuc            throw bad_optional_access();
5294684ddb6SLionel Sambuc        return this->__val_;
5304684ddb6SLionel Sambuc    }
5314684ddb6SLionel Sambuc
5324684ddb6SLionel Sambuc    template <class _Up>
5334684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5344684ddb6SLionel Sambuc    constexpr value_type value_or(_Up&& __v) const&
5354684ddb6SLionel Sambuc    {
5364684ddb6SLionel Sambuc        static_assert(is_copy_constructible<value_type>::value,
5374684ddb6SLionel Sambuc                      "optional<T>::value_or: T must be copy constructible");
5384684ddb6SLionel Sambuc        static_assert(is_convertible<_Up, value_type>::value,
5394684ddb6SLionel Sambuc                      "optional<T>::value_or: U must be convertible to T");
5404684ddb6SLionel Sambuc        return this->__engaged_ ? this->__val_ :
5414684ddb6SLionel Sambuc                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
5424684ddb6SLionel Sambuc    }
5434684ddb6SLionel Sambuc
5444684ddb6SLionel Sambuc    template <class _Up>
5454684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5464684ddb6SLionel Sambuc    value_type value_or(_Up&& __v) &&
5474684ddb6SLionel Sambuc    {
5484684ddb6SLionel Sambuc        static_assert(is_move_constructible<value_type>::value,
5494684ddb6SLionel Sambuc                      "optional<T>::value_or: T must be move constructible");
5504684ddb6SLionel Sambuc        static_assert(is_convertible<_Up, value_type>::value,
5514684ddb6SLionel Sambuc                      "optional<T>::value_or: U must be convertible to T");
5524684ddb6SLionel Sambuc        return this->__engaged_ ? _VSTD::move(this->__val_) :
5534684ddb6SLionel Sambuc                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
5544684ddb6SLionel Sambuc    }
5554684ddb6SLionel Sambuc
5564684ddb6SLionel Sambucprivate:
5574684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5584684ddb6SLionel Sambuc    value_type const*
5594684ddb6SLionel Sambuc    __operator_arrow(true_type) const
5604684ddb6SLionel Sambuc    {
5614684ddb6SLionel Sambuc        return _VSTD::addressof(this->__val_);
5624684ddb6SLionel Sambuc    }
5634684ddb6SLionel Sambuc
5644684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
5654684ddb6SLionel Sambuc    constexpr
5664684ddb6SLionel Sambuc    value_type const*
5674684ddb6SLionel Sambuc    __operator_arrow(false_type) const
5684684ddb6SLionel Sambuc    {
5694684ddb6SLionel Sambuc        return &this->__val_;
5704684ddb6SLionel Sambuc    }
5714684ddb6SLionel Sambuc};
5724684ddb6SLionel Sambuc
573*0a6a1f1dSLionel Sambuc// Comparisons between optionals
5744684ddb6SLionel Sambuctemplate <class _Tp>
5754684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
5764684ddb6SLionel Sambucconstexpr
5774684ddb6SLionel Sambucbool
5784684ddb6SLionel Sambucoperator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
5794684ddb6SLionel Sambuc{
5804684ddb6SLionel Sambuc    if (static_cast<bool>(__x) != static_cast<bool>(__y))
5814684ddb6SLionel Sambuc        return false;
5824684ddb6SLionel Sambuc    if (!static_cast<bool>(__x))
5834684ddb6SLionel Sambuc        return true;
5844684ddb6SLionel Sambuc    return *__x == *__y;
5854684ddb6SLionel Sambuc}
5864684ddb6SLionel Sambuc
5874684ddb6SLionel Sambuctemplate <class _Tp>
5884684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
5894684ddb6SLionel Sambucconstexpr
5904684ddb6SLionel Sambucbool
591*0a6a1f1dSLionel Sambucoperator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
592*0a6a1f1dSLionel Sambuc{
593*0a6a1f1dSLionel Sambuc    return !(__x == __y);
594*0a6a1f1dSLionel Sambuc}
595*0a6a1f1dSLionel Sambuc
596*0a6a1f1dSLionel Sambuctemplate <class _Tp>
597*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
598*0a6a1f1dSLionel Sambucconstexpr
599*0a6a1f1dSLionel Sambucbool
6004684ddb6SLionel Sambucoperator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
6014684ddb6SLionel Sambuc{
6024684ddb6SLionel Sambuc    if (!static_cast<bool>(__y))
6034684ddb6SLionel Sambuc        return false;
6044684ddb6SLionel Sambuc    if (!static_cast<bool>(__x))
6054684ddb6SLionel Sambuc        return true;
606*0a6a1f1dSLionel Sambuc    return *__x < *__y;
6074684ddb6SLionel Sambuc}
6084684ddb6SLionel Sambuc
6094684ddb6SLionel Sambuctemplate <class _Tp>
6104684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
6114684ddb6SLionel Sambucconstexpr
6124684ddb6SLionel Sambucbool
613*0a6a1f1dSLionel Sambucoperator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
614*0a6a1f1dSLionel Sambuc{
615*0a6a1f1dSLionel Sambuc    return __y < __x;
616*0a6a1f1dSLionel Sambuc}
617*0a6a1f1dSLionel Sambuc
618*0a6a1f1dSLionel Sambuctemplate <class _Tp>
619*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
620*0a6a1f1dSLionel Sambucconstexpr
621*0a6a1f1dSLionel Sambucbool
622*0a6a1f1dSLionel Sambucoperator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
623*0a6a1f1dSLionel Sambuc{
624*0a6a1f1dSLionel Sambuc    return !(__y < __x);
625*0a6a1f1dSLionel Sambuc}
626*0a6a1f1dSLionel Sambuc
627*0a6a1f1dSLionel Sambuctemplate <class _Tp>
628*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
629*0a6a1f1dSLionel Sambucconstexpr
630*0a6a1f1dSLionel Sambucbool
631*0a6a1f1dSLionel Sambucoperator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
632*0a6a1f1dSLionel Sambuc{
633*0a6a1f1dSLionel Sambuc    return !(__x < __y);
634*0a6a1f1dSLionel Sambuc}
635*0a6a1f1dSLionel Sambuc
636*0a6a1f1dSLionel Sambuc
637*0a6a1f1dSLionel Sambuc// Comparisons with nullopt
638*0a6a1f1dSLionel Sambuctemplate <class _Tp>
639*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
640*0a6a1f1dSLionel Sambucconstexpr
641*0a6a1f1dSLionel Sambucbool
6424684ddb6SLionel Sambucoperator==(const optional<_Tp>& __x, nullopt_t) noexcept
6434684ddb6SLionel Sambuc{
6444684ddb6SLionel Sambuc    return !static_cast<bool>(__x);
6454684ddb6SLionel Sambuc}
6464684ddb6SLionel Sambuc
6474684ddb6SLionel Sambuctemplate <class _Tp>
6484684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
6494684ddb6SLionel Sambucconstexpr
6504684ddb6SLionel Sambucbool
6514684ddb6SLionel Sambucoperator==(nullopt_t, const optional<_Tp>& __x) noexcept
6524684ddb6SLionel Sambuc{
6534684ddb6SLionel Sambuc    return !static_cast<bool>(__x);
6544684ddb6SLionel Sambuc}
6554684ddb6SLionel Sambuc
6564684ddb6SLionel Sambuctemplate <class _Tp>
6574684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
6584684ddb6SLionel Sambucconstexpr
6594684ddb6SLionel Sambucbool
660*0a6a1f1dSLionel Sambucoperator!=(const optional<_Tp>& __x, nullopt_t) noexcept
661*0a6a1f1dSLionel Sambuc{
662*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x);
663*0a6a1f1dSLionel Sambuc}
664*0a6a1f1dSLionel Sambuc
665*0a6a1f1dSLionel Sambuctemplate <class _Tp>
666*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
667*0a6a1f1dSLionel Sambucconstexpr
668*0a6a1f1dSLionel Sambucbool
669*0a6a1f1dSLionel Sambucoperator!=(nullopt_t, const optional<_Tp>& __x) noexcept
670*0a6a1f1dSLionel Sambuc{
671*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x);
672*0a6a1f1dSLionel Sambuc}
673*0a6a1f1dSLionel Sambuc
674*0a6a1f1dSLionel Sambuctemplate <class _Tp>
675*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
676*0a6a1f1dSLionel Sambucconstexpr
677*0a6a1f1dSLionel Sambucbool
6784684ddb6SLionel Sambucoperator<(const optional<_Tp>&, nullopt_t) noexcept
6794684ddb6SLionel Sambuc{
6804684ddb6SLionel Sambuc    return false;
6814684ddb6SLionel Sambuc}
6824684ddb6SLionel Sambuc
6834684ddb6SLionel Sambuctemplate <class _Tp>
6844684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
6854684ddb6SLionel Sambucconstexpr
6864684ddb6SLionel Sambucbool
6874684ddb6SLionel Sambucoperator<(nullopt_t, const optional<_Tp>& __x) noexcept
6884684ddb6SLionel Sambuc{
6894684ddb6SLionel Sambuc    return static_cast<bool>(__x);
6904684ddb6SLionel Sambuc}
6914684ddb6SLionel Sambuc
6924684ddb6SLionel Sambuctemplate <class _Tp>
6934684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
6944684ddb6SLionel Sambucconstexpr
6954684ddb6SLionel Sambucbool
696*0a6a1f1dSLionel Sambucoperator<=(const optional<_Tp>& __x, nullopt_t) noexcept
697*0a6a1f1dSLionel Sambuc{
698*0a6a1f1dSLionel Sambuc    return !static_cast<bool>(__x);
699*0a6a1f1dSLionel Sambuc}
700*0a6a1f1dSLionel Sambuc
701*0a6a1f1dSLionel Sambuctemplate <class _Tp>
702*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
703*0a6a1f1dSLionel Sambucconstexpr
704*0a6a1f1dSLionel Sambucbool
705*0a6a1f1dSLionel Sambucoperator<=(nullopt_t, const optional<_Tp>& __x) noexcept
706*0a6a1f1dSLionel Sambuc{
707*0a6a1f1dSLionel Sambuc    return true;
708*0a6a1f1dSLionel Sambuc}
709*0a6a1f1dSLionel Sambuc
710*0a6a1f1dSLionel Sambuctemplate <class _Tp>
711*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
712*0a6a1f1dSLionel Sambucconstexpr
713*0a6a1f1dSLionel Sambucbool
714*0a6a1f1dSLionel Sambucoperator>(const optional<_Tp>& __x, nullopt_t) noexcept
715*0a6a1f1dSLionel Sambuc{
716*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x);
717*0a6a1f1dSLionel Sambuc}
718*0a6a1f1dSLionel Sambuc
719*0a6a1f1dSLionel Sambuctemplate <class _Tp>
720*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
721*0a6a1f1dSLionel Sambucconstexpr
722*0a6a1f1dSLionel Sambucbool
723*0a6a1f1dSLionel Sambucoperator>(nullopt_t, const optional<_Tp>& __x) noexcept
724*0a6a1f1dSLionel Sambuc{
725*0a6a1f1dSLionel Sambuc    return false;
726*0a6a1f1dSLionel Sambuc}
727*0a6a1f1dSLionel Sambuc
728*0a6a1f1dSLionel Sambuctemplate <class _Tp>
729*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
730*0a6a1f1dSLionel Sambucconstexpr
731*0a6a1f1dSLionel Sambucbool
732*0a6a1f1dSLionel Sambucoperator>=(const optional<_Tp>&, nullopt_t) noexcept
733*0a6a1f1dSLionel Sambuc{
734*0a6a1f1dSLionel Sambuc    return true;
735*0a6a1f1dSLionel Sambuc}
736*0a6a1f1dSLionel Sambuc
737*0a6a1f1dSLionel Sambuctemplate <class _Tp>
738*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
739*0a6a1f1dSLionel Sambucconstexpr
740*0a6a1f1dSLionel Sambucbool
741*0a6a1f1dSLionel Sambucoperator>=(nullopt_t, const optional<_Tp>& __x) noexcept
742*0a6a1f1dSLionel Sambuc{
743*0a6a1f1dSLionel Sambuc    return !static_cast<bool>(__x);
744*0a6a1f1dSLionel Sambuc}
745*0a6a1f1dSLionel Sambuc
746*0a6a1f1dSLionel Sambuc// Comparisons with T
747*0a6a1f1dSLionel Sambuctemplate <class _Tp>
748*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
749*0a6a1f1dSLionel Sambucconstexpr
750*0a6a1f1dSLionel Sambucbool
7514684ddb6SLionel Sambucoperator==(const optional<_Tp>& __x, const _Tp& __v)
7524684ddb6SLionel Sambuc{
7534684ddb6SLionel Sambuc    return static_cast<bool>(__x) ? *__x == __v : false;
7544684ddb6SLionel Sambuc}
7554684ddb6SLionel Sambuc
7564684ddb6SLionel Sambuctemplate <class _Tp>
7574684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
7584684ddb6SLionel Sambucconstexpr
7594684ddb6SLionel Sambucbool
7604684ddb6SLionel Sambucoperator==(const _Tp& __v, const optional<_Tp>& __x)
7614684ddb6SLionel Sambuc{
7624684ddb6SLionel Sambuc    return static_cast<bool>(__x) ? *__x == __v : false;
7634684ddb6SLionel Sambuc}
7644684ddb6SLionel Sambuc
7654684ddb6SLionel Sambuctemplate <class _Tp>
7664684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
7674684ddb6SLionel Sambucconstexpr
7684684ddb6SLionel Sambucbool
769*0a6a1f1dSLionel Sambucoperator!=(const optional<_Tp>& __x, const _Tp& __v)
770*0a6a1f1dSLionel Sambuc{
771*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x) ? !(*__x == __v) : true;
772*0a6a1f1dSLionel Sambuc}
773*0a6a1f1dSLionel Sambuc
774*0a6a1f1dSLionel Sambuctemplate <class _Tp>
775*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
776*0a6a1f1dSLionel Sambucconstexpr
777*0a6a1f1dSLionel Sambucbool
778*0a6a1f1dSLionel Sambucoperator!=(const _Tp& __v, const optional<_Tp>& __x)
779*0a6a1f1dSLionel Sambuc{
780*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x) ? !(*__x == __v) : true;
781*0a6a1f1dSLionel Sambuc}
782*0a6a1f1dSLionel Sambuc
783*0a6a1f1dSLionel Sambuctemplate <class _Tp>
784*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
785*0a6a1f1dSLionel Sambucconstexpr
786*0a6a1f1dSLionel Sambucbool
7874684ddb6SLionel Sambucoperator<(const optional<_Tp>& __x, const _Tp& __v)
7884684ddb6SLionel Sambuc{
7894684ddb6SLionel Sambuc    return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
7904684ddb6SLionel Sambuc}
7914684ddb6SLionel Sambuc
7924684ddb6SLionel Sambuctemplate <class _Tp>
7934684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
7944684ddb6SLionel Sambucconstexpr
7954684ddb6SLionel Sambucbool
7964684ddb6SLionel Sambucoperator<(const _Tp& __v, const optional<_Tp>& __x)
7974684ddb6SLionel Sambuc{
7984684ddb6SLionel Sambuc    return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
7994684ddb6SLionel Sambuc}
8004684ddb6SLionel Sambuc
8014684ddb6SLionel Sambuctemplate <class _Tp>
8024684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
803*0a6a1f1dSLionel Sambucconstexpr
804*0a6a1f1dSLionel Sambucbool
805*0a6a1f1dSLionel Sambucoperator<=(const optional<_Tp>& __x, const _Tp& __v)
806*0a6a1f1dSLionel Sambuc{
807*0a6a1f1dSLionel Sambuc    return !(__x > __v);
808*0a6a1f1dSLionel Sambuc}
809*0a6a1f1dSLionel Sambuc
810*0a6a1f1dSLionel Sambuctemplate <class _Tp>
811*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
812*0a6a1f1dSLionel Sambucconstexpr
813*0a6a1f1dSLionel Sambucbool
814*0a6a1f1dSLionel Sambucoperator<=(const _Tp& __v, const optional<_Tp>& __x)
815*0a6a1f1dSLionel Sambuc{
816*0a6a1f1dSLionel Sambuc    return !(__v > __x);
817*0a6a1f1dSLionel Sambuc}
818*0a6a1f1dSLionel Sambuc
819*0a6a1f1dSLionel Sambuctemplate <class _Tp>
820*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
821*0a6a1f1dSLionel Sambucconstexpr
822*0a6a1f1dSLionel Sambucbool
823*0a6a1f1dSLionel Sambucoperator>(const optional<_Tp>& __x, const _Tp& __v)
824*0a6a1f1dSLionel Sambuc{
825*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x) ? __v < __x : false;
826*0a6a1f1dSLionel Sambuc}
827*0a6a1f1dSLionel Sambuc
828*0a6a1f1dSLionel Sambuctemplate <class _Tp>
829*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
830*0a6a1f1dSLionel Sambucconstexpr
831*0a6a1f1dSLionel Sambucbool
832*0a6a1f1dSLionel Sambucoperator>(const _Tp& __v, const optional<_Tp>& __x)
833*0a6a1f1dSLionel Sambuc{
834*0a6a1f1dSLionel Sambuc    return static_cast<bool>(__x) ? __x < __v : true;
835*0a6a1f1dSLionel Sambuc}
836*0a6a1f1dSLionel Sambuc
837*0a6a1f1dSLionel Sambuctemplate <class _Tp>
838*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
839*0a6a1f1dSLionel Sambucconstexpr
840*0a6a1f1dSLionel Sambucbool
841*0a6a1f1dSLionel Sambucoperator>=(const optional<_Tp>& __x, const _Tp& __v)
842*0a6a1f1dSLionel Sambuc{
843*0a6a1f1dSLionel Sambuc    return !(__x < __v);
844*0a6a1f1dSLionel Sambuc}
845*0a6a1f1dSLionel Sambuc
846*0a6a1f1dSLionel Sambuctemplate <class _Tp>
847*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
848*0a6a1f1dSLionel Sambucconstexpr
849*0a6a1f1dSLionel Sambucbool
850*0a6a1f1dSLionel Sambucoperator>=(const _Tp& __v, const optional<_Tp>& __x)
851*0a6a1f1dSLionel Sambuc{
852*0a6a1f1dSLionel Sambuc    return !(__v < __x);
853*0a6a1f1dSLionel Sambuc}
854*0a6a1f1dSLionel Sambuc
855*0a6a1f1dSLionel Sambuc
856*0a6a1f1dSLionel Sambuctemplate <class _Tp>
857*0a6a1f1dSLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
8584684ddb6SLionel Sambucvoid
8594684ddb6SLionel Sambucswap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
8604684ddb6SLionel Sambuc{
8614684ddb6SLionel Sambuc    __x.swap(__y);
8624684ddb6SLionel Sambuc}
8634684ddb6SLionel Sambuc
8644684ddb6SLionel Sambuctemplate <class _Tp>
8654684ddb6SLionel Sambucinline _LIBCPP_INLINE_VISIBILITY
8664684ddb6SLionel Sambucconstexpr
8674684ddb6SLionel Sambucoptional<typename decay<_Tp>::type>
8684684ddb6SLionel Sambucmake_optional(_Tp&& __v)
8694684ddb6SLionel Sambuc{
8704684ddb6SLionel Sambuc    return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
8714684ddb6SLionel Sambuc}
8724684ddb6SLionel Sambuc
873*0a6a1f1dSLionel Sambuc_LIBCPP_END_NAMESPACE_LFTS
8744684ddb6SLionel Sambuc
8754684ddb6SLionel Sambuc_LIBCPP_BEGIN_NAMESPACE_STD
8764684ddb6SLionel Sambuc
8774684ddb6SLionel Sambuctemplate <class _Tp>
8784684ddb6SLionel Sambucstruct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
8794684ddb6SLionel Sambuc{
8804684ddb6SLionel Sambuc    typedef std::experimental::optional<_Tp> argument_type;
8814684ddb6SLionel Sambuc    typedef size_t        result_type;
8824684ddb6SLionel Sambuc
8834684ddb6SLionel Sambuc    _LIBCPP_INLINE_VISIBILITY
8844684ddb6SLionel Sambuc    result_type operator()(const argument_type& __opt) const _NOEXCEPT
8854684ddb6SLionel Sambuc    {
8864684ddb6SLionel Sambuc        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
8874684ddb6SLionel Sambuc    }
8884684ddb6SLionel Sambuc};
8894684ddb6SLionel Sambuc
8904684ddb6SLionel Sambuc_LIBCPP_END_NAMESPACE_STD
8914684ddb6SLionel Sambuc
8924684ddb6SLionel Sambuc#endif  // _LIBCPP_STD_VER > 11
8934684ddb6SLionel Sambuc
894*0a6a1f1dSLionel Sambuc#endif  // _LIBCPP_OPTIONAL
895