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 // 20.6.3, optional for object types
21 template <class T> class optional;
23 // 20.6.4, no-value state indicator
24 struct nullopt_t{see below };
25 constexpr nullopt_t nullopt(unspecified );
27 // 20.6.5, class bad_optional_access
28 class bad_optional_access;
30 // 20.6.6, relational operators
32 constexpr bool operator==(const optional<T>&, const optional<T>&);
34 constexpr bool operator!=(const optional<T>&, const optional<T>&);
36 constexpr bool operator<(const optional<T>&, const optional<T>&);
38 constexpr bool operator>(const optional<T>&, const optional<T>&);
40 constexpr bool operator<=(const optional<T>&, const optional<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;
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>&);
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);
78 // 20.6.10, hash support
79 template <class T> struct hash;
80 template <class T> struct hash<optional<T>>;
82 template <class T> class optional {
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 &&);
97 constexpr EXPLICIT optional(const optional<U> &);
99 constexpr EXPLICIT optional(optional<U> &&);
101 // 20.6.3.2, destructor
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 &&...);
116 void swap(optional &) noexcept(see below );
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 &&) &&;
134 // 20.6.3.6, modifiers
135 void reset() noexcept;
138 T *val; // exposition only
146 #include <__functional_base>
147 #include <__undef_min_max>
148 #include <functional>
149 #include <initializer_list>
152 #include <type_traits>
155 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
156 #pragma GCC system_header
159 namespace std // purposefully not using versioning namespace
162 class _LIBCPP_EXCEPTION_ABI bad_optional_access
166 // Get the key function ~bad_optional_access() into the dylib
167 virtual ~bad_optional_access() _NOEXCEPT;
168 virtual const char* what() const _NOEXCEPT;
173 #if _LIBCPP_STD_VER > 14
175 _LIBCPP_BEGIN_NAMESPACE_STD
178 inline _LIBCPP_INLINE_VISIBILITY
179 void __throw_bad_optional_access() {
180 #ifndef _LIBCPP_NO_EXCEPTIONS
181 throw bad_optional_access();
189 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
190 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
193 /* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
195 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
196 struct __optional_destruct_base;
199 struct __optional_destruct_base<_Tp, false>
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");
211 _LIBCPP_INLINE_VISIBILITY
212 ~__optional_destruct_base()
215 __val_.~value_type();
218 _LIBCPP_INLINE_VISIBILITY
219 constexpr __optional_destruct_base() noexcept
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)...),
229 _LIBCPP_INLINE_VISIBILITY
230 void reset() noexcept
234 __val_.~value_type();
241 struct __optional_destruct_base<_Tp, true>
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");
253 _LIBCPP_INLINE_VISIBILITY
254 constexpr __optional_destruct_base() noexcept
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)...),
264 _LIBCPP_INLINE_VISIBILITY
265 void reset() noexcept
274 template <class _Tp, bool = is_reference<_Tp>::value>
275 struct __optional_storage_base : __optional_destruct_base<_Tp>
277 using __base = __optional_destruct_base<_Tp>;
278 using value_type = _Tp;
279 using __base::__base;
281 _LIBCPP_INLINE_VISIBILITY
282 constexpr bool has_value() const noexcept
284 return this->__engaged_;
287 _LIBCPP_INLINE_VISIBILITY
288 constexpr value_type& __get() & noexcept
292 _LIBCPP_INLINE_VISIBILITY
293 constexpr const value_type& __get() const& noexcept
297 _LIBCPP_INLINE_VISIBILITY
298 constexpr value_type&& __get() && noexcept
300 return _VSTD::move(this->__val_);
302 _LIBCPP_INLINE_VISIBILITY
303 constexpr const value_type&& __get() const&& noexcept
305 return _VSTD::move(this->__val_);
308 template <class... _Args>
309 _LIBCPP_INLINE_VISIBILITY
310 void __construct(_Args&&... __args)
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;
317 template <class _That>
318 _LIBCPP_INLINE_VISIBILITY
319 void __construct_from(_That&& __opt)
321 if (__opt.has_value())
322 __construct(_VSTD::forward<_That>(__opt).__get());
325 template <class _That>
326 _LIBCPP_INLINE_VISIBILITY
327 void __assign_from(_That&& __opt)
329 if (this->__engaged_ == __opt.has_value())
331 if (this->__engaged_)
332 this->__val_ = _VSTD::forward<_That>(__opt).__get();
336 if (this->__engaged_)
339 __construct(_VSTD::forward<_That>(__opt).__get());
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.
348 struct __optional_storage_base<_Tp, true>
350 using value_type = _Tp;
351 using __raw_type = remove_reference_t<_Tp>;
352 __raw_type* __value_;
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
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);
370 _LIBCPP_INLINE_VISIBILITY
371 constexpr __optional_storage_base() noexcept
372 : __value_(nullptr) {}
374 template <class _UArg>
375 _LIBCPP_INLINE_VISIBILITY
376 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
377 : __value_(_VSTD::addressof(__uarg))
379 static_assert(__can_bind_reference<_UArg>(),
380 "Attempted to construct a reference element in tuple from a "
381 "possible temporary");
384 _LIBCPP_INLINE_VISIBILITY
385 void reset() noexcept { __value_ = nullptr; }
387 _LIBCPP_INLINE_VISIBILITY
388 constexpr bool has_value() const noexcept
389 { return __value_ != nullptr; }
391 _LIBCPP_INLINE_VISIBILITY
392 constexpr value_type& __get() const& noexcept
393 { return *__value_; }
395 _LIBCPP_INLINE_VISIBILITY
396 constexpr value_type&& __get() const&& noexcept
397 { return _VSTD::forward<value_type>(*__value_); }
399 template <class _UArg>
400 _LIBCPP_INLINE_VISIBILITY
401 void __construct(_UArg&& __val)
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);
410 template <class _That>
411 _LIBCPP_INLINE_VISIBILITY
412 void __construct_from(_That&& __opt)
414 if (__opt.has_value())
415 __construct(_VSTD::forward<_That>(__opt).__get());
418 template <class _That>
419 _LIBCPP_INLINE_VISIBILITY
420 void __assign_from(_That&& __opt)
422 if (has_value() == __opt.has_value())
425 *__value_ = _VSTD::forward<_That>(__opt).__get();
432 __construct(_VSTD::forward<_That>(__opt).__get());
437 template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
438 struct __optional_storage;
441 struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
443 using __optional_storage_base<_Tp>::__optional_storage_base;
447 struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
449 using value_type = _Tp;
450 using __optional_storage_base<_Tp>::__optional_storage_base;
452 _LIBCPP_INLINE_VISIBILITY
453 __optional_storage() = default;
455 _LIBCPP_INLINE_VISIBILITY
456 __optional_storage(const __optional_storage& __opt)
458 this->__construct_from(__opt);
461 _LIBCPP_INLINE_VISIBILITY
462 __optional_storage(__optional_storage&& __opt)
463 noexcept(is_nothrow_move_constructible_v<value_type>)
465 this->__construct_from(_VSTD::move(__opt));
468 _LIBCPP_INLINE_VISIBILITY
469 __optional_storage& operator=(const __optional_storage& __opt)
471 this->__assign_from(__opt);
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>)
480 this->__assign_from(_VSTD::move(__opt));
486 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
487 is_copy_constructible<_Tp>::value,
488 is_move_constructible<_Tp>::value
492 using __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)
499 : private __optional_storage<_Tp>
500 , private __optional_sfinae_ctor_base_t<_Tp>
501 , private __optional_sfinae_assign_base_t<_Tp>
503 using __base = __optional_storage<_Tp>;
505 using value_type = _Tp;
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");
518 // LWG2756: conditionally explicit conversion from _Up
519 struct _CheckOptionalArgsConstructor {
521 static constexpr bool __enable_implicit() {
522 return is_constructible_v<_Tp, _Up&&> &&
523 is_convertible_v<_Up&&, _Tp>;
527 static constexpr bool __enable_explicit() {
528 return is_constructible_v<_Tp, _Up&&> &&
529 !is_convertible_v<_Up&&, _Tp>;
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
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>
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&&>
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;
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;
569 template <class _Up, class _QUp = _QualUp>
570 static constexpr bool __enable_assign() {
571 // Construction and assignability of _Qup to _Tp has already been
573 return !__check_constructible_from_opt<_Up>::value &&
574 !__check_assignable_from_opt<_Up>::value;
578 template <class _Up, class _QualUp>
579 using _CheckOptionalLikeCtor = conditional_t<
581 __lazy_not<is_same<_Up, _Tp>>,
582 is_constructible<_Tp, _QualUp>
584 _CheckOptionalLikeConstructor<_QualUp>,
585 __check_tuple_constructor_fail
587 template <class _Up, class _QualUp>
588 using _CheckOptionalLikeAssign = conditional_t<
590 __lazy_not<is_same<_Up, _Tp>>,
591 is_constructible<_Tp, _QualUp>,
592 is_assignable<_Tp&, _QualUp>
594 _CheckOptionalLikeConstructor<_QualUp>,
595 __check_tuple_constructor_fail
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 {}
604 template <class... _Args, class = enable_if_t<
605 is_constructible_v<value_type, _Args...>>
607 _LIBCPP_INLINE_VISIBILITY
608 constexpr explicit optional(in_place_t, _Args&&... __args)
609 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
611 template <class _Up, class... _Args, class = enable_if_t<
612 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
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)...) {}
618 template <class _Up = value_type, enable_if_t<
619 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
621 _LIBCPP_INLINE_VISIBILITY
622 constexpr optional(_Up&& __v)
623 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
625 template <class _Up, enable_if_t<
626 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
628 _LIBCPP_INLINE_VISIBILITY
629 constexpr explicit optional(_Up&& __v)
630 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
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>()
636 _LIBCPP_INLINE_VISIBILITY
637 optional(const optional<_Up>& __v)
639 this->__construct_from(__v);
641 template <class _Up, enable_if_t<
642 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
644 _LIBCPP_INLINE_VISIBILITY
645 explicit optional(const optional<_Up>& __v)
647 this->__construct_from(__v);
650 // LWG2756: conditionally explicit conversion from optional<_Up>&&
651 template <class _Up, enable_if_t<
652 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
654 _LIBCPP_INLINE_VISIBILITY
655 optional(optional<_Up>&& __v)
657 this->__construct_from(_VSTD::move(__v));
659 template <class _Up, enable_if_t<
660 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
662 _LIBCPP_INLINE_VISIBILITY
663 explicit optional(optional<_Up>&& __v)
665 this->__construct_from(_VSTD::move(__v));
668 _LIBCPP_INLINE_VISIBILITY
669 optional& operator=(nullopt_t) noexcept
675 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
676 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
679 template <class _Up = value_type,
682 integral_constant<bool,
683 !is_same_v<decay_t<_Up>, optional> &&
684 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
686 is_constructible<value_type, _Up>,
687 is_assignable<value_type&, _Up>
690 _LIBCPP_INLINE_VISIBILITY
694 if (this->has_value())
695 this->__get() = _VSTD::forward<_Up>(__v);
697 this->__construct(_VSTD::forward<_Up>(__v));
702 template <class _Up, enable_if_t<
703 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
705 _LIBCPP_INLINE_VISIBILITY
707 operator=(const optional<_Up>& __v)
709 this->__assign_from(__v);
714 template <class _Up, enable_if_t<
715 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
717 _LIBCPP_INLINE_VISIBILITY
719 operator=(optional<_Up>&& __v)
721 this->__assign_from(_VSTD::move(__v));
725 template <class... _Args,
728 is_constructible_v<value_type, _Args...>
731 _LIBCPP_INLINE_VISIBILITY
733 emplace(_Args&&... __args)
736 this->__construct(_VSTD::forward<_Args>(__args)...);
739 template <class _Up, class... _Args,
742 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
745 _LIBCPP_INLINE_VISIBILITY
747 emplace(initializer_list<_Up> __il, _Args&&... __args)
750 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
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>)
758 if (this->has_value() == __opt.has_value())
761 if (this->has_value())
762 swap(this->__get(), __opt.__get());
766 if (this->has_value())
768 __opt.__construct(_VSTD::move(this->__get()));
773 this->__construct(_VSTD::move(__opt.__get()));
779 _LIBCPP_INLINE_VISIBILITY
781 add_pointer_t<value_type const>
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());
788 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
792 _LIBCPP_INLINE_VISIBILITY
794 add_pointer_t<value_type>
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());
801 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
805 _LIBCPP_INLINE_VISIBILITY
810 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
811 return this->__get();
814 _LIBCPP_INLINE_VISIBILITY
819 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
820 return this->__get();
823 _LIBCPP_INLINE_VISIBILITY
828 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
829 return _VSTD::move(this->__get());
832 _LIBCPP_INLINE_VISIBILITY
837 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
838 return _VSTD::move(this->__get());
841 _LIBCPP_INLINE_VISIBILITY
842 constexpr explicit operator bool() const noexcept { return has_value(); }
844 using __base::has_value;
847 _LIBCPP_INLINE_VISIBILITY
848 constexpr value_type const& value() const&
850 if (!this->has_value())
851 __throw_bad_optional_access();
852 return this->__get();
855 _LIBCPP_INLINE_VISIBILITY
856 constexpr value_type& value() &
858 if (!this->has_value())
859 __throw_bad_optional_access();
860 return this->__get();
863 _LIBCPP_INLINE_VISIBILITY
864 constexpr value_type&& value() &&
866 if (!this->has_value())
867 __throw_bad_optional_access();
868 return _VSTD::move(this->__get());
871 _LIBCPP_INLINE_VISIBILITY
872 constexpr value_type const&& value() const&&
874 if (!this->has_value())
875 __throw_bad_optional_access();
876 return _VSTD::move(this->__get());
880 _LIBCPP_INLINE_VISIBILITY
881 constexpr value_type value_or(_Up&& __v) const&
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));
892 _LIBCPP_INLINE_VISIBILITY
893 value_type value_or(_Up&& __v) &&
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));
907 _LIBCPP_INLINE_VISIBILITY
909 __operator_arrow(true_type, _Up& __x)
911 return _VSTD::addressof(__x);
915 _LIBCPP_INLINE_VISIBILITY
916 static constexpr _Up*
917 __operator_arrow(false_type, _Up& __x)
923 // Comparisons between optionals
925 _LIBCPP_INLINE_VISIBILITY constexpr
927 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
928 _VSTD::declval<const _Tp&>()), bool>,
931 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
933 if (static_cast<bool>(__x) != static_cast<bool>(__y))
935 if (!static_cast<bool>(__x))
941 _LIBCPP_INLINE_VISIBILITY constexpr
943 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
944 _VSTD::declval<const _Tp&>()), bool>,
947 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
949 if (static_cast<bool>(__x) != static_cast<bool>(__y))
951 if (!static_cast<bool>(__x))
957 _LIBCPP_INLINE_VISIBILITY constexpr
959 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
960 _VSTD::declval<const _Tp&>()), bool>,
963 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
965 if (!static_cast<bool>(__y))
967 if (!static_cast<bool>(__x))
973 _LIBCPP_INLINE_VISIBILITY constexpr
975 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
976 _VSTD::declval<const _Tp&>()), bool>,
979 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
981 if (!static_cast<bool>(__x))
983 if (!static_cast<bool>(__y))
989 _LIBCPP_INLINE_VISIBILITY constexpr
991 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
992 _VSTD::declval<const _Tp&>()), bool>,
995 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
997 if (!static_cast<bool>(__x))
999 if (!static_cast<bool>(__y))
1001 return *__x <= *__y;
1004 template <class _Tp>
1005 _LIBCPP_INLINE_VISIBILITY constexpr
1007 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1008 _VSTD::declval<const _Tp&>()), bool>,
1011 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1013 if (!static_cast<bool>(__y))
1015 if (!static_cast<bool>(__x))
1017 return *__x >= *__y;
1020 // Comparisons with nullopt
1021 template <class _Tp>
1022 _LIBCPP_INLINE_VISIBILITY constexpr
1024 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1026 return !static_cast<bool>(__x);
1029 template <class _Tp>
1030 _LIBCPP_INLINE_VISIBILITY constexpr
1032 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1034 return !static_cast<bool>(__x);
1037 template <class _Tp>
1038 _LIBCPP_INLINE_VISIBILITY constexpr
1040 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1042 return static_cast<bool>(__x);
1045 template <class _Tp>
1046 _LIBCPP_INLINE_VISIBILITY constexpr
1048 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1050 return static_cast<bool>(__x);
1053 template <class _Tp>
1054 _LIBCPP_INLINE_VISIBILITY constexpr
1056 operator<(const optional<_Tp>&, nullopt_t) noexcept
1061 template <class _Tp>
1062 _LIBCPP_INLINE_VISIBILITY constexpr
1064 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1066 return static_cast<bool>(__x);
1069 template <class _Tp>
1070 _LIBCPP_INLINE_VISIBILITY constexpr
1072 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1074 return !static_cast<bool>(__x);
1077 template <class _Tp>
1078 _LIBCPP_INLINE_VISIBILITY constexpr
1080 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1085 template <class _Tp>
1086 _LIBCPP_INLINE_VISIBILITY constexpr
1088 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1090 return static_cast<bool>(__x);
1093 template <class _Tp>
1094 _LIBCPP_INLINE_VISIBILITY constexpr
1096 operator>(nullopt_t, const optional<_Tp>&) noexcept
1101 template <class _Tp>
1102 _LIBCPP_INLINE_VISIBILITY constexpr
1104 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1109 template <class _Tp>
1110 _LIBCPP_INLINE_VISIBILITY constexpr
1112 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1114 return !static_cast<bool>(__x);
1117 // Comparisons with T
1118 template <class _Tp>
1119 _LIBCPP_INLINE_VISIBILITY constexpr
1121 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1122 _VSTD::declval<const _Tp&>()), bool>,
1125 operator==(const optional<_Tp>& __x, const _Tp& __v)
1127 return static_cast<bool>(__x) ? *__x == __v : false;
1130 template <class _Tp>
1131 _LIBCPP_INLINE_VISIBILITY constexpr
1133 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1134 _VSTD::declval<const _Tp&>()), bool>,
1137 operator==(const _Tp& __v, const optional<_Tp>& __x)
1139 return static_cast<bool>(__x) ? __v == *__x : false;
1142 template <class _Tp>
1143 _LIBCPP_INLINE_VISIBILITY constexpr
1145 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1146 _VSTD::declval<const _Tp&>()), bool>,
1149 operator!=(const optional<_Tp>& __x, const _Tp& __v)
1151 return static_cast<bool>(__x) ? *__x != __v : true;
1154 template <class _Tp>
1155 _LIBCPP_INLINE_VISIBILITY constexpr
1157 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1158 _VSTD::declval<const _Tp&>()), bool>,
1161 operator!=(const _Tp& __v, const optional<_Tp>& __x)
1163 return static_cast<bool>(__x) ? __v != *__x : true;
1166 template <class _Tp>
1167 _LIBCPP_INLINE_VISIBILITY constexpr
1169 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1170 _VSTD::declval<const _Tp&>()), bool>,
1173 operator<(const optional<_Tp>& __x, const _Tp& __v)
1175 return static_cast<bool>(__x) ? *__x < __v : true;
1178 template <class _Tp>
1179 _LIBCPP_INLINE_VISIBILITY constexpr
1181 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1182 _VSTD::declval<const _Tp&>()), bool>,
1185 operator<(const _Tp& __v, const optional<_Tp>& __x)
1187 return static_cast<bool>(__x) ? __v < *__x : false;
1190 template <class _Tp>
1191 _LIBCPP_INLINE_VISIBILITY constexpr
1193 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1194 _VSTD::declval<const _Tp&>()), bool>,
1197 operator<=(const optional<_Tp>& __x, const _Tp& __v)
1199 return static_cast<bool>(__x) ? *__x <= __v : true;
1202 template <class _Tp>
1203 _LIBCPP_INLINE_VISIBILITY constexpr
1205 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1206 _VSTD::declval<const _Tp&>()), bool>,
1209 operator<=(const _Tp& __v, const optional<_Tp>& __x)
1211 return static_cast<bool>(__x) ? __v <= *__x : false;
1214 template <class _Tp>
1215 _LIBCPP_INLINE_VISIBILITY constexpr
1217 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1218 _VSTD::declval<const _Tp&>()), bool>,
1221 operator>(const optional<_Tp>& __x, const _Tp& __v)
1223 return static_cast<bool>(__x) ? *__x > __v : false;
1226 template <class _Tp>
1227 _LIBCPP_INLINE_VISIBILITY constexpr
1229 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1230 _VSTD::declval<const _Tp&>()), bool>,
1233 operator>(const _Tp& __v, const optional<_Tp>& __x)
1235 return static_cast<bool>(__x) ? __v > *__x : true;
1238 template <class _Tp>
1239 _LIBCPP_INLINE_VISIBILITY constexpr
1241 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1242 _VSTD::declval<const _Tp&>()), bool>,
1245 operator>=(const optional<_Tp>& __x, const _Tp& __v)
1247 return static_cast<bool>(__x) ? *__x >= __v : false;
1250 template <class _Tp>
1251 _LIBCPP_INLINE_VISIBILITY constexpr
1253 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1254 _VSTD::declval<const _Tp&>()), bool>,
1257 operator>=(const _Tp& __v, const optional<_Tp>& __x)
1259 return static_cast<bool>(__x) ? __v >= *__x : true;
1263 template <class _Tp>
1264 inline _LIBCPP_INLINE_VISIBILITY
1266 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1269 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1274 template <class _Tp>
1275 _LIBCPP_INLINE_VISIBILITY constexpr
1276 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1278 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1281 template <class _Tp, class... _Args>
1282 _LIBCPP_INLINE_VISIBILITY constexpr
1283 optional<_Tp> make_optional(_Args&&... __args)
1285 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1288 template <class _Tp, class _Up, class... _Args>
1289 _LIBCPP_INLINE_VISIBILITY constexpr
1290 optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1292 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1295 template <class _Tp>
1296 struct _LIBCPP_TEMPLATE_VIS hash<optional<_Tp> >
1298 typedef optional<_Tp> argument_type;
1299 typedef size_t result_type;
1301 _LIBCPP_INLINE_VISIBILITY
1302 result_type operator()(const argument_type& __opt) const _NOEXCEPT
1304 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1308 _LIBCPP_END_NAMESPACE_STD
1310 #endif // _LIBCPP_STD_VER > 14
1312 #endif // _LIBCPP_OPTIONAL