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                      <__lazy_and<
685                          integral_constant<bool,
686                              !is_same_v<decay_t<_Up>, optional> &&
687                              !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
688                          >,
689                          is_constructible<value_type, _Up>,
690                          is_assignable<value_type&, _Up>
691                      >::value>
692             >
693    _LIBCPP_INLINE_VISIBILITY
694    optional&
695    operator=(_Up&& __v)
696    {
697        if (this->has_value())
698            this->__get() = _VSTD::forward<_Up>(__v);
699        else
700            this->__construct(_VSTD::forward<_Up>(__v));
701        return *this;
702    }
703
704    // LWG2756
705    template <class _Up, enable_if_t<
706        _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
707    , int> = 0>
708    _LIBCPP_INLINE_VISIBILITY
709    optional&
710    operator=(const optional<_Up>& __v)
711    {
712        this->__assign_from(__v);
713        return *this;
714    }
715
716    // LWG2756
717    template <class _Up, enable_if_t<
718        _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
719    , int> = 0>
720    _LIBCPP_INLINE_VISIBILITY
721    optional&
722    operator=(optional<_Up>&& __v)
723    {
724        this->__assign_from(_VSTD::move(__v));
725        return *this;
726    }
727
728    template <class... _Args,
729              class = enable_if_t
730                      <
731                          is_constructible_v<value_type, _Args...>
732                      >
733             >
734    _LIBCPP_INLINE_VISIBILITY
735    void
736    emplace(_Args&&... __args)
737    {
738        reset();
739        this->__construct(_VSTD::forward<_Args>(__args)...);
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    void
750    emplace(initializer_list<_Up> __il, _Args&&... __args)
751    {
752        reset();
753        this->__construct(__il, _VSTD::forward<_Args>(__args)...);
754    }
755
756    _LIBCPP_INLINE_VISIBILITY
757    void swap(optional& __opt)
758        noexcept(is_nothrow_move_constructible_v<value_type> &&
759                 is_nothrow_swappable_v<value_type>)
760    {
761        if (this->has_value() == __opt.has_value())
762        {
763            using _VSTD::swap;
764            if (this->has_value())
765                swap(this->__get(), __opt.__get());
766        }
767        else
768        {
769            if (this->has_value())
770            {
771                __opt.__construct(_VSTD::move(this->__get()));
772                reset();
773            }
774            else
775            {
776                this->__construct(_VSTD::move(__opt.__get()));
777                __opt.reset();
778            }
779        }
780    }
781
782    _LIBCPP_INLINE_VISIBILITY
783    constexpr
784    add_pointer_t<value_type const>
785    operator->() const
786    {
787        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
788#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
789        return _VSTD::addressof(this->__get());
790#else
791        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
792#endif
793    }
794
795    _LIBCPP_INLINE_VISIBILITY
796    constexpr
797    add_pointer_t<value_type>
798    operator->()
799    {
800        _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
801#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
802        return _VSTD::addressof(this->__get());
803#else
804        return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
805#endif
806    }
807
808    _LIBCPP_INLINE_VISIBILITY
809    constexpr
810    const value_type&
811    operator*() const&
812    {
813        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
814        return this->__get();
815    }
816
817    _LIBCPP_INLINE_VISIBILITY
818    constexpr
819    value_type&
820    operator*() &
821    {
822        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
823        return this->__get();
824    }
825
826    _LIBCPP_INLINE_VISIBILITY
827    constexpr
828    value_type&&
829    operator*() &&
830    {
831        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
832        return _VSTD::move(this->__get());
833    }
834
835    _LIBCPP_INLINE_VISIBILITY
836    constexpr
837    const value_type&&
838    operator*() const&&
839    {
840        _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
841        return _VSTD::move(this->__get());
842    }
843
844    _LIBCPP_INLINE_VISIBILITY
845    constexpr explicit operator bool() const noexcept { return has_value(); }
846
847    using __base::has_value;
848    using __base::__get;
849
850    _LIBCPP_INLINE_VISIBILITY
851    constexpr value_type const& value() const&
852    {
853        if (!this->has_value())
854            __throw_bad_optional_access();
855        return this->__get();
856    }
857
858    _LIBCPP_INLINE_VISIBILITY
859    constexpr value_type& value() &
860    {
861        if (!this->has_value())
862            __throw_bad_optional_access();
863        return this->__get();
864    }
865
866    _LIBCPP_INLINE_VISIBILITY
867    constexpr value_type&& value() &&
868    {
869        if (!this->has_value())
870            __throw_bad_optional_access();
871        return _VSTD::move(this->__get());
872    }
873
874    _LIBCPP_INLINE_VISIBILITY
875    constexpr value_type const&& value() const&&
876    {
877        if (!this->has_value())
878            __throw_bad_optional_access();
879        return _VSTD::move(this->__get());
880    }
881
882    template <class _Up>
883    _LIBCPP_INLINE_VISIBILITY
884    constexpr value_type value_or(_Up&& __v) const&
885    {
886        static_assert(is_copy_constructible_v<value_type>,
887                      "optional<T>::value_or: T must be copy constructible");
888        static_assert(is_convertible_v<_Up, value_type>,
889                      "optional<T>::value_or: U must be convertible to T");
890        return this->has_value() ? this->__get() :
891                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
892    }
893
894    template <class _Up>
895    _LIBCPP_INLINE_VISIBILITY
896    value_type value_or(_Up&& __v) &&
897    {
898        static_assert(is_move_constructible_v<value_type>,
899                      "optional<T>::value_or: T must be move constructible");
900        static_assert(is_convertible_v<_Up, value_type>,
901                      "optional<T>::value_or: U must be convertible to T");
902        return this->has_value() ? _VSTD::move(this->__get()) :
903                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
904    }
905
906    using __base::reset;
907
908private:
909    template <class _Up>
910    _LIBCPP_INLINE_VISIBILITY
911    static _Up*
912    __operator_arrow(true_type, _Up& __x)
913    {
914        return _VSTD::addressof(__x);
915    }
916
917    template <class _Up>
918    _LIBCPP_INLINE_VISIBILITY
919    static constexpr _Up*
920    __operator_arrow(false_type, _Up& __x)
921    {
922        return &__x;
923    }
924};
925
926// Comparisons between optionals
927template <class _Tp>
928_LIBCPP_INLINE_VISIBILITY constexpr
929enable_if_t<
930    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
931        _VSTD::declval<const _Tp&>()), bool>,
932    bool
933>
934operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
935{
936    if (static_cast<bool>(__x) != static_cast<bool>(__y))
937        return false;
938    if (!static_cast<bool>(__x))
939        return true;
940    return *__x == *__y;
941}
942
943template <class _Tp>
944_LIBCPP_INLINE_VISIBILITY constexpr
945enable_if_t<
946    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
947        _VSTD::declval<const _Tp&>()), bool>,
948    bool
949>
950operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
951{
952    if (static_cast<bool>(__x) != static_cast<bool>(__y))
953        return true;
954    if (!static_cast<bool>(__x))
955        return false;
956    return *__x != *__y;
957}
958
959template <class _Tp>
960_LIBCPP_INLINE_VISIBILITY constexpr
961enable_if_t<
962    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
963        _VSTD::declval<const _Tp&>()), bool>,
964    bool
965>
966operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
967{
968    if (!static_cast<bool>(__y))
969        return false;
970    if (!static_cast<bool>(__x))
971        return true;
972    return *__x < *__y;
973}
974
975template <class _Tp>
976_LIBCPP_INLINE_VISIBILITY constexpr
977enable_if_t<
978    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
979        _VSTD::declval<const _Tp&>()), bool>,
980    bool
981>
982operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
983{
984    if (!static_cast<bool>(__x))
985        return false;
986    if (!static_cast<bool>(__y))
987        return true;
988    return *__x > *__y;
989}
990
991template <class _Tp>
992_LIBCPP_INLINE_VISIBILITY constexpr
993enable_if_t<
994    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
995        _VSTD::declval<const _Tp&>()), bool>,
996    bool
997>
998operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
999{
1000    if (!static_cast<bool>(__x))
1001        return true;
1002    if (!static_cast<bool>(__y))
1003        return false;
1004    return *__x <= *__y;
1005}
1006
1007template <class _Tp>
1008_LIBCPP_INLINE_VISIBILITY constexpr
1009enable_if_t<
1010    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1011        _VSTD::declval<const _Tp&>()), bool>,
1012    bool
1013>
1014operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1015{
1016    if (!static_cast<bool>(__y))
1017        return true;
1018    if (!static_cast<bool>(__x))
1019        return false;
1020    return *__x >= *__y;
1021}
1022
1023// Comparisons with nullopt
1024template <class _Tp>
1025_LIBCPP_INLINE_VISIBILITY constexpr
1026bool
1027operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1028{
1029    return !static_cast<bool>(__x);
1030}
1031
1032template <class _Tp>
1033_LIBCPP_INLINE_VISIBILITY constexpr
1034bool
1035operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1036{
1037    return !static_cast<bool>(__x);
1038}
1039
1040template <class _Tp>
1041_LIBCPP_INLINE_VISIBILITY constexpr
1042bool
1043operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1044{
1045    return static_cast<bool>(__x);
1046}
1047
1048template <class _Tp>
1049_LIBCPP_INLINE_VISIBILITY constexpr
1050bool
1051operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1052{
1053    return static_cast<bool>(__x);
1054}
1055
1056template <class _Tp>
1057_LIBCPP_INLINE_VISIBILITY constexpr
1058bool
1059operator<(const optional<_Tp>&, nullopt_t) noexcept
1060{
1061    return false;
1062}
1063
1064template <class _Tp>
1065_LIBCPP_INLINE_VISIBILITY constexpr
1066bool
1067operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1068{
1069    return static_cast<bool>(__x);
1070}
1071
1072template <class _Tp>
1073_LIBCPP_INLINE_VISIBILITY constexpr
1074bool
1075operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1076{
1077    return !static_cast<bool>(__x);
1078}
1079
1080template <class _Tp>
1081_LIBCPP_INLINE_VISIBILITY constexpr
1082bool
1083operator<=(nullopt_t, const optional<_Tp>& __x) noexcept
1084{
1085    return true;
1086}
1087
1088template <class _Tp>
1089_LIBCPP_INLINE_VISIBILITY constexpr
1090bool
1091operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1092{
1093    return static_cast<bool>(__x);
1094}
1095
1096template <class _Tp>
1097_LIBCPP_INLINE_VISIBILITY constexpr
1098bool
1099operator>(nullopt_t, const optional<_Tp>& __x) noexcept
1100{
1101    return false;
1102}
1103
1104template <class _Tp>
1105_LIBCPP_INLINE_VISIBILITY constexpr
1106bool
1107operator>=(const optional<_Tp>&, nullopt_t) noexcept
1108{
1109    return true;
1110}
1111
1112template <class _Tp>
1113_LIBCPP_INLINE_VISIBILITY constexpr
1114bool
1115operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1116{
1117    return !static_cast<bool>(__x);
1118}
1119
1120// Comparisons with T
1121template <class _Tp>
1122_LIBCPP_INLINE_VISIBILITY constexpr
1123enable_if_t<
1124    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1125        _VSTD::declval<const _Tp&>()), bool>,
1126    bool
1127>
1128operator==(const optional<_Tp>& __x, const _Tp& __v)
1129{
1130    return static_cast<bool>(__x) ? *__x == __v : false;
1131}
1132
1133template <class _Tp>
1134_LIBCPP_INLINE_VISIBILITY constexpr
1135enable_if_t<
1136    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1137        _VSTD::declval<const _Tp&>()), bool>,
1138    bool
1139>
1140operator==(const _Tp& __v, const optional<_Tp>& __x)
1141{
1142    return static_cast<bool>(__x) ? __v == *__x : false;
1143}
1144
1145template <class _Tp>
1146_LIBCPP_INLINE_VISIBILITY constexpr
1147enable_if_t<
1148    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1149        _VSTD::declval<const _Tp&>()), bool>,
1150    bool
1151>
1152operator!=(const optional<_Tp>& __x, const _Tp& __v)
1153{
1154    return static_cast<bool>(__x) ? *__x != __v : true;
1155}
1156
1157template <class _Tp>
1158_LIBCPP_INLINE_VISIBILITY constexpr
1159enable_if_t<
1160    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1161        _VSTD::declval<const _Tp&>()), bool>,
1162    bool
1163>
1164operator!=(const _Tp& __v, const optional<_Tp>& __x)
1165{
1166    return static_cast<bool>(__x) ? __v != *__x : true;
1167}
1168
1169template <class _Tp>
1170_LIBCPP_INLINE_VISIBILITY constexpr
1171enable_if_t<
1172    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1173        _VSTD::declval<const _Tp&>()), bool>,
1174    bool
1175>
1176operator<(const optional<_Tp>& __x, const _Tp& __v)
1177{
1178    return static_cast<bool>(__x) ? *__x < __v : true;
1179}
1180
1181template <class _Tp>
1182_LIBCPP_INLINE_VISIBILITY constexpr
1183enable_if_t<
1184    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1185        _VSTD::declval<const _Tp&>()), bool>,
1186    bool
1187>
1188operator<(const _Tp& __v, const optional<_Tp>& __x)
1189{
1190    return static_cast<bool>(__x) ? __v < *__x : false;
1191}
1192
1193template <class _Tp>
1194_LIBCPP_INLINE_VISIBILITY constexpr
1195enable_if_t<
1196    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1197        _VSTD::declval<const _Tp&>()), bool>,
1198    bool
1199>
1200operator<=(const optional<_Tp>& __x, const _Tp& __v)
1201{
1202    return static_cast<bool>(__x) ? *__x <= __v : true;
1203}
1204
1205template <class _Tp>
1206_LIBCPP_INLINE_VISIBILITY constexpr
1207enable_if_t<
1208    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1209        _VSTD::declval<const _Tp&>()), bool>,
1210    bool
1211>
1212operator<=(const _Tp& __v, const optional<_Tp>& __x)
1213{
1214    return static_cast<bool>(__x) ? __v <= *__x : false;
1215}
1216
1217template <class _Tp>
1218_LIBCPP_INLINE_VISIBILITY constexpr
1219enable_if_t<
1220    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1221        _VSTD::declval<const _Tp&>()), bool>,
1222    bool
1223>
1224operator>(const optional<_Tp>& __x, const _Tp& __v)
1225{
1226    return static_cast<bool>(__x) ? *__x > __v : false;
1227}
1228
1229template <class _Tp>
1230_LIBCPP_INLINE_VISIBILITY constexpr
1231enable_if_t<
1232    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1233        _VSTD::declval<const _Tp&>()), bool>,
1234    bool
1235>
1236operator>(const _Tp& __v, const optional<_Tp>& __x)
1237{
1238    return static_cast<bool>(__x) ? __v > *__x : true;
1239}
1240
1241template <class _Tp>
1242_LIBCPP_INLINE_VISIBILITY constexpr
1243enable_if_t<
1244    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1245        _VSTD::declval<const _Tp&>()), bool>,
1246    bool
1247>
1248operator>=(const optional<_Tp>& __x, const _Tp& __v)
1249{
1250    return static_cast<bool>(__x) ? *__x >= __v : false;
1251}
1252
1253template <class _Tp>
1254_LIBCPP_INLINE_VISIBILITY constexpr
1255enable_if_t<
1256    is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1257        _VSTD::declval<const _Tp&>()), bool>,
1258    bool
1259>
1260operator>=(const _Tp& __v, const optional<_Tp>& __x)
1261{
1262    return static_cast<bool>(__x) ? __v >= *__x : true;
1263}
1264
1265
1266template <class _Tp>
1267inline _LIBCPP_INLINE_VISIBILITY
1268enable_if_t<
1269    is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1270    void
1271>
1272swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1273{
1274    __x.swap(__y);
1275}
1276
1277template <class _Tp>
1278_LIBCPP_INLINE_VISIBILITY constexpr
1279optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1280{
1281    return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1282}
1283
1284template <class _Tp, class... _Args>
1285_LIBCPP_INLINE_VISIBILITY constexpr
1286optional<_Tp> make_optional(_Args&&... __args)
1287{
1288    return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1289}
1290
1291template <class _Tp, class _Up, class... _Args>
1292_LIBCPP_INLINE_VISIBILITY constexpr
1293optional<_Tp> make_optional(initializer_list<_Up> __il,  _Args&&... __args)
1294{
1295    return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1296}
1297
1298template <class _Tp>
1299struct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> >
1300{
1301    typedef optional<_Tp> argument_type;
1302    typedef size_t        result_type;
1303
1304    _LIBCPP_INLINE_VISIBILITY
1305    result_type operator()(const argument_type& __opt) const _NOEXCEPT
1306    {
1307        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1308    }
1309};
1310
1311_LIBCPP_END_NAMESPACE_STD
1312
1313#endif  // _LIBCPP_STD_VER > 14
1314
1315#endif  // _LIBCPP_OPTIONAL
1316