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