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