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