1// -*- C++ -*-
2//===-------------------------- optional ----------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_OPTIONAL
12#define _LIBCPP_OPTIONAL
13
14/*
15    optional synopsis
16
17// C++1z
18
19namespace std {
20  // 23.6.3, optional for object types
21  template <class T> class optional;
22
23  // 23.6.4, no-value state indicator
24  struct nullopt_t{see below };
25  constexpr nullopt_t nullopt(unspecified );
26
27  // 23.6.5, class bad_optional_access
28  class bad_optional_access;
29
30  // 23.6.6, relational operators
31  template <class T, class U>
32  constexpr bool operator==(const optional<T>&, const optional<U>&);
33  template <class T, class U>
34  constexpr bool operator!=(const optional<T>&, const optional<U>&);
35  template <class T, class U>
36  constexpr bool operator<(const optional<T>&, const optional<U>&);
37  template <class T, class U>
38  constexpr bool operator>(const optional<T>&, const optional<U>&);
39  template <class T, class U>
40  constexpr bool operator<=(const optional<T>&, const optional<U>&);
41  template <class T, class U>
42  constexpr bool operator>=(const optional<T>&, const optional<U>&);
43
44  // 23.6.7 comparison with nullopt
45  template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
46  template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
47  template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
48  template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
49  template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
50  template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
51  template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
52  template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
53  template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
54  template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
55  template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
56  template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
57
58  // 23.6.8, comparison with T
59  template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
60  template <class T, class U> constexpr bool operator==(const U&, const optional<T>&);
61  template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
62  template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&);
63  template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
64  template <class T, class U> constexpr bool operator<(const U&, const optional<T>&);
65  template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
66  template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&);
67  template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
68  template <class T, class U> constexpr bool operator>(const U&, const optional<T>&);
69  template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
70  template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&);
71
72  // 23.6.9, specialized algorithms
73  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
74  template <class T> constexpr optional<see below > make_optional(T&&);
75  template <class T, class... Args>
76    constexpr optional<T> make_optional(Args&&... args);
77  template <class T, class U, class... Args>
78    constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
79
80  // 23.6.10, hash support
81  template <class T> struct hash;
82  template <class T> struct hash<optional<T>>;
83
84  template <class T> class optional {
85  public:
86    using value_type = T;
87
88    // 23.6.3.1, constructors
89    constexpr optional() noexcept;
90    constexpr optional(nullopt_t) noexcept;
91    optional(const optional &);
92    optional(optional &&) noexcept(see below);
93    template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
94    template <class U, class... Args>
95      constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
96    template <class U = T>
97      constexpr EXPLICIT optional(U &&);
98    template <class U>
99      constexpr EXPLICIT optional(const optional<U> &);
100    template <class U>
101      constexpr EXPLICIT optional(optional<U> &&);
102
103    // 23.6.3.2, destructor
104    ~optional();
105
106    // 23.6.3.3, assignment
107    optional &operator=(nullopt_t) noexcept;
108    optional &operator=(const optional &);
109    optional &operator=(optional &&) noexcept(see below );
110    template <class U = T> optional &operator=(U &&);
111    template <class U> optional &operator=(const optional<U> &);
112    template <class U> optional &operator=(optional<U> &&);
113    template <class... Args> T& emplace(Args &&...);
114    template <class U, class... Args>
115      T& emplace(initializer_list<U>, Args &&...);
116
117    // 23.6.3.4, swap
118    void swap(optional &) noexcept(see below );
119
120    // 23.6.3.5, observers
121    constexpr T const *operator->() const;
122    constexpr T *operator->();
123    constexpr T const &operator*() const &;
124    constexpr T &operator*() &;
125    constexpr T &&operator*() &&;
126    constexpr const T &&operator*() const &&;
127    constexpr explicit operator bool() const noexcept;
128    constexpr bool has_value() const noexcept;
129    constexpr T const &value() const &;
130    constexpr T &value() &;
131    constexpr T &&value() &&;
132    constexpr const T &&value() const &&;
133    template <class U> constexpr T value_or(U &&) const &;
134    template <class U> constexpr T value_or(U &&) &&;
135
136    // 23.6.3.6, modifiers
137    void reset() noexcept;
138
139  private:
140    T *val; // exposition only
141  };
142} // namespace std
143
144*/
145
146#include <__config>
147#include <__debug>
148#include <__functional_base>
149#include <__undef_min_max>
150#include <functional>
151#include <initializer_list>
152#include <new>
153#include <stdexcept>
154#include <type_traits>
155#include <utility>
156
157#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
158#pragma GCC system_header
159#endif
160
161namespace std  // purposefully not using versioning namespace
162{
163
164class _LIBCPP_EXCEPTION_ABI bad_optional_access
165    : public exception
166{
167public:
168    // Get the key function ~bad_optional_access() into the dylib
169    virtual ~bad_optional_access() _NOEXCEPT;
170    virtual const char* what() const _NOEXCEPT;
171};
172
173}  // std
174
175#if _LIBCPP_STD_VER > 14
176
177_LIBCPP_BEGIN_NAMESPACE_STD
178
179_LIBCPP_NORETURN
180inline _LIBCPP_INLINE_VISIBILITY
181void __throw_bad_optional_access() {
182#ifndef _LIBCPP_NO_EXCEPTIONS
183        throw bad_optional_access();
184#else
185        _VSTD::abort();
186#endif
187}
188
189struct nullopt_t
190{
191    struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
192    _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
193};
194
195/* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
196
197template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
198struct __optional_destruct_base;
199
200template <class _Tp>
201struct __optional_destruct_base<_Tp, false>
202{
203    typedef _Tp value_type;
204    static_assert(is_object_v<value_type>,
205        "instantiation of optional with a non-object type is undefined behavior");
206    union
207    {
208        char __null_state_;
209        value_type __val_;
210    };
211    bool __engaged_;
212
213    _LIBCPP_INLINE_VISIBILITY
214    ~__optional_destruct_base()
215    {
216        if (__engaged_)
217            __val_.~value_type();
218    }
219
220    _LIBCPP_INLINE_VISIBILITY
221    constexpr __optional_destruct_base() noexcept
222        :  __null_state_(),
223           __engaged_(false) {}
224
225    template <class... _Args>
226    _LIBCPP_INLINE_VISIBILITY
227    constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
228        :  __val_(_VSTD::forward<_Args>(__args)...),
229           __engaged_(true) {}
230
231    _LIBCPP_INLINE_VISIBILITY
232    void reset() noexcept
233    {
234        if (__engaged_)
235        {
236            __val_.~value_type();
237            __engaged_ = false;
238        }
239    }
240};
241
242template <class _Tp>
243struct __optional_destruct_base<_Tp, true>
244{
245    typedef _Tp value_type;
246    static_assert(is_object_v<value_type>,
247        "instantiation of optional with a non-object type is undefined behavior");
248    union
249    {
250        char __null_state_;
251        value_type __val_;
252    };
253    bool __engaged_;
254
255    _LIBCPP_INLINE_VISIBILITY
256    constexpr __optional_destruct_base() noexcept
257        :  __null_state_(),
258           __engaged_(false) {}
259
260    template <class... _Args>
261    _LIBCPP_INLINE_VISIBILITY
262    constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
263        :  __val_(_VSTD::forward<_Args>(__args)...),
264           __engaged_(true) {}
265
266    _LIBCPP_INLINE_VISIBILITY
267    void reset() noexcept
268    {
269        if (__engaged_)
270        {
271            __engaged_ = false;
272        }
273    }
274};
275
276template <class _Tp, bool = is_reference<_Tp>::value>
277struct __optional_storage_base : __optional_destruct_base<_Tp>
278{
279    using __base = __optional_destruct_base<_Tp>;
280    using value_type = _Tp;
281    using __base::__base;
282
283    _LIBCPP_INLINE_VISIBILITY
284    constexpr bool has_value() const noexcept
285    {
286        return this->__engaged_;
287    }
288
289    _LIBCPP_INLINE_VISIBILITY
290    constexpr value_type& __get() & noexcept
291    {
292        return this->__val_;
293    }
294    _LIBCPP_INLINE_VISIBILITY
295    constexpr const value_type& __get() const& noexcept
296    {
297        return this->__val_;
298    }
299    _LIBCPP_INLINE_VISIBILITY
300    constexpr value_type&& __get() && noexcept
301    {
302        return _VSTD::move(this->__val_);
303    }
304    _LIBCPP_INLINE_VISIBILITY
305    constexpr const value_type&& __get() const&& noexcept
306    {
307        return _VSTD::move(this->__val_);
308    }
309
310    template <class... _Args>
311    _LIBCPP_INLINE_VISIBILITY
312    void __construct(_Args&&... __args)
313    {
314        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
315        ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
316        this->__engaged_ = true;
317    }
318
319    template <class _That>
320    _LIBCPP_INLINE_VISIBILITY
321    void __construct_from(_That&& __opt)
322    {
323        if (__opt.has_value())
324            __construct(_VSTD::forward<_That>(__opt).__get());
325    }
326
327    template <class _That>
328    _LIBCPP_INLINE_VISIBILITY
329    void __assign_from(_That&& __opt)
330    {
331        if (this->__engaged_ == __opt.has_value())
332        {
333            if (this->__engaged_)
334                this->__val_ = _VSTD::forward<_That>(__opt).__get();
335        }
336        else
337        {
338            if (this->__engaged_)
339                this->reset();
340            else
341                __construct(_VSTD::forward<_That>(__opt).__get());
342        }
343    }
344};
345
346// optional<T&> is currently required ill-formed, however it may to be in the
347// future. For this reason it has already been implemented to ensure we can
348// make the change in an ABI compatible manner.
349template <class _Tp>
350struct __optional_storage_base<_Tp, true>
351{
352    using value_type = _Tp;
353    using __raw_type = remove_reference_t<_Tp>;
354    __raw_type* __value_;
355
356    template <class _Up>
357    static constexpr bool __can_bind_reference() {
358        using _RawUp = typename remove_reference<_Up>::type;
359        using _UpPtr = _RawUp*;
360        using _RawTp = typename remove_reference<_Tp>::type;
361        using _TpPtr = _RawTp*;
362        using _CheckLValueArg = integral_constant<bool,
363            (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
364        ||  is_same<_RawUp, reference_wrapper<_RawTp>>::value
365        ||  is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
366        >;
367        return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
368            || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
369                is_convertible<_UpPtr, _TpPtr>::value);
370    }
371
372    _LIBCPP_INLINE_VISIBILITY
373    constexpr __optional_storage_base() noexcept
374        :  __value_(nullptr) {}
375
376    template <class _UArg>
377    _LIBCPP_INLINE_VISIBILITY
378    constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
379        :  __value_(_VSTD::addressof(__uarg))
380    {
381      static_assert(__can_bind_reference<_UArg>(),
382        "Attempted to construct a reference element in tuple from a "
383        "possible temporary");
384    }
385
386    _LIBCPP_INLINE_VISIBILITY
387    void reset() noexcept { __value_ = nullptr; }
388
389    _LIBCPP_INLINE_VISIBILITY
390    constexpr bool has_value() const noexcept
391      { return __value_ != nullptr; }
392
393    _LIBCPP_INLINE_VISIBILITY
394    constexpr value_type& __get() const& noexcept
395      { return *__value_; }
396
397    _LIBCPP_INLINE_VISIBILITY
398    constexpr value_type&& __get() const&& noexcept
399      { return _VSTD::forward<value_type>(*__value_); }
400
401    template <class _UArg>
402    _LIBCPP_INLINE_VISIBILITY
403    void __construct(_UArg&& __val)
404    {
405        _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
406        static_assert(__can_bind_reference<_UArg>(),
407            "Attempted to construct a reference element in tuple from a "
408            "possible temporary");
409        __value_ = _VSTD::addressof(__val);
410    }
411
412    template <class _That>
413    _LIBCPP_INLINE_VISIBILITY
414    void __construct_from(_That&& __opt)
415    {
416        if (__opt.has_value())
417            __construct(_VSTD::forward<_That>(__opt).__get());
418    }
419
420    template <class _That>
421    _LIBCPP_INLINE_VISIBILITY
422    void __assign_from(_That&& __opt)
423    {
424        if (has_value() == __opt.has_value())
425        {
426            if (has_value())
427                *__value_ = _VSTD::forward<_That>(__opt).__get();
428        }
429        else
430        {
431            if (has_value())
432                reset();
433            else
434                __construct(_VSTD::forward<_That>(__opt).__get());
435        }
436    }
437};
438
439template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
440struct __optional_storage;
441
442template <class _Tp>
443struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
444{
445    using __optional_storage_base<_Tp>::__optional_storage_base;
446};
447
448template <class _Tp>
449struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
450{
451    using value_type = _Tp;
452    using __optional_storage_base<_Tp>::__optional_storage_base;
453
454    _LIBCPP_INLINE_VISIBILITY
455    __optional_storage() = default;
456
457    _LIBCPP_INLINE_VISIBILITY
458    __optional_storage(const __optional_storage& __opt)
459    {
460        this->__construct_from(__opt);
461    }
462
463    _LIBCPP_INLINE_VISIBILITY
464    __optional_storage(__optional_storage&& __opt)
465        noexcept(is_nothrow_move_constructible_v<value_type>)
466    {
467        this->__construct_from(_VSTD::move(__opt));
468    }
469
470    _LIBCPP_INLINE_VISIBILITY
471    __optional_storage& operator=(const __optional_storage& __opt)
472    {
473        this->__assign_from(__opt);
474        return *this;
475    }
476
477    _LIBCPP_INLINE_VISIBILITY
478    __optional_storage& operator=(__optional_storage&& __opt)
479        noexcept(is_nothrow_move_assignable_v<value_type> &&
480                 is_nothrow_move_constructible_v<value_type>)
481    {
482        this->__assign_from(_VSTD::move(__opt));
483        return *this;
484    }
485};
486
487template <class _Tp>
488using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
489    is_copy_constructible<_Tp>::value,
490    is_move_constructible<_Tp>::value
491>;
492
493template <class _Tp>
494using __optional_sfinae_assign_base_t = __sfinae_assign_base<
495    (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
496    (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
497>;
498
499template <class _Tp>
500class optional
501    : private __optional_storage<_Tp>
502    , private __optional_sfinae_ctor_base_t<_Tp>
503    , private __optional_sfinae_assign_base_t<_Tp>
504{
505    using __base = __optional_storage<_Tp>;
506public:
507    using value_type = _Tp;
508
509private:
510     // Disable the reference extension using this static assert.
511    static_assert(!is_same_v<value_type, in_place_t>,
512        "instantiation of optional with in_place_t is ill-formed");
513    static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
514        "instantiation of optional with nullopt_t is ill-formed");
515    static_assert(!is_reference_v<value_type>,
516        "instantiation of optional with a reference type is ill-formed");
517    static_assert(is_destructible_v<value_type>,
518        "instantiation of optional with a non-destructible type is ill-formed");
519
520    // LWG2756: conditionally explicit conversion from _Up
521    struct _CheckOptionalArgsConstructor {
522      template <class _Up>
523      static constexpr bool __enable_implicit() {
524          return is_constructible_v<_Tp, _Up&&> &&
525                 is_convertible_v<_Up&&, _Tp>;
526      }
527
528      template <class _Up>
529      static constexpr bool __enable_explicit() {
530          return is_constructible_v<_Tp, _Up&&> &&
531                 !is_convertible_v<_Up&&, _Tp>;
532      }
533    };
534    template <class _Up>
535    using _CheckOptionalArgsCtor = conditional_t<
536        !is_same_v<decay_t<_Up>, in_place_t> &&
537        !is_same_v<decay_t<_Up>, optional>,
538        _CheckOptionalArgsConstructor,
539        __check_tuple_constructor_fail
540    >;
541    template <class _QualUp>
542    struct _CheckOptionalLikeConstructor {
543      template <class _Up, class _Opt = optional<_Up>>
544      using __check_constructible_from_opt = __lazy_or<
545          is_constructible<_Tp, _Opt&>,
546          is_constructible<_Tp, _Opt const&>,
547          is_constructible<_Tp, _Opt&&>,
548          is_constructible<_Tp, _Opt const&&>,
549          is_convertible<_Opt&, _Tp>,
550          is_convertible<_Opt const&, _Tp>,
551          is_convertible<_Opt&&, _Tp>,
552          is_convertible<_Opt const&&, _Tp>
553      >;
554      template <class _Up, class _Opt = optional<_Up>>
555      using __check_assignable_from_opt = __lazy_or<
556          is_assignable<_Tp&, _Opt&>,
557          is_assignable<_Tp&, _Opt const&>,
558          is_assignable<_Tp&, _Opt&&>,
559          is_assignable<_Tp&, _Opt const&&>
560      >;
561      template <class _Up, class _QUp = _QualUp>
562      static constexpr bool __enable_implicit() {
563          return is_convertible<_QUp, _Tp>::value &&
564              !__check_constructible_from_opt<_Up>::value;
565      }
566      template <class _Up, class _QUp = _QualUp>
567      static constexpr bool __enable_explicit() {
568          return !is_convertible<_QUp, _Tp>::value &&
569              !__check_constructible_from_opt<_Up>::value;
570      }
571      template <class _Up, class _QUp = _QualUp>
572      static constexpr bool __enable_assign() {
573          // Construction and assignability of _Qup to _Tp has already been
574          // checked.
575          return !__check_constructible_from_opt<_Up>::value &&
576              !__check_assignable_from_opt<_Up>::value;
577      }
578    };
579
580    template <class _Up, class _QualUp>
581    using _CheckOptionalLikeCtor = conditional_t<
582      __lazy_and<
583          __lazy_not<is_same<_Up, _Tp>>,
584          is_constructible<_Tp, _QualUp>
585      >::value,
586      _CheckOptionalLikeConstructor<_QualUp>,
587      __check_tuple_constructor_fail
588    >;
589    template <class _Up, class _QualUp>
590    using _CheckOptionalLikeAssign = conditional_t<
591      __lazy_and<
592          __lazy_not<is_same<_Up, _Tp>>,
593          is_constructible<_Tp, _QualUp>,
594          is_assignable<_Tp&, _QualUp>
595      >::value,
596      _CheckOptionalLikeConstructor<_QualUp>,
597      __check_tuple_constructor_fail
598    >;
599public:
600
601    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
602    _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
603    _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
604    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
605
606    template <class... _Args, class = enable_if_t<
607        is_constructible_v<value_type, _Args...>>
608    >
609    _LIBCPP_INLINE_VISIBILITY
610    constexpr explicit optional(in_place_t, _Args&&... __args)
611        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
612
613    template <class _Up, class... _Args, class = enable_if_t<
614        is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
615    >
616    _LIBCPP_INLINE_VISIBILITY
617    constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
618        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
619
620    template <class _Up = value_type, enable_if_t<
621        _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
622    , int> = 0>
623    _LIBCPP_INLINE_VISIBILITY
624    constexpr optional(_Up&& __v)
625        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
626
627    template <class _Up, enable_if_t<
628        _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
629    , int> = 0>
630    _LIBCPP_INLINE_VISIBILITY
631    constexpr explicit optional(_Up&& __v)
632        : __base(in_place, _VSTD::forward<_Up>(__v)) {}
633
634    // LWG2756: conditionally explicit conversion from const optional<_Up>&
635    template <class _Up, enable_if_t<
636        _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
637    , int> = 0>
638    _LIBCPP_INLINE_VISIBILITY
639    optional(const optional<_Up>& __v)
640    {
641        this->__construct_from(__v);
642    }
643    template <class _Up, enable_if_t<
644        _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
645    , int> = 0>
646    _LIBCPP_INLINE_VISIBILITY
647    explicit optional(const optional<_Up>& __v)
648    {
649        this->__construct_from(__v);
650    }
651
652    // LWG2756: conditionally explicit conversion from optional<_Up>&&
653    template <class _Up, enable_if_t<
654        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
655    , int> = 0>
656    _LIBCPP_INLINE_VISIBILITY
657    optional(optional<_Up>&& __v)
658    {
659        this->__construct_from(_VSTD::move(__v));
660    }
661    template <class _Up, enable_if_t<
662        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
663    , int> = 0>
664    _LIBCPP_INLINE_VISIBILITY
665    explicit optional(optional<_Up>&& __v)
666    {
667        this->__construct_from(_VSTD::move(__v));
668    }
669
670    _LIBCPP_INLINE_VISIBILITY
671    optional& operator=(nullopt_t) noexcept
672    {
673        reset();
674        return *this;
675    }
676
677    _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
678    _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
679
680    // LWG2756
681    template <class _Up = value_type,
682              class = enable_if_t
683                      <__lazy_and<
684                          integral_constant<bool,
685                              !is_same_v<decay_t<_Up>, optional> &&
686                              !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
687                          >,
688                          is_constructible<value_type, _Up>,
689                          is_assignable<value_type&, _Up>
690                      >::value>
691             >
692    _LIBCPP_INLINE_VISIBILITY
693    optional&
694    operator=(_Up&& __v)
695    {
696        if (this->has_value())
697            this->__get() = _VSTD::forward<_Up>(__v);
698        else
699            this->__construct(_VSTD::forward<_Up>(__v));
700        return *this;
701    }
702
703    // LWG2756
704    template <class _Up, enable_if_t<
705        _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
706    , int> = 0>
707    _LIBCPP_INLINE_VISIBILITY
708    optional&
709    operator=(const optional<_Up>& __v)
710    {
711        this->__assign_from(__v);
712        return *this;
713    }
714
715    // LWG2756
716    template <class _Up, enable_if_t<
717        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
718    , int> = 0>
719    _LIBCPP_INLINE_VISIBILITY
720    optional&
721    operator=(optional<_Up>&& __v)
722    {
723        this->__assign_from(_VSTD::move(__v));
724        return *this;
725    }
726
727    template <class... _Args,
728              class = enable_if_t
729                      <
730                          is_constructible_v<value_type, _Args...>
731                      >
732             >
733    _LIBCPP_INLINE_VISIBILITY
734    _Tp &
735    emplace(_Args&&... __args)
736    {
737        reset();
738        this->__construct(_VSTD::forward<_Args>(__args)...);
739        return this->__get();
740    }
741
742    template <class _Up, class... _Args,
743              class = enable_if_t
744                      <
745                          is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
746                      >
747             >
748    _LIBCPP_INLINE_VISIBILITY
749    _Tp &
750    emplace(initializer_list<_Up> __il, _Args&&... __args)
751    {
752        reset();
753        this->__construct(__il, _VSTD::forward<_Args>(__args)...);
754        return this->__get();
755    }
756
757    _LIBCPP_INLINE_VISIBILITY
758    void swap(optional& __opt)
759        noexcept(is_nothrow_move_constructible_v<value_type> &&
760                 is_nothrow_swappable_v<value_type>)
761    {
762        if (this->has_value() == __opt.has_value())
763        {
764            using _VSTD::swap;
765            if (this->has_value())
766                swap(this->__get(), __opt.__get());
767        }
768        else
769        {
770            if (this->has_value())
771            {
772                __opt.__construct(_VSTD::move(this->__get()));
773                reset();
774            }
775            else
776            {
777                this->__construct(_VSTD::move(__opt.__get()));
778                __opt.reset();
779            }
780        }
781    }
782
783    _LIBCPP_INLINE_VISIBILITY
784    constexpr
785    add_pointer_t<value_type const>
786    operator->() const
787    {
788        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
789#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
790        return _VSTD::addressof(this->__get());
791#else
792        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
793#endif
794    }
795
796    _LIBCPP_INLINE_VISIBILITY
797    constexpr
798    add_pointer_t<value_type>
799    operator->()
800    {
801        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
802#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
803        return _VSTD::addressof(this->__get());
804#else
805        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
806#endif
807    }
808
809    _LIBCPP_INLINE_VISIBILITY
810    constexpr
811    const value_type&
812    operator*() const&
813    {
814        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
815        return this->__get();
816    }
817
818    _LIBCPP_INLINE_VISIBILITY
819    constexpr
820    value_type&
821    operator*() &
822    {
823        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
824        return this->__get();
825    }
826
827    _LIBCPP_INLINE_VISIBILITY
828    constexpr
829    value_type&&
830    operator*() &&
831    {
832        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
833        return _VSTD::move(this->__get());
834    }
835
836    _LIBCPP_INLINE_VISIBILITY
837    constexpr
838    const value_type&&
839    operator*() const&&
840    {
841        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
842        return _VSTD::move(this->__get());
843    }
844
845    _LIBCPP_INLINE_VISIBILITY
846    constexpr explicit operator bool() const noexcept { return has_value(); }
847
848    using __base::has_value;
849    using __base::__get;
850
851    _LIBCPP_INLINE_VISIBILITY
852    constexpr value_type const& value() const&
853    {
854        if (!this->has_value())
855            __throw_bad_optional_access();
856        return this->__get();
857    }
858
859    _LIBCPP_INLINE_VISIBILITY
860    constexpr value_type& value() &
861    {
862        if (!this->has_value())
863            __throw_bad_optional_access();
864        return this->__get();
865    }
866
867    _LIBCPP_INLINE_VISIBILITY
868    constexpr value_type&& value() &&
869    {
870        if (!this->has_value())
871            __throw_bad_optional_access();
872        return _VSTD::move(this->__get());
873    }
874
875    _LIBCPP_INLINE_VISIBILITY
876    constexpr value_type const&& value() const&&
877    {
878        if (!this->has_value())
879            __throw_bad_optional_access();
880        return _VSTD::move(this->__get());
881    }
882
883    template <class _Up>
884    _LIBCPP_INLINE_VISIBILITY
885    constexpr value_type value_or(_Up&& __v) const&
886    {
887        static_assert(is_copy_constructible_v<value_type>,
888                      "optional<T>::value_or: T must be copy constructible");
889        static_assert(is_convertible_v<_Up, value_type>,
890                      "optional<T>::value_or: U must be convertible to T");
891        return this->has_value() ? this->__get() :
892                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
893    }
894
895    template <class _Up>
896    _LIBCPP_INLINE_VISIBILITY
897    value_type value_or(_Up&& __v) &&
898    {
899        static_assert(is_move_constructible_v<value_type>,
900                      "optional<T>::value_or: T must be move constructible");
901        static_assert(is_convertible_v<_Up, value_type>,
902                      "optional<T>::value_or: U must be convertible to T");
903        return this->has_value() ? _VSTD::move(this->__get()) :
904                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
905    }
906
907    using __base::reset;
908
909private:
910    template <class _Up>
911    _LIBCPP_INLINE_VISIBILITY
912    static _Up*
913    __operator_arrow(true_type, _Up& __x)
914    {
915        return _VSTD::addressof(__x);
916    }
917
918    template <class _Up>
919    _LIBCPP_INLINE_VISIBILITY
920    static constexpr _Up*
921    __operator_arrow(false_type, _Up& __x)
922    {
923        return &__x;
924    }
925};
926
927// Comparisons between optionals
928template <class _Tp, class _Up>
929_LIBCPP_INLINE_VISIBILITY constexpr
930enable_if_t<
931    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
932        _VSTD::declval<const _Up&>()), bool>,
933    bool
934>
935operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
936{
937    if (static_cast<bool>(__x) != static_cast<bool>(__y))
938        return false;
939    if (!static_cast<bool>(__x))
940        return true;
941    return *__x == *__y;
942}
943
944template <class _Tp, class _Up>
945_LIBCPP_INLINE_VISIBILITY constexpr
946enable_if_t<
947    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
948        _VSTD::declval<const _Up&>()), bool>,
949    bool
950>
951operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
952{
953    if (static_cast<bool>(__x) != static_cast<bool>(__y))
954        return true;
955    if (!static_cast<bool>(__x))
956        return false;
957    return *__x != *__y;
958}
959
960template <class _Tp, class _Up>
961_LIBCPP_INLINE_VISIBILITY constexpr
962enable_if_t<
963    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
964        _VSTD::declval<const _Up&>()), bool>,
965    bool
966>
967operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
968{
969    if (!static_cast<bool>(__y))
970        return false;
971    if (!static_cast<bool>(__x))
972        return true;
973    return *__x < *__y;
974}
975
976template <class _Tp, class _Up>
977_LIBCPP_INLINE_VISIBILITY constexpr
978enable_if_t<
979    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
980        _VSTD::declval<const _Up&>()), bool>,
981    bool
982>
983operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
984{
985    if (!static_cast<bool>(__x))
986        return false;
987    if (!static_cast<bool>(__y))
988        return true;
989    return *__x > *__y;
990}
991
992template <class _Tp, class _Up>
993_LIBCPP_INLINE_VISIBILITY constexpr
994enable_if_t<
995    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
996        _VSTD::declval<const _Up&>()), bool>,
997    bool
998>
999operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1000{
1001    if (!static_cast<bool>(__x))
1002        return true;
1003    if (!static_cast<bool>(__y))
1004        return false;
1005    return *__x <= *__y;
1006}
1007
1008template <class _Tp, class _Up>
1009_LIBCPP_INLINE_VISIBILITY constexpr
1010enable_if_t<
1011    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1012        _VSTD::declval<const _Up&>()), bool>,
1013    bool
1014>
1015operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1016{
1017    if (!static_cast<bool>(__y))
1018        return true;
1019    if (!static_cast<bool>(__x))
1020        return false;
1021    return *__x >= *__y;
1022}
1023
1024// Comparisons with nullopt
1025template <class _Tp>
1026_LIBCPP_INLINE_VISIBILITY constexpr
1027bool
1028operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1029{
1030    return !static_cast<bool>(__x);
1031}
1032
1033template <class _Tp>
1034_LIBCPP_INLINE_VISIBILITY constexpr
1035bool
1036operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1037{
1038    return !static_cast<bool>(__x);
1039}
1040
1041template <class _Tp>
1042_LIBCPP_INLINE_VISIBILITY constexpr
1043bool
1044operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1045{
1046    return static_cast<bool>(__x);
1047}
1048
1049template <class _Tp>
1050_LIBCPP_INLINE_VISIBILITY constexpr
1051bool
1052operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1053{
1054    return static_cast<bool>(__x);
1055}
1056
1057template <class _Tp>
1058_LIBCPP_INLINE_VISIBILITY constexpr
1059bool
1060operator<(const optional<_Tp>&, nullopt_t) noexcept
1061{
1062    return false;
1063}
1064
1065template <class _Tp>
1066_LIBCPP_INLINE_VISIBILITY constexpr
1067bool
1068operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1069{
1070    return static_cast<bool>(__x);
1071}
1072
1073template <class _Tp>
1074_LIBCPP_INLINE_VISIBILITY constexpr
1075bool
1076operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1077{
1078    return !static_cast<bool>(__x);
1079}
1080
1081template <class _Tp>
1082_LIBCPP_INLINE_VISIBILITY constexpr
1083bool
1084operator<=(nullopt_t, const optional<_Tp>&) noexcept
1085{
1086    return true;
1087}
1088
1089template <class _Tp>
1090_LIBCPP_INLINE_VISIBILITY constexpr
1091bool
1092operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1093{
1094    return static_cast<bool>(__x);
1095}
1096
1097template <class _Tp>
1098_LIBCPP_INLINE_VISIBILITY constexpr
1099bool
1100operator>(nullopt_t, const optional<_Tp>&) noexcept
1101{
1102    return false;
1103}
1104
1105template <class _Tp>
1106_LIBCPP_INLINE_VISIBILITY constexpr
1107bool
1108operator>=(const optional<_Tp>&, nullopt_t) noexcept
1109{
1110    return true;
1111}
1112
1113template <class _Tp>
1114_LIBCPP_INLINE_VISIBILITY constexpr
1115bool
1116operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1117{
1118    return !static_cast<bool>(__x);
1119}
1120
1121// Comparisons with T
1122template <class _Tp, class _Up>
1123_LIBCPP_INLINE_VISIBILITY constexpr
1124enable_if_t<
1125    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1126        _VSTD::declval<const _Up&>()), bool>,
1127    bool
1128>
1129operator==(const optional<_Tp>& __x, const _Up& __v)
1130{
1131    return static_cast<bool>(__x) ? *__x == __v : false;
1132}
1133
1134template <class _Tp, class _Up>
1135_LIBCPP_INLINE_VISIBILITY constexpr
1136enable_if_t<
1137    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1138        _VSTD::declval<const _Up&>()), bool>,
1139    bool
1140>
1141operator==(const _Tp& __v, const optional<_Up>& __x)
1142{
1143    return static_cast<bool>(__x) ? __v == *__x : false;
1144}
1145
1146template <class _Tp, class _Up>
1147_LIBCPP_INLINE_VISIBILITY constexpr
1148enable_if_t<
1149    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1150        _VSTD::declval<const _Up&>()), bool>,
1151    bool
1152>
1153operator!=(const optional<_Tp>& __x, const _Up& __v)
1154{
1155    return static_cast<bool>(__x) ? *__x != __v : true;
1156}
1157
1158template <class _Tp, class _Up>
1159_LIBCPP_INLINE_VISIBILITY constexpr
1160enable_if_t<
1161    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1162        _VSTD::declval<const _Up&>()), bool>,
1163    bool
1164>
1165operator!=(const _Tp& __v, const optional<_Up>& __x)
1166{
1167    return static_cast<bool>(__x) ? __v != *__x : true;
1168}
1169
1170template <class _Tp, class _Up>
1171_LIBCPP_INLINE_VISIBILITY constexpr
1172enable_if_t<
1173    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1174        _VSTD::declval<const _Up&>()), bool>,
1175    bool
1176>
1177operator<(const optional<_Tp>& __x, const _Up& __v)
1178{
1179    return static_cast<bool>(__x) ? *__x < __v : true;
1180}
1181
1182template <class _Tp, class _Up>
1183_LIBCPP_INLINE_VISIBILITY constexpr
1184enable_if_t<
1185    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1186        _VSTD::declval<const _Up&>()), bool>,
1187    bool
1188>
1189operator<(const _Tp& __v, const optional<_Up>& __x)
1190{
1191    return static_cast<bool>(__x) ? __v < *__x : false;
1192}
1193
1194template <class _Tp, class _Up>
1195_LIBCPP_INLINE_VISIBILITY constexpr
1196enable_if_t<
1197    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1198        _VSTD::declval<const _Up&>()), bool>,
1199    bool
1200>
1201operator<=(const optional<_Tp>& __x, const _Up& __v)
1202{
1203    return static_cast<bool>(__x) ? *__x <= __v : true;
1204}
1205
1206template <class _Tp, class _Up>
1207_LIBCPP_INLINE_VISIBILITY constexpr
1208enable_if_t<
1209    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1210        _VSTD::declval<const _Up&>()), bool>,
1211    bool
1212>
1213operator<=(const _Tp& __v, const optional<_Up>& __x)
1214{
1215    return static_cast<bool>(__x) ? __v <= *__x : false;
1216}
1217
1218template <class _Tp, class _Up>
1219_LIBCPP_INLINE_VISIBILITY constexpr
1220enable_if_t<
1221    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1222        _VSTD::declval<const _Up&>()), bool>,
1223    bool
1224>
1225operator>(const optional<_Tp>& __x, const _Up& __v)
1226{
1227    return static_cast<bool>(__x) ? *__x > __v : false;
1228}
1229
1230template <class _Tp, class _Up>
1231_LIBCPP_INLINE_VISIBILITY constexpr
1232enable_if_t<
1233    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1234        _VSTD::declval<const _Up&>()), bool>,
1235    bool
1236>
1237operator>(const _Tp& __v, const optional<_Up>& __x)
1238{
1239    return static_cast<bool>(__x) ? __v > *__x : true;
1240}
1241
1242template <class _Tp, class _Up>
1243_LIBCPP_INLINE_VISIBILITY constexpr
1244enable_if_t<
1245    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1246        _VSTD::declval<const _Up&>()), bool>,
1247    bool
1248>
1249operator>=(const optional<_Tp>& __x, const _Up& __v)
1250{
1251    return static_cast<bool>(__x) ? *__x >= __v : false;
1252}
1253
1254template <class _Tp, class _Up>
1255_LIBCPP_INLINE_VISIBILITY constexpr
1256enable_if_t<
1257    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1258        _VSTD::declval<const _Up&>()), bool>,
1259    bool
1260>
1261operator>=(const _Tp& __v, const optional<_Up>& __x)
1262{
1263    return static_cast<bool>(__x) ? __v >= *__x : true;
1264}
1265
1266
1267template <class _Tp>
1268inline _LIBCPP_INLINE_VISIBILITY
1269enable_if_t<
1270    is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1271    void
1272>
1273swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1274{
1275    __x.swap(__y);
1276}
1277
1278template <class _Tp>
1279_LIBCPP_INLINE_VISIBILITY constexpr
1280optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1281{
1282    return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1283}
1284
1285template <class _Tp, class... _Args>
1286_LIBCPP_INLINE_VISIBILITY constexpr
1287optional<_Tp> make_optional(_Args&&... __args)
1288{
1289    return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1290}
1291
1292template <class _Tp, class _Up, class... _Args>
1293_LIBCPP_INLINE_VISIBILITY constexpr
1294optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1295{
1296    return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1297}
1298
1299template <class _Tp>
1300struct _LIBCPP_TEMPLATE_VIS hash<
1301    __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1302>
1303{
1304    typedef optional<_Tp> argument_type;
1305    typedef size_t        result_type;
1306
1307    _LIBCPP_INLINE_VISIBILITY
1308    result_type operator()(const argument_type& __opt) const
1309    {
1310        return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1311    }
1312};
1313
1314_LIBCPP_END_NAMESPACE_STD
1315
1316#endif  // _LIBCPP_STD_VER > 14
1317
1318#endif  // _LIBCPP_OPTIONAL
1319