2 //===-------------------------- optional ----------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_OPTIONAL
12 #define _LIBCPP_OPTIONAL
20 // 23.6.3, optional for object types
21 template <class T> class optional;
23 // 23.6.4, no-value state indicator
24 struct nullopt_t{see below };
25 constexpr nullopt_t nullopt(unspecified );
27 // 23.6.5, class bad_optional_access
28 class bad_optional_access;
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>&);
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;
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>&);
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);
80 // 23.6.10, hash support
81 template <class T> struct hash;
82 template <class T> struct hash<optional<T>>;
84 template <class T> class optional {
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 &&);
99 constexpr EXPLICIT optional(const optional<U> &);
101 constexpr EXPLICIT optional(optional<U> &&);
103 // 23.6.3.2, destructor
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 &&...);
118 void swap(optional &) noexcept(see below );
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 &&) &&;
136 // 23.6.3.6, modifiers
137 void reset() noexcept;
140 T *val; // exposition only
148 #include <__functional_base>
149 #include <functional>
150 #include <initializer_list>
153 #include <type_traits>
156 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
157 #pragma GCC system_header
161 #include <__undef_macros>
164 namespace std // purposefully not using versioning namespace
167 class _LIBCPP_EXCEPTION_ABI bad_optional_access
171 // Get the key function ~bad_optional_access() into the dylib
172 virtual ~bad_optional_access() _NOEXCEPT;
173 virtual const char* what() const _NOEXCEPT;
178 #if _LIBCPP_STD_VER > 14
180 _LIBCPP_BEGIN_NAMESPACE_STD
183 inline _LIBCPP_INLINE_VISIBILITY
184 void __throw_bad_optional_access() {
185 #ifndef _LIBCPP_NO_EXCEPTIONS
186 throw bad_optional_access();
194 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
195 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
198 /* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
200 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
201 struct __optional_destruct_base;
204 struct __optional_destruct_base<_Tp, false>
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");
216 _LIBCPP_INLINE_VISIBILITY
217 ~__optional_destruct_base()
220 __val_.~value_type();
223 _LIBCPP_INLINE_VISIBILITY
224 constexpr __optional_destruct_base() noexcept
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)...),
234 _LIBCPP_INLINE_VISIBILITY
235 void reset() noexcept
239 __val_.~value_type();
246 struct __optional_destruct_base<_Tp, true>
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");
258 _LIBCPP_INLINE_VISIBILITY
259 constexpr __optional_destruct_base() noexcept
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)...),
269 _LIBCPP_INLINE_VISIBILITY
270 void reset() noexcept
279 template <class _Tp, bool = is_reference<_Tp>::value>
280 struct __optional_storage_base : __optional_destruct_base<_Tp>
282 using __base = __optional_destruct_base<_Tp>;
283 using value_type = _Tp;
284 using __base::__base;
286 _LIBCPP_INLINE_VISIBILITY
287 constexpr bool has_value() const noexcept
289 return this->__engaged_;
292 _LIBCPP_INLINE_VISIBILITY
293 constexpr value_type& __get() & noexcept
297 _LIBCPP_INLINE_VISIBILITY
298 constexpr const value_type& __get() const& noexcept
302 _LIBCPP_INLINE_VISIBILITY
303 constexpr value_type&& __get() && noexcept
305 return _VSTD::move(this->__val_);
307 _LIBCPP_INLINE_VISIBILITY
308 constexpr const value_type&& __get() const&& noexcept
310 return _VSTD::move(this->__val_);
313 template <class... _Args>
314 _LIBCPP_INLINE_VISIBILITY
315 void __construct(_Args&&... __args)
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;
322 template <class _That>
323 _LIBCPP_INLINE_VISIBILITY
324 void __construct_from(_That&& __opt)
326 if (__opt.has_value())
327 __construct(_VSTD::forward<_That>(__opt).__get());
330 template <class _That>
331 _LIBCPP_INLINE_VISIBILITY
332 void __assign_from(_That&& __opt)
334 if (this->__engaged_ == __opt.has_value())
336 if (this->__engaged_)
337 this->__val_ = _VSTD::forward<_That>(__opt).__get();
341 if (this->__engaged_)
344 __construct(_VSTD::forward<_That>(__opt).__get());
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.
353 struct __optional_storage_base<_Tp, true>
355 using value_type = _Tp;
356 using __raw_type = remove_reference_t<_Tp>;
357 __raw_type* __value_;
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
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);
375 _LIBCPP_INLINE_VISIBILITY
376 constexpr __optional_storage_base() noexcept
377 : __value_(nullptr) {}
379 template <class _UArg>
380 _LIBCPP_INLINE_VISIBILITY
381 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
382 : __value_(_VSTD::addressof(__uarg))
384 static_assert(__can_bind_reference<_UArg>(),
385 "Attempted to construct a reference element in tuple from a "
386 "possible temporary");
389 _LIBCPP_INLINE_VISIBILITY
390 void reset() noexcept { __value_ = nullptr; }
392 _LIBCPP_INLINE_VISIBILITY
393 constexpr bool has_value() const noexcept
394 { return __value_ != nullptr; }
396 _LIBCPP_INLINE_VISIBILITY
397 constexpr value_type& __get() const& noexcept
398 { return *__value_; }
400 _LIBCPP_INLINE_VISIBILITY
401 constexpr value_type&& __get() const&& noexcept
402 { return _VSTD::forward<value_type>(*__value_); }
404 template <class _UArg>
405 _LIBCPP_INLINE_VISIBILITY
406 void __construct(_UArg&& __val)
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);
415 template <class _That>
416 _LIBCPP_INLINE_VISIBILITY
417 void __construct_from(_That&& __opt)
419 if (__opt.has_value())
420 __construct(_VSTD::forward<_That>(__opt).__get());
423 template <class _That>
424 _LIBCPP_INLINE_VISIBILITY
425 void __assign_from(_That&& __opt)
427 if (has_value() == __opt.has_value())
430 *__value_ = _VSTD::forward<_That>(__opt).__get();
437 __construct(_VSTD::forward<_That>(__opt).__get());
442 template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
443 struct __optional_storage;
446 struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
448 using __optional_storage_base<_Tp>::__optional_storage_base;
452 struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
454 using value_type = _Tp;
455 using __optional_storage_base<_Tp>::__optional_storage_base;
457 _LIBCPP_INLINE_VISIBILITY
458 __optional_storage() = default;
460 _LIBCPP_INLINE_VISIBILITY
461 __optional_storage(const __optional_storage& __opt)
463 this->__construct_from(__opt);
466 _LIBCPP_INLINE_VISIBILITY
467 __optional_storage(__optional_storage&& __opt)
468 noexcept(is_nothrow_move_constructible_v<value_type>)
470 this->__construct_from(_VSTD::move(__opt));
473 _LIBCPP_INLINE_VISIBILITY
474 __optional_storage& operator=(const __optional_storage& __opt)
476 this->__assign_from(__opt);
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>)
485 this->__assign_from(_VSTD::move(__opt));
491 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
492 is_copy_constructible<_Tp>::value,
493 is_move_constructible<_Tp>::value
497 using __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)
504 : private __optional_storage<_Tp>
505 , private __optional_sfinae_ctor_base_t<_Tp>
506 , private __optional_sfinae_assign_base_t<_Tp>
508 using __base = __optional_storage<_Tp>;
510 using value_type = _Tp;
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");
523 // LWG2756: conditionally explicit conversion from _Up
524 struct _CheckOptionalArgsConstructor {
526 static constexpr bool __enable_implicit() {
527 return is_constructible_v<_Tp, _Up&&> &&
528 is_convertible_v<_Up&&, _Tp>;
532 static constexpr bool __enable_explicit() {
533 return is_constructible_v<_Tp, _Up&&> &&
534 !is_convertible_v<_Up&&, _Tp>;
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
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>
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&&>
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;
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;
574 template <class _Up, class _QUp = _QualUp>
575 static constexpr bool __enable_assign() {
576 // Construction and assignability of _Qup to _Tp has already been
578 return !__check_constructible_from_opt<_Up>::value &&
579 !__check_assignable_from_opt<_Up>::value;
583 template <class _Up, class _QualUp>
584 using _CheckOptionalLikeCtor = conditional_t<
586 __lazy_not<is_same<_Up, _Tp>>,
587 is_constructible<_Tp, _QualUp>
589 _CheckOptionalLikeConstructor<_QualUp>,
590 __check_tuple_constructor_fail
592 template <class _Up, class _QualUp>
593 using _CheckOptionalLikeAssign = conditional_t<
595 __lazy_not<is_same<_Up, _Tp>>,
596 is_constructible<_Tp, _QualUp>,
597 is_assignable<_Tp&, _QualUp>
599 _CheckOptionalLikeConstructor<_QualUp>,
600 __check_tuple_constructor_fail
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 {}
609 template <class... _Args, class = enable_if_t<
610 is_constructible_v<value_type, _Args...>>
612 _LIBCPP_INLINE_VISIBILITY
613 constexpr explicit optional(in_place_t, _Args&&... __args)
614 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
616 template <class _Up, class... _Args, class = enable_if_t<
617 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
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)...) {}
623 template <class _Up = value_type, enable_if_t<
624 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
626 _LIBCPP_INLINE_VISIBILITY
627 constexpr optional(_Up&& __v)
628 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
630 template <class _Up, enable_if_t<
631 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
633 _LIBCPP_INLINE_VISIBILITY
634 constexpr explicit optional(_Up&& __v)
635 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
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>()
641 _LIBCPP_INLINE_VISIBILITY
642 optional(const optional<_Up>& __v)
644 this->__construct_from(__v);
646 template <class _Up, enable_if_t<
647 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
649 _LIBCPP_INLINE_VISIBILITY
650 explicit optional(const optional<_Up>& __v)
652 this->__construct_from(__v);
655 // LWG2756: conditionally explicit conversion from optional<_Up>&&
656 template <class _Up, enable_if_t<
657 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
659 _LIBCPP_INLINE_VISIBILITY
660 optional(optional<_Up>&& __v)
662 this->__construct_from(_VSTD::move(__v));
664 template <class _Up, enable_if_t<
665 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
667 _LIBCPP_INLINE_VISIBILITY
668 explicit optional(optional<_Up>&& __v)
670 this->__construct_from(_VSTD::move(__v));
673 _LIBCPP_INLINE_VISIBILITY
674 optional& operator=(nullopt_t) noexcept
680 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
681 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
684 template <class _Up = value_type,
687 integral_constant<bool,
688 !is_same_v<decay_t<_Up>, optional> &&
689 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
691 is_constructible<value_type, _Up>,
692 is_assignable<value_type&, _Up>
695 _LIBCPP_INLINE_VISIBILITY
699 if (this->has_value())
700 this->__get() = _VSTD::forward<_Up>(__v);
702 this->__construct(_VSTD::forward<_Up>(__v));
707 template <class _Up, enable_if_t<
708 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
710 _LIBCPP_INLINE_VISIBILITY
712 operator=(const optional<_Up>& __v)
714 this->__assign_from(__v);
719 template <class _Up, enable_if_t<
720 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
722 _LIBCPP_INLINE_VISIBILITY
724 operator=(optional<_Up>&& __v)
726 this->__assign_from(_VSTD::move(__v));
730 template <class... _Args,
733 is_constructible_v<value_type, _Args...>
736 _LIBCPP_INLINE_VISIBILITY
738 emplace(_Args&&... __args)
741 this->__construct(_VSTD::forward<_Args>(__args)...);
742 return this->__get();
745 template <class _Up, class... _Args,
748 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
751 _LIBCPP_INLINE_VISIBILITY
753 emplace(initializer_list<_Up> __il, _Args&&... __args)
756 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
757 return this->__get();
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>)
765 if (this->has_value() == __opt.has_value())
768 if (this->has_value())
769 swap(this->__get(), __opt.__get());
773 if (this->has_value())
775 __opt.__construct(_VSTD::move(this->__get()));
780 this->__construct(_VSTD::move(__opt.__get()));
786 _LIBCPP_INLINE_VISIBILITY
788 add_pointer_t<value_type const>
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());
795 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
799 _LIBCPP_INLINE_VISIBILITY
801 add_pointer_t<value_type>
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());
808 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
812 _LIBCPP_INLINE_VISIBILITY
817 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
818 return this->__get();
821 _LIBCPP_INLINE_VISIBILITY
826 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
827 return this->__get();
830 _LIBCPP_INLINE_VISIBILITY
835 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
836 return _VSTD::move(this->__get());
839 _LIBCPP_INLINE_VISIBILITY
844 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
845 return _VSTD::move(this->__get());
848 _LIBCPP_INLINE_VISIBILITY
849 constexpr explicit operator bool() const noexcept { return has_value(); }
851 using __base::has_value;
854 _LIBCPP_INLINE_VISIBILITY
855 constexpr value_type const& value() const&
857 if (!this->has_value())
858 __throw_bad_optional_access();
859 return this->__get();
862 _LIBCPP_INLINE_VISIBILITY
863 constexpr value_type& value() &
865 if (!this->has_value())
866 __throw_bad_optional_access();
867 return this->__get();
870 _LIBCPP_INLINE_VISIBILITY
871 constexpr value_type&& value() &&
873 if (!this->has_value())
874 __throw_bad_optional_access();
875 return _VSTD::move(this->__get());
878 _LIBCPP_INLINE_VISIBILITY
879 constexpr value_type const&& value() const&&
881 if (!this->has_value())
882 __throw_bad_optional_access();
883 return _VSTD::move(this->__get());
887 _LIBCPP_INLINE_VISIBILITY
888 constexpr value_type value_or(_Up&& __v) const&
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));
899 _LIBCPP_INLINE_VISIBILITY
900 constexpr value_type value_or(_Up&& __v) &&
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));
914 _LIBCPP_INLINE_VISIBILITY
916 __operator_arrow(true_type, _Up& __x)
918 return _VSTD::addressof(__x);
922 _LIBCPP_INLINE_VISIBILITY
923 static constexpr _Up*
924 __operator_arrow(false_type, _Up& __x)
930 // Comparisons between optionals
931 template <class _Tp, class _Up>
932 _LIBCPP_INLINE_VISIBILITY constexpr
934 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
935 _VSTD::declval<const _Up&>()), bool>,
938 operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
940 if (static_cast<bool>(__x) != static_cast<bool>(__y))
942 if (!static_cast<bool>(__x))
947 template <class _Tp, class _Up>
948 _LIBCPP_INLINE_VISIBILITY constexpr
950 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
951 _VSTD::declval<const _Up&>()), bool>,
954 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
956 if (static_cast<bool>(__x) != static_cast<bool>(__y))
958 if (!static_cast<bool>(__x))
963 template <class _Tp, class _Up>
964 _LIBCPP_INLINE_VISIBILITY constexpr
966 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
967 _VSTD::declval<const _Up&>()), bool>,
970 operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
972 if (!static_cast<bool>(__y))
974 if (!static_cast<bool>(__x))
979 template <class _Tp, class _Up>
980 _LIBCPP_INLINE_VISIBILITY constexpr
982 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
983 _VSTD::declval<const _Up&>()), bool>,
986 operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
988 if (!static_cast<bool>(__x))
990 if (!static_cast<bool>(__y))
995 template <class _Tp, class _Up>
996 _LIBCPP_INLINE_VISIBILITY constexpr
998 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
999 _VSTD::declval<const _Up&>()), bool>,
1002 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1004 if (!static_cast<bool>(__x))
1006 if (!static_cast<bool>(__y))
1008 return *__x <= *__y;
1011 template <class _Tp, class _Up>
1012 _LIBCPP_INLINE_VISIBILITY constexpr
1014 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1015 _VSTD::declval<const _Up&>()), bool>,
1018 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1020 if (!static_cast<bool>(__y))
1022 if (!static_cast<bool>(__x))
1024 return *__x >= *__y;
1027 // Comparisons with nullopt
1028 template <class _Tp>
1029 _LIBCPP_INLINE_VISIBILITY constexpr
1031 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1033 return !static_cast<bool>(__x);
1036 template <class _Tp>
1037 _LIBCPP_INLINE_VISIBILITY constexpr
1039 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1041 return !static_cast<bool>(__x);
1044 template <class _Tp>
1045 _LIBCPP_INLINE_VISIBILITY constexpr
1047 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1049 return static_cast<bool>(__x);
1052 template <class _Tp>
1053 _LIBCPP_INLINE_VISIBILITY constexpr
1055 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1057 return static_cast<bool>(__x);
1060 template <class _Tp>
1061 _LIBCPP_INLINE_VISIBILITY constexpr
1063 operator<(const optional<_Tp>&, nullopt_t) noexcept
1068 template <class _Tp>
1069 _LIBCPP_INLINE_VISIBILITY constexpr
1071 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1073 return static_cast<bool>(__x);
1076 template <class _Tp>
1077 _LIBCPP_INLINE_VISIBILITY constexpr
1079 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1081 return !static_cast<bool>(__x);
1084 template <class _Tp>
1085 _LIBCPP_INLINE_VISIBILITY constexpr
1087 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1092 template <class _Tp>
1093 _LIBCPP_INLINE_VISIBILITY constexpr
1095 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1097 return static_cast<bool>(__x);
1100 template <class _Tp>
1101 _LIBCPP_INLINE_VISIBILITY constexpr
1103 operator>(nullopt_t, const optional<_Tp>&) noexcept
1108 template <class _Tp>
1109 _LIBCPP_INLINE_VISIBILITY constexpr
1111 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1116 template <class _Tp>
1117 _LIBCPP_INLINE_VISIBILITY constexpr
1119 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1121 return !static_cast<bool>(__x);
1124 // Comparisons with T
1125 template <class _Tp, class _Up>
1126 _LIBCPP_INLINE_VISIBILITY constexpr
1128 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1129 _VSTD::declval<const _Up&>()), bool>,
1132 operator==(const optional<_Tp>& __x, const _Up& __v)
1134 return static_cast<bool>(__x) ? *__x == __v : false;
1137 template <class _Tp, class _Up>
1138 _LIBCPP_INLINE_VISIBILITY constexpr
1140 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1141 _VSTD::declval<const _Up&>()), bool>,
1144 operator==(const _Tp& __v, const optional<_Up>& __x)
1146 return static_cast<bool>(__x) ? __v == *__x : false;
1149 template <class _Tp, class _Up>
1150 _LIBCPP_INLINE_VISIBILITY constexpr
1152 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1153 _VSTD::declval<const _Up&>()), bool>,
1156 operator!=(const optional<_Tp>& __x, const _Up& __v)
1158 return static_cast<bool>(__x) ? *__x != __v : true;
1161 template <class _Tp, class _Up>
1162 _LIBCPP_INLINE_VISIBILITY constexpr
1164 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1165 _VSTD::declval<const _Up&>()), bool>,
1168 operator!=(const _Tp& __v, const optional<_Up>& __x)
1170 return static_cast<bool>(__x) ? __v != *__x : true;
1173 template <class _Tp, class _Up>
1174 _LIBCPP_INLINE_VISIBILITY constexpr
1176 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1177 _VSTD::declval<const _Up&>()), bool>,
1180 operator<(const optional<_Tp>& __x, const _Up& __v)
1182 return static_cast<bool>(__x) ? *__x < __v : true;
1185 template <class _Tp, class _Up>
1186 _LIBCPP_INLINE_VISIBILITY constexpr
1188 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1189 _VSTD::declval<const _Up&>()), bool>,
1192 operator<(const _Tp& __v, const optional<_Up>& __x)
1194 return static_cast<bool>(__x) ? __v < *__x : false;
1197 template <class _Tp, class _Up>
1198 _LIBCPP_INLINE_VISIBILITY constexpr
1200 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1201 _VSTD::declval<const _Up&>()), bool>,
1204 operator<=(const optional<_Tp>& __x, const _Up& __v)
1206 return static_cast<bool>(__x) ? *__x <= __v : true;
1209 template <class _Tp, class _Up>
1210 _LIBCPP_INLINE_VISIBILITY constexpr
1212 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1213 _VSTD::declval<const _Up&>()), bool>,
1216 operator<=(const _Tp& __v, const optional<_Up>& __x)
1218 return static_cast<bool>(__x) ? __v <= *__x : false;
1221 template <class _Tp, class _Up>
1222 _LIBCPP_INLINE_VISIBILITY constexpr
1224 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1225 _VSTD::declval<const _Up&>()), bool>,
1228 operator>(const optional<_Tp>& __x, const _Up& __v)
1230 return static_cast<bool>(__x) ? *__x > __v : false;
1233 template <class _Tp, class _Up>
1234 _LIBCPP_INLINE_VISIBILITY constexpr
1236 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1237 _VSTD::declval<const _Up&>()), bool>,
1240 operator>(const _Tp& __v, const optional<_Up>& __x)
1242 return static_cast<bool>(__x) ? __v > *__x : true;
1245 template <class _Tp, class _Up>
1246 _LIBCPP_INLINE_VISIBILITY constexpr
1248 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1249 _VSTD::declval<const _Up&>()), bool>,
1252 operator>=(const optional<_Tp>& __x, const _Up& __v)
1254 return static_cast<bool>(__x) ? *__x >= __v : false;
1257 template <class _Tp, class _Up>
1258 _LIBCPP_INLINE_VISIBILITY constexpr
1260 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1261 _VSTD::declval<const _Up&>()), bool>,
1264 operator>=(const _Tp& __v, const optional<_Up>& __x)
1266 return static_cast<bool>(__x) ? __v >= *__x : true;
1270 template <class _Tp>
1271 inline _LIBCPP_INLINE_VISIBILITY
1273 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1276 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1281 template <class _Tp>
1282 _LIBCPP_INLINE_VISIBILITY constexpr
1283 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1285 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1288 template <class _Tp, class... _Args>
1289 _LIBCPP_INLINE_VISIBILITY constexpr
1290 optional<_Tp> make_optional(_Args&&... __args)
1292 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1295 template <class _Tp, class _Up, class... _Args>
1296 _LIBCPP_INLINE_VISIBILITY constexpr
1297 optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1299 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1302 template <class _Tp>
1303 struct _LIBCPP_TEMPLATE_VIS hash<
1304 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1307 typedef optional<_Tp> argument_type;
1308 typedef size_t result_type;
1310 _LIBCPP_INLINE_VISIBILITY
1311 result_type operator()(const argument_type& __opt) const
1313 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1317 _LIBCPP_END_NAMESPACE_STD
1319 #endif // _LIBCPP_STD_VER > 14
1323 #endif // _LIBCPP_OPTIONAL