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  // 20.6.3, optional for object types
21  template <class T> class optional;
22
23  // 20.6.4, no-value state indicator
24  struct nullopt_t{see below };
25  constexpr nullopt_t nullopt(unspecified );
26
27  // 20.6.5, class bad_optional_access
28  class bad_optional_access;
29
30  // 20.6.6, relational operators
31  template <class T>
32  constexpr bool operator==(const optional<T>&, const optional<T>&);
33  template <class T>
34  constexpr bool operator!=(const optional<T>&, const optional<T>&);
35  template <class T>
36  constexpr bool operator<(const optional<T>&, const optional<T>&);
37  template <class T>
38  constexpr bool operator>(const optional<T>&, const optional<T>&);
39  template <class T>
40  constexpr bool operator<=(const optional<T>&, const optional<T>&);
41  template <class T>
42  constexpr bool operator>=(const optional<T>&, const optional<T>&);
43  template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
44  template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
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
56  // 20.6.8, comparison with T
57  template <class T> constexpr bool operator==(const optional<T>&, const T&);
58  template <class T> constexpr bool operator==(const T&, const optional<T>&);
59  template <class T> constexpr bool operator!=(const optional<T>&, const T&);
60  template <class T> constexpr bool operator!=(const T&, const optional<T>&);
61  template <class T> constexpr bool operator<(const optional<T>&, const T&);
62  template <class T> constexpr bool operator<(const T&, const optional<T>&);
63  template <class T> constexpr bool operator<=(const optional<T>&, const T&);
64  template <class T> constexpr bool operator<=(const T&, const optional<T>&);
65  template <class T> constexpr bool operator>(const optional<T>&, const T&);
66  template <class T> constexpr bool operator>(const T&, const optional<T>&);
67  template <class T> constexpr bool operator>=(const optional<T>&, const T&);
68  template <class T> constexpr bool operator>=(const T&, const optional<T>&);
69
70  // 20.6.9, specialized algorithms
71  template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
72  template <class T> constexpr optional<see below > make_optional(T&&);
73  template <class T, class... Args>
74    constexpr optional<T> make_optional(Args&&... args);
75  template <class T, class U, class... Args>
76    constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
77
78  // 20.6.10, hash support
79  template <class T> struct hash;
80  template <class T> struct hash<optional<T>>;
81
82  template <class T> class optional {
83  public:
84    using value_type = T;
85
86    // 20.6.3.1, constructors
87    constexpr optional() noexcept;
88    constexpr optional(nullopt_t) noexcept;
89    optional(const optional &);
90    optional(optional &&) noexcept(see below );
91    template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
92    template <class U, class... Args>
93      constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
94    template <class U = T>
95      constexpr EXPLICIT optional(U &&);
96    template <class U>
97      constexpr EXPLICIT optional(const optional<U> &);
98    template <class U>
99      constexpr EXPLICIT optional(optional<U> &&);
100
101    // 20.6.3.2, destructor
102    ~optional();
103
104    // 20.6.3.3, assignment
105    optional &operator=(nullopt_t) noexcept;
106    optional &operator=(const optional &);
107    optional &operator=(optional &&) noexcept(see below );
108    template <class U = T> optional &operator=(U &&);
109    template <class U> optional &operator=(const optional<U> &);
110    template <class U> optional &operator=(optional<U> &&);
111    template <class... Args> void emplace(Args &&...);
112    template <class U, class... Args>
113      void emplace(initializer_list<U>, Args &&...);
114
115    // 20.6.3.4, swap
116    void swap(optional &) noexcept(see below );
117
118    // 20.6.3.5, observers
119    constexpr T const *operator->() const;
120    constexpr T *operator->();
121    constexpr T const &operator*() const &;
122    constexpr T &operator*() &;
123    constexpr T &&operator*() &&;
124    constexpr const T &&operator*() const &&;
125    constexpr explicit operator bool() const noexcept;
126    constexpr bool has_value() const noexcept;
127    constexpr T const &value() const &;
128    constexpr T &value() &;
129    constexpr T &&value() &&;
130    constexpr const T &&value() const &&;
131    template <class U> constexpr T value_or(U &&) const &;
132    template <class U> constexpr T value_or(U &&) &&;
133
134    // 20.6.3.6, modifiers
135    void reset() noexcept;
136
137  private:
138    T *val; // exposition only
139  };
140} // namespace std
141
142*/
143
144#include <__config>
145#include <__debug>
146#include <__functional_base>
147#include <__undef_min_max>
148#include <functional>
149#include <initializer_list>
150#include <new>
151#include <stdexcept>
152#include <type_traits>
153#include <utility>
154
155#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
156#pragma GCC system_header
157#endif
158
159namespace std  // purposefully not using versioning namespace
160{
161
162class _LIBCPP_EXCEPTION_ABI bad_optional_access
163    : public logic_error
164{
165public:
166    _LIBCPP_INLINE_VISIBILITY
167    bad_optional_access() : logic_error("bad optional access") {}
168
169    // Get the key function ~bad_optional_access() into the dylib
170    virtual ~bad_optional_access() _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<in_place_t, _Up> &&
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 optional(const optional&) = default;
603    _LIBCPP_INLINE_VISIBILITY 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    void
735    emplace(_Args&&... __args)
736    {
737        reset();
738        this->__construct(_VSTD::forward<_Args>(__args)...);
739    }
740
741    template <class _Up, class... _Args,
742              class = enable_if_t
743                      <
744                          is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
745                      >
746             >
747    _LIBCPP_INLINE_VISIBILITY
748    void
749    emplace(initializer_list<_Up> __il, _Args&&... __args)
750    {
751        reset();
752        this->__construct(__il, _VSTD::forward<_Args>(__args)...);
753    }
754
755    _LIBCPP_INLINE_VISIBILITY
756    void swap(optional& __opt)
757        noexcept(is_nothrow_move_constructible_v<value_type> &&
758                 is_nothrow_swappable_v<value_type>)
759    {
760        if (this->has_value() == __opt.has_value())
761        {
762            using _VSTD::swap;
763            if (this->has_value())
764                swap(this->__get(), __opt.__get());
765        }
766        else
767        {
768            if (this->has_value())
769            {
770                __opt.__construct(_VSTD::move(this->__get()));
771                reset();
772            }
773            else
774            {
775                this->__construct(_VSTD::move(__opt.__get()));
776                __opt.reset();
777            }
778        }
779    }
780
781    _LIBCPP_INLINE_VISIBILITY
782    constexpr
783    add_pointer_t<value_type const>
784    operator->() const
785    {
786        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
787#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
788        return _VSTD::addressof(this->__get());
789#else
790        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
791#endif
792    }
793
794    _LIBCPP_INLINE_VISIBILITY
795    constexpr
796    add_pointer_t<value_type>
797    operator->()
798    {
799        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
800#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
801        return _VSTD::addressof(this->__get());
802#else
803        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
804#endif
805    }
806
807    _LIBCPP_INLINE_VISIBILITY
808    constexpr
809    const value_type&
810    operator*() const&
811    {
812        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
813        return this->__get();
814    }
815
816    _LIBCPP_INLINE_VISIBILITY
817    constexpr
818    value_type&
819    operator*() &
820    {
821        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
822        return this->__get();
823    }
824
825    _LIBCPP_INLINE_VISIBILITY
826    constexpr
827    value_type&&
828    operator*() &&
829    {
830        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
831        return _VSTD::move(this->__get());
832    }
833
834    _LIBCPP_INLINE_VISIBILITY
835    constexpr
836    const value_type&&
837    operator*() const&&
838    {
839        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
840        return _VSTD::move(this->__get());
841    }
842
843    _LIBCPP_INLINE_VISIBILITY
844    constexpr explicit operator bool() const noexcept { return has_value(); }
845
846    using __base::has_value;
847    using __base::__get;
848
849    _LIBCPP_INLINE_VISIBILITY
850    constexpr value_type const& value() const&
851    {
852        if (!this->has_value())
853            __throw_bad_optional_access();
854        return this->__get();
855    }
856
857    _LIBCPP_INLINE_VISIBILITY
858    constexpr value_type& value() &
859    {
860        if (!this->has_value())
861            __throw_bad_optional_access();
862        return this->__get();
863    }
864
865    _LIBCPP_INLINE_VISIBILITY
866    constexpr value_type&& value() &&
867    {
868        if (!this->has_value())
869            __throw_bad_optional_access();
870        return _VSTD::move(this->__get());
871    }
872
873    _LIBCPP_INLINE_VISIBILITY
874    constexpr value_type const&& value() const&&
875    {
876        if (!this->has_value())
877            __throw_bad_optional_access();
878        return _VSTD::move(this->__get());
879    }
880
881    template <class _Up>
882    _LIBCPP_INLINE_VISIBILITY
883    constexpr value_type value_or(_Up&& __v) const&
884    {
885        static_assert(is_copy_constructible_v<value_type>,
886                      "optional<T>::value_or: T must be copy constructible");
887        static_assert(is_convertible_v<_Up, value_type>,
888                      "optional<T>::value_or: U must be convertible to T");
889        return this->has_value() ? this->__get() :
890                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
891    }
892
893    template <class _Up>
894    _LIBCPP_INLINE_VISIBILITY
895    value_type value_or(_Up&& __v) &&
896    {
897        static_assert(is_move_constructible_v<value_type>,
898                      "optional<T>::value_or: T must be move constructible");
899        static_assert(is_convertible_v<_Up, value_type>,
900                      "optional<T>::value_or: U must be convertible to T");
901        return this->has_value() ? _VSTD::move(this->__get()) :
902                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
903    }
904
905    using __base::reset;
906
907private:
908    template <class _Up>
909    _LIBCPP_INLINE_VISIBILITY
910    static _Up*
911    __operator_arrow(true_type, _Up& __x)
912    {
913        return _VSTD::addressof(__x);
914    }
915
916    template <class _Up>
917    _LIBCPP_INLINE_VISIBILITY
918    static constexpr _Up*
919    __operator_arrow(false_type, _Up& __x)
920    {
921        return &__x;
922    }
923};
924
925// Comparisons between optionals
926template <class _Tp>
927_LIBCPP_INLINE_VISIBILITY constexpr
928enable_if_t<
929    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
930        _VSTD::declval<const _Tp&>()), bool>,
931    bool
932>
933operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
934{
935    if (static_cast<bool>(__x) != static_cast<bool>(__y))
936        return false;
937    if (!static_cast<bool>(__x))
938        return true;
939    return *__x == *__y;
940}
941
942template <class _Tp>
943_LIBCPP_INLINE_VISIBILITY constexpr
944enable_if_t<
945    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
946        _VSTD::declval<const _Tp&>()), bool>,
947    bool
948>
949operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
950{
951    if (static_cast<bool>(__x) != static_cast<bool>(__y))
952        return true;
953    if (!static_cast<bool>(__x))
954        return false;
955    return *__x != *__y;
956}
957
958template <class _Tp>
959_LIBCPP_INLINE_VISIBILITY constexpr
960enable_if_t<
961    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
962        _VSTD::declval<const _Tp&>()), bool>,
963    bool
964>
965operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
966{
967    if (!static_cast<bool>(__y))
968        return false;
969    if (!static_cast<bool>(__x))
970        return true;
971    return *__x < *__y;
972}
973
974template <class _Tp>
975_LIBCPP_INLINE_VISIBILITY constexpr
976enable_if_t<
977    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
978        _VSTD::declval<const _Tp&>()), bool>,
979    bool
980>
981operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
982{
983    if (!static_cast<bool>(__x))
984        return false;
985    if (!static_cast<bool>(__y))
986        return true;
987    return *__x > *__y;
988}
989
990template <class _Tp>
991_LIBCPP_INLINE_VISIBILITY constexpr
992enable_if_t<
993    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
994        _VSTD::declval<const _Tp&>()), bool>,
995    bool
996>
997operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
998{
999    if (!static_cast<bool>(__x))
1000        return true;
1001    if (!static_cast<bool>(__y))
1002        return false;
1003    return *__x <= *__y;
1004}
1005
1006template <class _Tp>
1007_LIBCPP_INLINE_VISIBILITY constexpr
1008enable_if_t<
1009    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1010        _VSTD::declval<const _Tp&>()), bool>,
1011    bool
1012>
1013operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1014{
1015    if (!static_cast<bool>(__y))
1016        return true;
1017    if (!static_cast<bool>(__x))
1018        return false;
1019    return *__x >= *__y;
1020}
1021
1022// Comparisons with nullopt
1023template <class _Tp>
1024_LIBCPP_INLINE_VISIBILITY constexpr
1025bool
1026operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1027{
1028    return !static_cast<bool>(__x);
1029}
1030
1031template <class _Tp>
1032_LIBCPP_INLINE_VISIBILITY constexpr
1033bool
1034operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1035{
1036    return !static_cast<bool>(__x);
1037}
1038
1039template <class _Tp>
1040_LIBCPP_INLINE_VISIBILITY constexpr
1041bool
1042operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1043{
1044    return static_cast<bool>(__x);
1045}
1046
1047template <class _Tp>
1048_LIBCPP_INLINE_VISIBILITY constexpr
1049bool
1050operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1051{
1052    return static_cast<bool>(__x);
1053}
1054
1055template <class _Tp>
1056_LIBCPP_INLINE_VISIBILITY constexpr
1057bool
1058operator<(const optional<_Tp>&, nullopt_t) noexcept
1059{
1060    return false;
1061}
1062
1063template <class _Tp>
1064_LIBCPP_INLINE_VISIBILITY constexpr
1065bool
1066operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1067{
1068    return static_cast<bool>(__x);
1069}
1070
1071template <class _Tp>
1072_LIBCPP_INLINE_VISIBILITY constexpr
1073bool
1074operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1075{
1076    return !static_cast<bool>(__x);
1077}
1078
1079template <class _Tp>
1080_LIBCPP_INLINE_VISIBILITY constexpr
1081bool
1082operator<=(nullopt_t, const optional<_Tp>&) noexcept
1083{
1084    return true;
1085}
1086
1087template <class _Tp>
1088_LIBCPP_INLINE_VISIBILITY constexpr
1089bool
1090operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1091{
1092    return static_cast<bool>(__x);
1093}
1094
1095template <class _Tp>
1096_LIBCPP_INLINE_VISIBILITY constexpr
1097bool
1098operator>(nullopt_t, const optional<_Tp>&) noexcept
1099{
1100    return false;
1101}
1102
1103template <class _Tp>
1104_LIBCPP_INLINE_VISIBILITY constexpr
1105bool
1106operator>=(const optional<_Tp>&, nullopt_t) noexcept
1107{
1108    return true;
1109}
1110
1111template <class _Tp>
1112_LIBCPP_INLINE_VISIBILITY constexpr
1113bool
1114operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1115{
1116    return !static_cast<bool>(__x);
1117}
1118
1119// Comparisons with T
1120template <class _Tp>
1121_LIBCPP_INLINE_VISIBILITY constexpr
1122enable_if_t<
1123    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1124        _VSTD::declval<const _Tp&>()), bool>,
1125    bool
1126>
1127operator==(const optional<_Tp>& __x, const _Tp& __v)
1128{
1129    return static_cast<bool>(__x) ? *__x == __v : false;
1130}
1131
1132template <class _Tp>
1133_LIBCPP_INLINE_VISIBILITY constexpr
1134enable_if_t<
1135    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1136        _VSTD::declval<const _Tp&>()), bool>,
1137    bool
1138>
1139operator==(const _Tp& __v, const optional<_Tp>& __x)
1140{
1141    return static_cast<bool>(__x) ? __v == *__x : false;
1142}
1143
1144template <class _Tp>
1145_LIBCPP_INLINE_VISIBILITY constexpr
1146enable_if_t<
1147    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1148        _VSTD::declval<const _Tp&>()), bool>,
1149    bool
1150>
1151operator!=(const optional<_Tp>& __x, const _Tp& __v)
1152{
1153    return static_cast<bool>(__x) ? *__x != __v : true;
1154}
1155
1156template <class _Tp>
1157_LIBCPP_INLINE_VISIBILITY constexpr
1158enable_if_t<
1159    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1160        _VSTD::declval<const _Tp&>()), bool>,
1161    bool
1162>
1163operator!=(const _Tp& __v, const optional<_Tp>& __x)
1164{
1165    return static_cast<bool>(__x) ? __v != *__x : true;
1166}
1167
1168template <class _Tp>
1169_LIBCPP_INLINE_VISIBILITY constexpr
1170enable_if_t<
1171    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1172        _VSTD::declval<const _Tp&>()), bool>,
1173    bool
1174>
1175operator<(const optional<_Tp>& __x, const _Tp& __v)
1176{
1177    return static_cast<bool>(__x) ? *__x < __v : true;
1178}
1179
1180template <class _Tp>
1181_LIBCPP_INLINE_VISIBILITY constexpr
1182enable_if_t<
1183    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1184        _VSTD::declval<const _Tp&>()), bool>,
1185    bool
1186>
1187operator<(const _Tp& __v, const optional<_Tp>& __x)
1188{
1189    return static_cast<bool>(__x) ? __v < *__x : false;
1190}
1191
1192template <class _Tp>
1193_LIBCPP_INLINE_VISIBILITY constexpr
1194enable_if_t<
1195    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1196        _VSTD::declval<const _Tp&>()), bool>,
1197    bool
1198>
1199operator<=(const optional<_Tp>& __x, const _Tp& __v)
1200{
1201    return static_cast<bool>(__x) ? *__x <= __v : true;
1202}
1203
1204template <class _Tp>
1205_LIBCPP_INLINE_VISIBILITY constexpr
1206enable_if_t<
1207    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1208        _VSTD::declval<const _Tp&>()), bool>,
1209    bool
1210>
1211operator<=(const _Tp& __v, const optional<_Tp>& __x)
1212{
1213    return static_cast<bool>(__x) ? __v <= *__x : false;
1214}
1215
1216template <class _Tp>
1217_LIBCPP_INLINE_VISIBILITY constexpr
1218enable_if_t<
1219    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1220        _VSTD::declval<const _Tp&>()), bool>,
1221    bool
1222>
1223operator>(const optional<_Tp>& __x, const _Tp& __v)
1224{
1225    return static_cast<bool>(__x) ? *__x > __v : false;
1226}
1227
1228template <class _Tp>
1229_LIBCPP_INLINE_VISIBILITY constexpr
1230enable_if_t<
1231    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1232        _VSTD::declval<const _Tp&>()), bool>,
1233    bool
1234>
1235operator>(const _Tp& __v, const optional<_Tp>& __x)
1236{
1237    return static_cast<bool>(__x) ? __v > *__x : true;
1238}
1239
1240template <class _Tp>
1241_LIBCPP_INLINE_VISIBILITY constexpr
1242enable_if_t<
1243    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1244        _VSTD::declval<const _Tp&>()), bool>,
1245    bool
1246>
1247operator>=(const optional<_Tp>& __x, const _Tp& __v)
1248{
1249    return static_cast<bool>(__x) ? *__x >= __v : false;
1250}
1251
1252template <class _Tp>
1253_LIBCPP_INLINE_VISIBILITY constexpr
1254enable_if_t<
1255    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1256        _VSTD::declval<const _Tp&>()), bool>,
1257    bool
1258>
1259operator>=(const _Tp& __v, const optional<_Tp>& __x)
1260{
1261    return static_cast<bool>(__x) ? __v >= *__x : true;
1262}
1263
1264
1265template <class _Tp>
1266inline _LIBCPP_INLINE_VISIBILITY
1267enable_if_t<
1268    is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1269    void
1270>
1271swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1272{
1273    __x.swap(__y);
1274}
1275
1276template <class _Tp>
1277_LIBCPP_INLINE_VISIBILITY constexpr
1278optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1279{
1280    return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1281}
1282
1283template <class _Tp, class... _Args>
1284_LIBCPP_INLINE_VISIBILITY constexpr
1285optional<_Tp> make_optional(_Args&&... __args)
1286{
1287    return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1288}
1289
1290template <class _Tp, class _Up, class... _Args>
1291_LIBCPP_INLINE_VISIBILITY constexpr
1292optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1293{
1294    return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1295}
1296
1297template <class _Tp>
1298struct _LIBCPP_TEMPLATE_VIS hash<optional<_Tp> >
1299{
1300    typedef optional<_Tp> argument_type;
1301    typedef size_t        result_type;
1302
1303    _LIBCPP_INLINE_VISIBILITY
1304    result_type operator()(const argument_type& __opt) const _NOEXCEPT
1305    {
1306        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1307    }
1308};
1309
1310_LIBCPP_END_NAMESPACE_STD
1311
1312#endif  // _LIBCPP_STD_VER > 14
1313
1314#endif  // _LIBCPP_OPTIONAL
1315