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 _LIBCPP_INLINE_VISIBILITY
167 bad_optional_access() : logic_error("bad optional access") {}
169 // Get the key function ~bad_optional_access() into the dylib
170 virtual ~bad_optional_access() _NOEXCEPT;
175 #if _LIBCPP_STD_VER > 14
177 _LIBCPP_BEGIN_NAMESPACE_STD
180 inline _LIBCPP_INLINE_VISIBILITY
181 void __throw_bad_optional_access() {
182 #ifndef _LIBCPP_NO_EXCEPTIONS
183 throw bad_optional_access();
191 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
192 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
195 /* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
197 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
198 struct __optional_destruct_base;
201 struct __optional_destruct_base<_Tp, false>
203 typedef _Tp value_type;
204 static_assert(is_object_v<value_type>,
205 "instantiation of optional with a non-object type is undefined behavior");
213 _LIBCPP_INLINE_VISIBILITY
214 ~__optional_destruct_base()
217 __val_.~value_type();
220 _LIBCPP_INLINE_VISIBILITY
221 constexpr __optional_destruct_base() noexcept
225 template <class... _Args>
226 _LIBCPP_INLINE_VISIBILITY
227 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
228 : __val_(_VSTD::forward<_Args>(__args)...),
231 _LIBCPP_INLINE_VISIBILITY
232 void reset() noexcept
236 __val_.~value_type();
243 struct __optional_destruct_base<_Tp, true>
245 typedef _Tp value_type;
246 static_assert(is_object_v<value_type>,
247 "instantiation of optional with a non-object type is undefined behavior");
255 _LIBCPP_INLINE_VISIBILITY
256 constexpr __optional_destruct_base() noexcept
260 template <class... _Args>
261 _LIBCPP_INLINE_VISIBILITY
262 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
263 : __val_(_VSTD::forward<_Args>(__args)...),
266 _LIBCPP_INLINE_VISIBILITY
267 void reset() noexcept
276 template <class _Tp, bool = is_reference<_Tp>::value>
277 struct __optional_storage_base : __optional_destruct_base<_Tp>
279 using __base = __optional_destruct_base<_Tp>;
280 using value_type = _Tp;
281 using __base::__base;
283 _LIBCPP_INLINE_VISIBILITY
284 constexpr bool has_value() const noexcept
286 return this->__engaged_;
289 _LIBCPP_INLINE_VISIBILITY
290 constexpr value_type& __get() & noexcept
294 _LIBCPP_INLINE_VISIBILITY
295 constexpr const value_type& __get() const& noexcept
299 _LIBCPP_INLINE_VISIBILITY
300 constexpr value_type&& __get() && noexcept
302 return _VSTD::move(this->__val_);
304 _LIBCPP_INLINE_VISIBILITY
305 constexpr const value_type&& __get() const&& noexcept
307 return _VSTD::move(this->__val_);
310 template <class... _Args>
311 _LIBCPP_INLINE_VISIBILITY
312 void __construct(_Args&&... __args)
314 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
315 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
316 this->__engaged_ = true;
319 template <class _That>
320 _LIBCPP_INLINE_VISIBILITY
321 void __construct_from(_That&& __opt)
323 if (__opt.has_value())
324 __construct(_VSTD::forward<_That>(__opt).__get());
327 template <class _That>
328 _LIBCPP_INLINE_VISIBILITY
329 void __assign_from(_That&& __opt)
331 if (this->__engaged_ == __opt.has_value())
333 if (this->__engaged_)
334 this->__val_ = _VSTD::forward<_That>(__opt).__get();
338 if (this->__engaged_)
341 __construct(_VSTD::forward<_That>(__opt).__get());
346 // optional<T&> is currently required ill-formed, however it may to be in the
347 // future. For this reason it has already been implemented to ensure we can
348 // make the change in an ABI compatible manner.
350 struct __optional_storage_base<_Tp, true>
352 using value_type = _Tp;
353 using __raw_type = remove_reference_t<_Tp>;
354 __raw_type* __value_;
357 static constexpr bool __can_bind_reference() {
358 using _RawUp = typename remove_reference<_Up>::type;
359 using _UpPtr = _RawUp*;
360 using _RawTp = typename remove_reference<_Tp>::type;
361 using _TpPtr = _RawTp*;
362 using _CheckLValueArg = integral_constant<bool,
363 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
364 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
365 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
367 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
368 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
369 is_convertible<_UpPtr, _TpPtr>::value);
372 _LIBCPP_INLINE_VISIBILITY
373 constexpr __optional_storage_base() noexcept
374 : __value_(nullptr) {}
376 template <class _UArg>
377 _LIBCPP_INLINE_VISIBILITY
378 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
379 : __value_(_VSTD::addressof(__uarg))
381 static_assert(__can_bind_reference<_UArg>(),
382 "Attempted to construct a reference element in tuple from a "
383 "possible temporary");
386 _LIBCPP_INLINE_VISIBILITY
387 void reset() noexcept { __value_ = nullptr; }
389 _LIBCPP_INLINE_VISIBILITY
390 constexpr bool has_value() const noexcept
391 { return __value_ != nullptr; }
393 _LIBCPP_INLINE_VISIBILITY
394 constexpr value_type& __get() const& noexcept
395 { return *__value_; }
397 _LIBCPP_INLINE_VISIBILITY
398 constexpr value_type&& __get() const&& noexcept
399 { return _VSTD::forward<value_type>(*__value_); }
401 template <class _UArg>
402 _LIBCPP_INLINE_VISIBILITY
403 void __construct(_UArg&& __val)
405 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
406 static_assert(__can_bind_reference<_UArg>(),
407 "Attempted to construct a reference element in tuple from a "
408 "possible temporary");
409 __value_ = _VSTD::addressof(__val);
412 template <class _That>
413 _LIBCPP_INLINE_VISIBILITY
414 void __construct_from(_That&& __opt)
416 if (__opt.has_value())
417 __construct(_VSTD::forward<_That>(__opt).__get());
420 template <class _That>
421 _LIBCPP_INLINE_VISIBILITY
422 void __assign_from(_That&& __opt)
424 if (has_value() == __opt.has_value())
427 *__value_ = _VSTD::forward<_That>(__opt).__get();
434 __construct(_VSTD::forward<_That>(__opt).__get());
439 template <class _Tp, bool = is_trivially_copyable<_Tp>::value>
440 struct __optional_storage;
443 struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp>
445 using __optional_storage_base<_Tp>::__optional_storage_base;
449 struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp>
451 using value_type = _Tp;
452 using __optional_storage_base<_Tp>::__optional_storage_base;
454 _LIBCPP_INLINE_VISIBILITY
455 __optional_storage() = default;
457 _LIBCPP_INLINE_VISIBILITY
458 __optional_storage(const __optional_storage& __opt)
460 this->__construct_from(__opt);
463 _LIBCPP_INLINE_VISIBILITY
464 __optional_storage(__optional_storage&& __opt)
465 noexcept(is_nothrow_move_constructible_v<value_type>)
467 this->__construct_from(_VSTD::move(__opt));
470 _LIBCPP_INLINE_VISIBILITY
471 __optional_storage& operator=(const __optional_storage& __opt)
473 this->__assign_from(__opt);
477 _LIBCPP_INLINE_VISIBILITY
478 __optional_storage& operator=(__optional_storage&& __opt)
479 noexcept(is_nothrow_move_assignable_v<value_type> &&
480 is_nothrow_move_constructible_v<value_type>)
482 this->__assign_from(_VSTD::move(__opt));
488 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
489 is_copy_constructible<_Tp>::value,
490 is_move_constructible<_Tp>::value
494 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
495 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
496 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
501 : private __optional_storage<_Tp>
502 , private __optional_sfinae_ctor_base_t<_Tp>
503 , private __optional_sfinae_assign_base_t<_Tp>
505 using __base = __optional_storage<_Tp>;
507 using value_type = _Tp;
510 // Disable the reference extension using this static assert.
511 static_assert(!is_same_v<value_type, in_place_t>,
512 "instantiation of optional with in_place_t is ill-formed");
513 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
514 "instantiation of optional with nullopt_t is ill-formed");
515 static_assert(!is_reference_v<value_type>,
516 "instantiation of optional with a reference type is ill-formed");
517 static_assert(is_destructible_v<value_type>,
518 "instantiation of optional with a non-destructible type is ill-formed");
520 // LWG2756: conditionally explicit conversion from _Up
521 struct _CheckOptionalArgsConstructor {
523 static constexpr bool __enable_implicit() {
524 return is_constructible_v<_Tp, _Up&&> &&
525 is_convertible_v<_Up&&, _Tp>;
529 static constexpr bool __enable_explicit() {
530 return is_constructible_v<_Tp, _Up&&> &&
531 !is_convertible_v<_Up&&, _Tp>;
535 using _CheckOptionalArgsCtor = conditional_t<
536 !is_same_v<in_place_t, _Up> &&
537 !is_same_v<decay_t<_Up>, optional>,
538 _CheckOptionalArgsConstructor,
539 __check_tuple_constructor_fail
541 template <class _QualUp>
542 struct _CheckOptionalLikeConstructor {
543 template <class _Up, class _Opt = optional<_Up>>
544 using __check_constructible_from_opt = __lazy_or<
545 is_constructible<_Tp, _Opt&>,
546 is_constructible<_Tp, _Opt const&>,
547 is_constructible<_Tp, _Opt&&>,
548 is_constructible<_Tp, _Opt const&&>,
549 is_convertible<_Opt&, _Tp>,
550 is_convertible<_Opt const&, _Tp>,
551 is_convertible<_Opt&&, _Tp>,
552 is_convertible<_Opt const&&, _Tp>
554 template <class _Up, class _Opt = optional<_Up>>
555 using __check_assignable_from_opt = __lazy_or<
556 is_assignable<_Tp&, _Opt&>,
557 is_assignable<_Tp&, _Opt const&>,
558 is_assignable<_Tp&, _Opt&&>,
559 is_assignable<_Tp&, _Opt const&&>
561 template <class _Up, class _QUp = _QualUp>
562 static constexpr bool __enable_implicit() {
563 return is_convertible<_QUp, _Tp>::value &&
564 !__check_constructible_from_opt<_Up>::value;
566 template <class _Up, class _QUp = _QualUp>
567 static constexpr bool __enable_explicit() {
568 return !is_convertible<_QUp, _Tp>::value &&
569 !__check_constructible_from_opt<_Up>::value;
571 template <class _Up, class _QUp = _QualUp>
572 static constexpr bool __enable_assign() {
573 // Construction and assignability of _Qup to _Tp has already been
575 return !__check_constructible_from_opt<_Up>::value &&
576 !__check_assignable_from_opt<_Up>::value;
580 template <class _Up, class _QualUp>
581 using _CheckOptionalLikeCtor = conditional_t<
583 __lazy_not<is_same<_Up, _Tp>>,
584 is_constructible<_Tp, _QualUp>
586 _CheckOptionalLikeConstructor<_QualUp>,
587 __check_tuple_constructor_fail
589 template <class _Up, class _QualUp>
590 using _CheckOptionalLikeAssign = conditional_t<
592 __lazy_not<is_same<_Up, _Tp>>,
593 is_constructible<_Tp, _QualUp>,
594 is_assignable<_Tp&, _QualUp>
596 _CheckOptionalLikeConstructor<_QualUp>,
597 __check_tuple_constructor_fail
601 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
602 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
603 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
604 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
606 template <class... _Args, class = enable_if_t<
607 is_constructible_v<value_type, _Args...>>
609 _LIBCPP_INLINE_VISIBILITY
610 constexpr explicit optional(in_place_t, _Args&&... __args)
611 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
613 template <class _Up, class... _Args, class = enable_if_t<
614 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
616 _LIBCPP_INLINE_VISIBILITY
617 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
618 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
620 template <class _Up = value_type, enable_if_t<
621 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
623 _LIBCPP_INLINE_VISIBILITY
624 constexpr optional(_Up&& __v)
625 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
627 template <class _Up, enable_if_t<
628 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
630 _LIBCPP_INLINE_VISIBILITY
631 constexpr explicit optional(_Up&& __v)
632 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
634 // LWG2756: conditionally explicit conversion from const optional<_Up>&
635 template <class _Up, enable_if_t<
636 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
638 _LIBCPP_INLINE_VISIBILITY
639 optional(const optional<_Up>& __v)
641 this->__construct_from(__v);
643 template <class _Up, enable_if_t<
644 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
646 _LIBCPP_INLINE_VISIBILITY
647 explicit optional(const optional<_Up>& __v)
649 this->__construct_from(__v);
652 // LWG2756: conditionally explicit conversion from optional<_Up>&&
653 template <class _Up, enable_if_t<
654 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
656 _LIBCPP_INLINE_VISIBILITY
657 optional(optional<_Up>&& __v)
659 this->__construct_from(_VSTD::move(__v));
661 template <class _Up, enable_if_t<
662 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
664 _LIBCPP_INLINE_VISIBILITY
665 explicit optional(optional<_Up>&& __v)
667 this->__construct_from(_VSTD::move(__v));
670 _LIBCPP_INLINE_VISIBILITY
671 optional& operator=(nullopt_t) noexcept
677 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
678 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
681 template <class _Up = value_type,
684 integral_constant<bool,
685 !is_same_v<decay_t<_Up>, optional> &&
686 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
688 is_constructible<value_type, _Up>,
689 is_assignable<value_type&, _Up>
692 _LIBCPP_INLINE_VISIBILITY
696 if (this->has_value())
697 this->__get() = _VSTD::forward<_Up>(__v);
699 this->__construct(_VSTD::forward<_Up>(__v));
704 template <class _Up, enable_if_t<
705 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
707 _LIBCPP_INLINE_VISIBILITY
709 operator=(const optional<_Up>& __v)
711 this->__assign_from(__v);
716 template <class _Up, enable_if_t<
717 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
719 _LIBCPP_INLINE_VISIBILITY
721 operator=(optional<_Up>&& __v)
723 this->__assign_from(_VSTD::move(__v));
727 template <class... _Args,
730 is_constructible_v<value_type, _Args...>
733 _LIBCPP_INLINE_VISIBILITY
735 emplace(_Args&&... __args)
738 this->__construct(_VSTD::forward<_Args>(__args)...);
741 template <class _Up, class... _Args,
744 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
747 _LIBCPP_INLINE_VISIBILITY
749 emplace(initializer_list<_Up> __il, _Args&&... __args)
752 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
755 _LIBCPP_INLINE_VISIBILITY
756 void swap(optional& __opt)
757 noexcept(is_nothrow_move_constructible_v<value_type> &&
758 is_nothrow_swappable_v<value_type>)
760 if (this->has_value() == __opt.has_value())
763 if (this->has_value())
764 swap(this->__get(), __opt.__get());
768 if (this->has_value())
770 __opt.__construct(_VSTD::move(this->__get()));
775 this->__construct(_VSTD::move(__opt.__get()));
781 _LIBCPP_INLINE_VISIBILITY
783 add_pointer_t<value_type const>
786 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
787 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
788 return _VSTD::addressof(this->__get());
790 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
794 _LIBCPP_INLINE_VISIBILITY
796 add_pointer_t<value_type>
799 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
800 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
801 return _VSTD::addressof(this->__get());
803 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
807 _LIBCPP_INLINE_VISIBILITY
812 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
813 return this->__get();
816 _LIBCPP_INLINE_VISIBILITY
821 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
822 return this->__get();
825 _LIBCPP_INLINE_VISIBILITY
830 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
831 return _VSTD::move(this->__get());
834 _LIBCPP_INLINE_VISIBILITY
839 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
840 return _VSTD::move(this->__get());
843 _LIBCPP_INLINE_VISIBILITY
844 constexpr explicit operator bool() const noexcept { return has_value(); }
846 using __base::has_value;
849 _LIBCPP_INLINE_VISIBILITY
850 constexpr value_type const& value() const&
852 if (!this->has_value())
853 __throw_bad_optional_access();
854 return this->__get();
857 _LIBCPP_INLINE_VISIBILITY
858 constexpr value_type& value() &
860 if (!this->has_value())
861 __throw_bad_optional_access();
862 return this->__get();
865 _LIBCPP_INLINE_VISIBILITY
866 constexpr value_type&& value() &&
868 if (!this->has_value())
869 __throw_bad_optional_access();
870 return _VSTD::move(this->__get());
873 _LIBCPP_INLINE_VISIBILITY
874 constexpr value_type const&& value() const&&
876 if (!this->has_value())
877 __throw_bad_optional_access();
878 return _VSTD::move(this->__get());
882 _LIBCPP_INLINE_VISIBILITY
883 constexpr value_type value_or(_Up&& __v) const&
885 static_assert(is_copy_constructible_v<value_type>,
886 "optional<T>::value_or: T must be copy constructible");
887 static_assert(is_convertible_v<_Up, value_type>,
888 "optional<T>::value_or: U must be convertible to T");
889 return this->has_value() ? this->__get() :
890 static_cast<value_type>(_VSTD::forward<_Up>(__v));
894 _LIBCPP_INLINE_VISIBILITY
895 value_type value_or(_Up&& __v) &&
897 static_assert(is_move_constructible_v<value_type>,
898 "optional<T>::value_or: T must be move constructible");
899 static_assert(is_convertible_v<_Up, value_type>,
900 "optional<T>::value_or: U must be convertible to T");
901 return this->has_value() ? _VSTD::move(this->__get()) :
902 static_cast<value_type>(_VSTD::forward<_Up>(__v));
909 _LIBCPP_INLINE_VISIBILITY
911 __operator_arrow(true_type, _Up& __x)
913 return _VSTD::addressof(__x);
917 _LIBCPP_INLINE_VISIBILITY
918 static constexpr _Up*
919 __operator_arrow(false_type, _Up& __x)
925 // Comparisons between optionals
927 _LIBCPP_INLINE_VISIBILITY constexpr
929 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
930 _VSTD::declval<const _Tp&>()), bool>,
933 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
935 if (static_cast<bool>(__x) != static_cast<bool>(__y))
937 if (!static_cast<bool>(__x))
943 _LIBCPP_INLINE_VISIBILITY constexpr
945 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
946 _VSTD::declval<const _Tp&>()), bool>,
949 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y)
951 if (static_cast<bool>(__x) != static_cast<bool>(__y))
953 if (!static_cast<bool>(__x))
959 _LIBCPP_INLINE_VISIBILITY constexpr
961 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
962 _VSTD::declval<const _Tp&>()), bool>,
965 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
967 if (!static_cast<bool>(__y))
969 if (!static_cast<bool>(__x))
975 _LIBCPP_INLINE_VISIBILITY constexpr
977 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
978 _VSTD::declval<const _Tp&>()), bool>,
981 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y)
983 if (!static_cast<bool>(__x))
985 if (!static_cast<bool>(__y))
991 _LIBCPP_INLINE_VISIBILITY constexpr
993 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
994 _VSTD::declval<const _Tp&>()), bool>,
997 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y)
999 if (!static_cast<bool>(__x))
1001 if (!static_cast<bool>(__y))
1003 return *__x <= *__y;
1006 template <class _Tp>
1007 _LIBCPP_INLINE_VISIBILITY constexpr
1009 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1010 _VSTD::declval<const _Tp&>()), bool>,
1013 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y)
1015 if (!static_cast<bool>(__y))
1017 if (!static_cast<bool>(__x))
1019 return *__x >= *__y;
1022 // Comparisons with nullopt
1023 template <class _Tp>
1024 _LIBCPP_INLINE_VISIBILITY constexpr
1026 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1028 return !static_cast<bool>(__x);
1031 template <class _Tp>
1032 _LIBCPP_INLINE_VISIBILITY constexpr
1034 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1036 return !static_cast<bool>(__x);
1039 template <class _Tp>
1040 _LIBCPP_INLINE_VISIBILITY constexpr
1042 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1044 return static_cast<bool>(__x);
1047 template <class _Tp>
1048 _LIBCPP_INLINE_VISIBILITY constexpr
1050 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1052 return static_cast<bool>(__x);
1055 template <class _Tp>
1056 _LIBCPP_INLINE_VISIBILITY constexpr
1058 operator<(const optional<_Tp>&, nullopt_t) noexcept
1063 template <class _Tp>
1064 _LIBCPP_INLINE_VISIBILITY constexpr
1066 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1068 return static_cast<bool>(__x);
1071 template <class _Tp>
1072 _LIBCPP_INLINE_VISIBILITY constexpr
1074 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1076 return !static_cast<bool>(__x);
1079 template <class _Tp>
1080 _LIBCPP_INLINE_VISIBILITY constexpr
1082 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1087 template <class _Tp>
1088 _LIBCPP_INLINE_VISIBILITY constexpr
1090 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1092 return static_cast<bool>(__x);
1095 template <class _Tp>
1096 _LIBCPP_INLINE_VISIBILITY constexpr
1098 operator>(nullopt_t, const optional<_Tp>&) noexcept
1103 template <class _Tp>
1104 _LIBCPP_INLINE_VISIBILITY constexpr
1106 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1111 template <class _Tp>
1112 _LIBCPP_INLINE_VISIBILITY constexpr
1114 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1116 return !static_cast<bool>(__x);
1119 // Comparisons with T
1120 template <class _Tp>
1121 _LIBCPP_INLINE_VISIBILITY constexpr
1123 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1124 _VSTD::declval<const _Tp&>()), bool>,
1127 operator==(const optional<_Tp>& __x, const _Tp& __v)
1129 return static_cast<bool>(__x) ? *__x == __v : false;
1132 template <class _Tp>
1133 _LIBCPP_INLINE_VISIBILITY constexpr
1135 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1136 _VSTD::declval<const _Tp&>()), bool>,
1139 operator==(const _Tp& __v, const optional<_Tp>& __x)
1141 return static_cast<bool>(__x) ? __v == *__x : false;
1144 template <class _Tp>
1145 _LIBCPP_INLINE_VISIBILITY constexpr
1147 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1148 _VSTD::declval<const _Tp&>()), bool>,
1151 operator!=(const optional<_Tp>& __x, const _Tp& __v)
1153 return static_cast<bool>(__x) ? *__x != __v : true;
1156 template <class _Tp>
1157 _LIBCPP_INLINE_VISIBILITY constexpr
1159 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1160 _VSTD::declval<const _Tp&>()), bool>,
1163 operator!=(const _Tp& __v, const optional<_Tp>& __x)
1165 return static_cast<bool>(__x) ? __v != *__x : true;
1168 template <class _Tp>
1169 _LIBCPP_INLINE_VISIBILITY constexpr
1171 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1172 _VSTD::declval<const _Tp&>()), bool>,
1175 operator<(const optional<_Tp>& __x, const _Tp& __v)
1177 return static_cast<bool>(__x) ? *__x < __v : true;
1180 template <class _Tp>
1181 _LIBCPP_INLINE_VISIBILITY constexpr
1183 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1184 _VSTD::declval<const _Tp&>()), bool>,
1187 operator<(const _Tp& __v, const optional<_Tp>& __x)
1189 return static_cast<bool>(__x) ? __v < *__x : false;
1192 template <class _Tp>
1193 _LIBCPP_INLINE_VISIBILITY constexpr
1195 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1196 _VSTD::declval<const _Tp&>()), bool>,
1199 operator<=(const optional<_Tp>& __x, const _Tp& __v)
1201 return static_cast<bool>(__x) ? *__x <= __v : true;
1204 template <class _Tp>
1205 _LIBCPP_INLINE_VISIBILITY constexpr
1207 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1208 _VSTD::declval<const _Tp&>()), bool>,
1211 operator<=(const _Tp& __v, const optional<_Tp>& __x)
1213 return static_cast<bool>(__x) ? __v <= *__x : false;
1216 template <class _Tp>
1217 _LIBCPP_INLINE_VISIBILITY constexpr
1219 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1220 _VSTD::declval<const _Tp&>()), bool>,
1223 operator>(const optional<_Tp>& __x, const _Tp& __v)
1225 return static_cast<bool>(__x) ? *__x > __v : false;
1228 template <class _Tp>
1229 _LIBCPP_INLINE_VISIBILITY constexpr
1231 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1232 _VSTD::declval<const _Tp&>()), bool>,
1235 operator>(const _Tp& __v, const optional<_Tp>& __x)
1237 return static_cast<bool>(__x) ? __v > *__x : true;
1240 template <class _Tp>
1241 _LIBCPP_INLINE_VISIBILITY constexpr
1243 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1244 _VSTD::declval<const _Tp&>()), bool>,
1247 operator>=(const optional<_Tp>& __x, const _Tp& __v)
1249 return static_cast<bool>(__x) ? *__x >= __v : false;
1252 template <class _Tp>
1253 _LIBCPP_INLINE_VISIBILITY constexpr
1255 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1256 _VSTD::declval<const _Tp&>()), bool>,
1259 operator>=(const _Tp& __v, const optional<_Tp>& __x)
1261 return static_cast<bool>(__x) ? __v >= *__x : true;
1265 template <class _Tp>
1266 inline _LIBCPP_INLINE_VISIBILITY
1268 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1271 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1276 template <class _Tp>
1277 _LIBCPP_INLINE_VISIBILITY constexpr
1278 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1280 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1283 template <class _Tp, class... _Args>
1284 _LIBCPP_INLINE_VISIBILITY constexpr
1285 optional<_Tp> make_optional(_Args&&... __args)
1287 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1290 template <class _Tp, class _Up, class... _Args>
1291 _LIBCPP_INLINE_VISIBILITY constexpr
1292 optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1294 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1297 template <class _Tp>
1298 struct _LIBCPP_TEMPLATE_VIS hash<optional<_Tp> >
1300 typedef optional<_Tp> argument_type;
1301 typedef size_t result_type;
1303 _LIBCPP_INLINE_VISIBILITY
1304 result_type operator()(const argument_type& __opt) const _NOEXCEPT
1306 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
1310 _LIBCPP_END_NAMESPACE_STD
1312 #endif // _LIBCPP_STD_VER > 14
1314 #endif // _LIBCPP_OPTIONAL