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 inline 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 T&, const optional<U>&);
61 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
62 template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
63 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
64 template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
65 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
66 template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
67 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
68 template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
69 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
70 template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
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 &); // constexpr in C++20
109 optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
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
144 optional(T) -> optional<T>;
152 #include <__functional_base>
153 #include <functional>
154 #include <initializer_list>
157 #include <type_traits>
161 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
162 #pragma GCC system_header
166 #include <__undef_macros>
169 namespace std // purposefully not using versioning namespace
172 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
176 // Get the key function ~bad_optional_access() into the dylib
177 virtual ~bad_optional_access() _NOEXCEPT;
178 virtual const char* what() const _NOEXCEPT;
183 #if _LIBCPP_STD_VER > 14
185 _LIBCPP_BEGIN_NAMESPACE_STD
188 inline _LIBCPP_INLINE_VISIBILITY
189 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
190 void __throw_bad_optional_access() {
191 #ifndef _LIBCPP_NO_EXCEPTIONS
192 throw bad_optional_access();
200 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
201 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
204 _LIBCPP_INLINE_VAR constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
206 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
207 struct __optional_destruct_base;
210 struct __optional_destruct_base<_Tp, false>
212 typedef _Tp value_type;
213 static_assert(is_object_v<value_type>,
214 "instantiation of optional with a non-object type is undefined behavior");
222 _LIBCPP_INLINE_VISIBILITY
223 ~__optional_destruct_base()
226 __val_.~value_type();
229 _LIBCPP_INLINE_VISIBILITY
230 constexpr __optional_destruct_base() noexcept
234 template <class... _Args>
235 _LIBCPP_INLINE_VISIBILITY
236 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
237 : __val_(_VSTD::forward<_Args>(__args)...),
240 _LIBCPP_INLINE_VISIBILITY
241 void reset() noexcept
245 __val_.~value_type();
252 struct __optional_destruct_base<_Tp, true>
254 typedef _Tp value_type;
255 static_assert(is_object_v<value_type>,
256 "instantiation of optional with a non-object type is undefined behavior");
264 _LIBCPP_INLINE_VISIBILITY
265 constexpr __optional_destruct_base() noexcept
269 template <class... _Args>
270 _LIBCPP_INLINE_VISIBILITY
271 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
272 : __val_(_VSTD::forward<_Args>(__args)...),
275 _LIBCPP_INLINE_VISIBILITY
276 void reset() noexcept
285 template <class _Tp, bool = is_reference<_Tp>::value>
286 struct __optional_storage_base : __optional_destruct_base<_Tp>
288 using __base = __optional_destruct_base<_Tp>;
289 using value_type = _Tp;
290 using __base::__base;
292 _LIBCPP_INLINE_VISIBILITY
293 constexpr bool has_value() const noexcept
295 return this->__engaged_;
298 _LIBCPP_INLINE_VISIBILITY
299 constexpr value_type& __get() & noexcept
303 _LIBCPP_INLINE_VISIBILITY
304 constexpr const value_type& __get() const& noexcept
308 _LIBCPP_INLINE_VISIBILITY
309 constexpr value_type&& __get() && noexcept
311 return _VSTD::move(this->__val_);
313 _LIBCPP_INLINE_VISIBILITY
314 constexpr const value_type&& __get() const&& noexcept
316 return _VSTD::move(this->__val_);
319 template <class... _Args>
320 _LIBCPP_INLINE_VISIBILITY
321 void __construct(_Args&&... __args)
323 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
324 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
325 this->__engaged_ = true;
328 template <class _That>
329 _LIBCPP_INLINE_VISIBILITY
330 void __construct_from(_That&& __opt)
332 if (__opt.has_value())
333 __construct(_VSTD::forward<_That>(__opt).__get());
336 template <class _That>
337 _LIBCPP_INLINE_VISIBILITY
338 void __assign_from(_That&& __opt)
340 if (this->__engaged_ == __opt.has_value())
342 if (this->__engaged_)
343 this->__val_ = _VSTD::forward<_That>(__opt).__get();
347 if (this->__engaged_)
350 __construct(_VSTD::forward<_That>(__opt).__get());
355 // optional<T&> is currently required ill-formed, however it may to be in the
356 // future. For this reason it has already been implemented to ensure we can
357 // make the change in an ABI compatible manner.
359 struct __optional_storage_base<_Tp, true>
361 using value_type = _Tp;
362 using __raw_type = remove_reference_t<_Tp>;
363 __raw_type* __value_;
366 static constexpr bool __can_bind_reference() {
367 using _RawUp = typename remove_reference<_Up>::type;
368 using _UpPtr = _RawUp*;
369 using _RawTp = typename remove_reference<_Tp>::type;
370 using _TpPtr = _RawTp*;
371 using _CheckLValueArg = integral_constant<bool,
372 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
373 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
374 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
376 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
377 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
378 is_convertible<_UpPtr, _TpPtr>::value);
381 _LIBCPP_INLINE_VISIBILITY
382 constexpr __optional_storage_base() noexcept
383 : __value_(nullptr) {}
385 template <class _UArg>
386 _LIBCPP_INLINE_VISIBILITY
387 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
388 : __value_(_VSTD::addressof(__uarg))
390 static_assert(__can_bind_reference<_UArg>(),
391 "Attempted to construct a reference element in tuple from a "
392 "possible temporary");
395 _LIBCPP_INLINE_VISIBILITY
396 void reset() noexcept { __value_ = nullptr; }
398 _LIBCPP_INLINE_VISIBILITY
399 constexpr bool has_value() const noexcept
400 { return __value_ != nullptr; }
402 _LIBCPP_INLINE_VISIBILITY
403 constexpr value_type& __get() const& noexcept
404 { return *__value_; }
406 _LIBCPP_INLINE_VISIBILITY
407 constexpr value_type&& __get() const&& noexcept
408 { return _VSTD::forward<value_type>(*__value_); }
410 template <class _UArg>
411 _LIBCPP_INLINE_VISIBILITY
412 void __construct(_UArg&& __val)
414 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
415 static_assert(__can_bind_reference<_UArg>(),
416 "Attempted to construct a reference element in tuple from a "
417 "possible temporary");
418 __value_ = _VSTD::addressof(__val);
421 template <class _That>
422 _LIBCPP_INLINE_VISIBILITY
423 void __construct_from(_That&& __opt)
425 if (__opt.has_value())
426 __construct(_VSTD::forward<_That>(__opt).__get());
429 template <class _That>
430 _LIBCPP_INLINE_VISIBILITY
431 void __assign_from(_That&& __opt)
433 if (has_value() == __opt.has_value())
436 *__value_ = _VSTD::forward<_That>(__opt).__get();
443 __construct(_VSTD::forward<_That>(__opt).__get());
448 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
449 struct __optional_copy_base : __optional_storage_base<_Tp>
451 using __optional_storage_base<_Tp>::__optional_storage_base;
455 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
457 using __optional_storage_base<_Tp>::__optional_storage_base;
459 _LIBCPP_INLINE_VISIBILITY
460 __optional_copy_base() = default;
462 _LIBCPP_INLINE_VISIBILITY
463 __optional_copy_base(const __optional_copy_base& __opt)
465 this->__construct_from(__opt);
468 _LIBCPP_INLINE_VISIBILITY
469 __optional_copy_base(__optional_copy_base&&) = default;
470 _LIBCPP_INLINE_VISIBILITY
471 __optional_copy_base& operator=(const __optional_copy_base&) = default;
472 _LIBCPP_INLINE_VISIBILITY
473 __optional_copy_base& operator=(__optional_copy_base&&) = default;
476 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
477 struct __optional_move_base : __optional_copy_base<_Tp>
479 using __optional_copy_base<_Tp>::__optional_copy_base;
483 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
485 using value_type = _Tp;
486 using __optional_copy_base<_Tp>::__optional_copy_base;
488 _LIBCPP_INLINE_VISIBILITY
489 __optional_move_base() = default;
490 _LIBCPP_INLINE_VISIBILITY
491 __optional_move_base(const __optional_move_base&) = default;
493 _LIBCPP_INLINE_VISIBILITY
494 __optional_move_base(__optional_move_base&& __opt)
495 noexcept(is_nothrow_move_constructible_v<value_type>)
497 this->__construct_from(_VSTD::move(__opt));
500 _LIBCPP_INLINE_VISIBILITY
501 __optional_move_base& operator=(const __optional_move_base&) = default;
502 _LIBCPP_INLINE_VISIBILITY
503 __optional_move_base& operator=(__optional_move_base&&) = default;
506 template <class _Tp, bool =
507 is_trivially_destructible<_Tp>::value &&
508 is_trivially_copy_constructible<_Tp>::value &&
509 is_trivially_copy_assignable<_Tp>::value>
510 struct __optional_copy_assign_base : __optional_move_base<_Tp>
512 using __optional_move_base<_Tp>::__optional_move_base;
516 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
518 using __optional_move_base<_Tp>::__optional_move_base;
520 _LIBCPP_INLINE_VISIBILITY
521 __optional_copy_assign_base() = default;
522 _LIBCPP_INLINE_VISIBILITY
523 __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
524 _LIBCPP_INLINE_VISIBILITY
525 __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
527 _LIBCPP_INLINE_VISIBILITY
528 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
530 this->__assign_from(__opt);
534 _LIBCPP_INLINE_VISIBILITY
535 __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
538 template <class _Tp, bool =
539 is_trivially_destructible<_Tp>::value &&
540 is_trivially_move_constructible<_Tp>::value &&
541 is_trivially_move_assignable<_Tp>::value>
542 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
544 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
548 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
550 using value_type = _Tp;
551 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
553 _LIBCPP_INLINE_VISIBILITY
554 __optional_move_assign_base() = default;
555 _LIBCPP_INLINE_VISIBILITY
556 __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
557 _LIBCPP_INLINE_VISIBILITY
558 __optional_move_assign_base(__optional_move_assign_base&&) = default;
559 _LIBCPP_INLINE_VISIBILITY
560 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
562 _LIBCPP_INLINE_VISIBILITY
563 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
564 noexcept(is_nothrow_move_assignable_v<value_type> &&
565 is_nothrow_move_constructible_v<value_type>)
567 this->__assign_from(_VSTD::move(__opt));
573 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
574 is_copy_constructible<_Tp>::value,
575 is_move_constructible<_Tp>::value
579 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
580 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
581 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
586 : private __optional_move_assign_base<_Tp>
587 , private __optional_sfinae_ctor_base_t<_Tp>
588 , private __optional_sfinae_assign_base_t<_Tp>
590 using __base = __optional_move_assign_base<_Tp>;
592 using value_type = _Tp;
595 // Disable the reference extension using this static assert.
596 static_assert(!is_same_v<value_type, in_place_t>,
597 "instantiation of optional with in_place_t is ill-formed");
598 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
599 "instantiation of optional with nullopt_t is ill-formed");
600 static_assert(!is_reference_v<value_type>,
601 "instantiation of optional with a reference type is ill-formed");
602 static_assert(is_destructible_v<value_type>,
603 "instantiation of optional with a non-destructible type is ill-formed");
605 // LWG2756: conditionally explicit conversion from _Up
606 struct _CheckOptionalArgsConstructor {
608 static constexpr bool __enable_implicit() {
609 return is_constructible_v<_Tp, _Up&&> &&
610 is_convertible_v<_Up&&, _Tp>;
614 static constexpr bool __enable_explicit() {
615 return is_constructible_v<_Tp, _Up&&> &&
616 !is_convertible_v<_Up&&, _Tp>;
620 using _CheckOptionalArgsCtor = conditional_t<
621 !is_same_v<__uncvref_t<_Up>, in_place_t> &&
622 !is_same_v<__uncvref_t<_Up>, optional>,
623 _CheckOptionalArgsConstructor,
624 __check_tuple_constructor_fail
626 template <class _QualUp>
627 struct _CheckOptionalLikeConstructor {
628 template <class _Up, class _Opt = optional<_Up>>
629 using __check_constructible_from_opt = __lazy_or<
630 is_constructible<_Tp, _Opt&>,
631 is_constructible<_Tp, _Opt const&>,
632 is_constructible<_Tp, _Opt&&>,
633 is_constructible<_Tp, _Opt const&&>,
634 is_convertible<_Opt&, _Tp>,
635 is_convertible<_Opt const&, _Tp>,
636 is_convertible<_Opt&&, _Tp>,
637 is_convertible<_Opt const&&, _Tp>
639 template <class _Up, class _Opt = optional<_Up>>
640 using __check_assignable_from_opt = __lazy_or<
641 is_assignable<_Tp&, _Opt&>,
642 is_assignable<_Tp&, _Opt const&>,
643 is_assignable<_Tp&, _Opt&&>,
644 is_assignable<_Tp&, _Opt const&&>
646 template <class _Up, class _QUp = _QualUp>
647 static constexpr bool __enable_implicit() {
648 return is_convertible<_QUp, _Tp>::value &&
649 !__check_constructible_from_opt<_Up>::value;
651 template <class _Up, class _QUp = _QualUp>
652 static constexpr bool __enable_explicit() {
653 return !is_convertible<_QUp, _Tp>::value &&
654 !__check_constructible_from_opt<_Up>::value;
656 template <class _Up, class _QUp = _QualUp>
657 static constexpr bool __enable_assign() {
658 // Construction and assignability of _Qup to _Tp has already been
660 return !__check_constructible_from_opt<_Up>::value &&
661 !__check_assignable_from_opt<_Up>::value;
665 template <class _Up, class _QualUp>
666 using _CheckOptionalLikeCtor = conditional_t<
668 __lazy_not<is_same<_Up, _Tp>>,
669 is_constructible<_Tp, _QualUp>
671 _CheckOptionalLikeConstructor<_QualUp>,
672 __check_tuple_constructor_fail
674 template <class _Up, class _QualUp>
675 using _CheckOptionalLikeAssign = conditional_t<
677 __lazy_not<is_same<_Up, _Tp>>,
678 is_constructible<_Tp, _QualUp>,
679 is_assignable<_Tp&, _QualUp>
681 _CheckOptionalLikeConstructor<_QualUp>,
682 __check_tuple_constructor_fail
686 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
687 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
688 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
689 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
691 template <class... _Args, class = enable_if_t<
692 is_constructible_v<value_type, _Args...>>
694 _LIBCPP_INLINE_VISIBILITY
695 constexpr explicit optional(in_place_t, _Args&&... __args)
696 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
698 template <class _Up, class... _Args, class = enable_if_t<
699 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
701 _LIBCPP_INLINE_VISIBILITY
702 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
703 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
705 template <class _Up = value_type, enable_if_t<
706 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
708 _LIBCPP_INLINE_VISIBILITY
709 constexpr optional(_Up&& __v)
710 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
712 template <class _Up, enable_if_t<
713 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
715 _LIBCPP_INLINE_VISIBILITY
716 constexpr explicit optional(_Up&& __v)
717 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
719 // LWG2756: conditionally explicit conversion from const optional<_Up>&
720 template <class _Up, enable_if_t<
721 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
723 _LIBCPP_INLINE_VISIBILITY
724 optional(const optional<_Up>& __v)
726 this->__construct_from(__v);
728 template <class _Up, enable_if_t<
729 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
731 _LIBCPP_INLINE_VISIBILITY
732 explicit optional(const optional<_Up>& __v)
734 this->__construct_from(__v);
737 // LWG2756: conditionally explicit conversion from optional<_Up>&&
738 template <class _Up, enable_if_t<
739 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
741 _LIBCPP_INLINE_VISIBILITY
742 optional(optional<_Up>&& __v)
744 this->__construct_from(_VSTD::move(__v));
746 template <class _Up, enable_if_t<
747 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
749 _LIBCPP_INLINE_VISIBILITY
750 explicit optional(optional<_Up>&& __v)
752 this->__construct_from(_VSTD::move(__v));
755 _LIBCPP_INLINE_VISIBILITY
756 optional& operator=(nullopt_t) noexcept
762 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
763 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
766 template <class _Up = value_type,
769 integral_constant<bool,
770 !is_same_v<__uncvref_t<_Up>, optional> &&
771 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>)
773 is_constructible<value_type, _Up>,
774 is_assignable<value_type&, _Up>
777 _LIBCPP_INLINE_VISIBILITY
781 if (this->has_value())
782 this->__get() = _VSTD::forward<_Up>(__v);
784 this->__construct(_VSTD::forward<_Up>(__v));
789 template <class _Up, enable_if_t<
790 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
792 _LIBCPP_INLINE_VISIBILITY
794 operator=(const optional<_Up>& __v)
796 this->__assign_from(__v);
801 template <class _Up, enable_if_t<
802 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
804 _LIBCPP_INLINE_VISIBILITY
806 operator=(optional<_Up>&& __v)
808 this->__assign_from(_VSTD::move(__v));
812 template <class... _Args,
815 is_constructible_v<value_type, _Args...>
818 _LIBCPP_INLINE_VISIBILITY
820 emplace(_Args&&... __args)
823 this->__construct(_VSTD::forward<_Args>(__args)...);
824 return this->__get();
827 template <class _Up, class... _Args,
830 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
833 _LIBCPP_INLINE_VISIBILITY
835 emplace(initializer_list<_Up> __il, _Args&&... __args)
838 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
839 return this->__get();
842 _LIBCPP_INLINE_VISIBILITY
843 void swap(optional& __opt)
844 noexcept(is_nothrow_move_constructible_v<value_type> &&
845 is_nothrow_swappable_v<value_type>)
847 if (this->has_value() == __opt.has_value())
850 if (this->has_value())
851 swap(this->__get(), __opt.__get());
855 if (this->has_value())
857 __opt.__construct(_VSTD::move(this->__get()));
862 this->__construct(_VSTD::move(__opt.__get()));
868 _LIBCPP_INLINE_VISIBILITY
870 add_pointer_t<value_type const>
873 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
874 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
875 return _VSTD::addressof(this->__get());
877 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
881 _LIBCPP_INLINE_VISIBILITY
883 add_pointer_t<value_type>
886 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
887 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
888 return _VSTD::addressof(this->__get());
890 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
894 _LIBCPP_INLINE_VISIBILITY
899 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
900 return this->__get();
903 _LIBCPP_INLINE_VISIBILITY
908 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
909 return this->__get();
912 _LIBCPP_INLINE_VISIBILITY
917 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
918 return _VSTD::move(this->__get());
921 _LIBCPP_INLINE_VISIBILITY
926 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
927 return _VSTD::move(this->__get());
930 _LIBCPP_INLINE_VISIBILITY
931 constexpr explicit operator bool() const noexcept { return has_value(); }
933 using __base::has_value;
936 _LIBCPP_INLINE_VISIBILITY
937 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
938 constexpr value_type const& value() const&
940 if (!this->has_value())
941 __throw_bad_optional_access();
942 return this->__get();
945 _LIBCPP_INLINE_VISIBILITY
946 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
947 constexpr value_type& value() &
949 if (!this->has_value())
950 __throw_bad_optional_access();
951 return this->__get();
954 _LIBCPP_INLINE_VISIBILITY
955 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
956 constexpr value_type&& value() &&
958 if (!this->has_value())
959 __throw_bad_optional_access();
960 return _VSTD::move(this->__get());
963 _LIBCPP_INLINE_VISIBILITY
964 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
965 constexpr value_type const&& value() const&&
967 if (!this->has_value())
968 __throw_bad_optional_access();
969 return _VSTD::move(this->__get());
973 _LIBCPP_INLINE_VISIBILITY
974 constexpr value_type value_or(_Up&& __v) const&
976 static_assert(is_copy_constructible_v<value_type>,
977 "optional<T>::value_or: T must be copy constructible");
978 static_assert(is_convertible_v<_Up, value_type>,
979 "optional<T>::value_or: U must be convertible to T");
980 return this->has_value() ? this->__get() :
981 static_cast<value_type>(_VSTD::forward<_Up>(__v));
985 _LIBCPP_INLINE_VISIBILITY
986 constexpr value_type value_or(_Up&& __v) &&
988 static_assert(is_move_constructible_v<value_type>,
989 "optional<T>::value_or: T must be move constructible");
990 static_assert(is_convertible_v<_Up, value_type>,
991 "optional<T>::value_or: U must be convertible to T");
992 return this->has_value() ? _VSTD::move(this->__get()) :
993 static_cast<value_type>(_VSTD::forward<_Up>(__v));
1000 _LIBCPP_INLINE_VISIBILITY
1002 __operator_arrow(true_type, _Up& __x)
1004 return _VSTD::addressof(__x);
1007 template <class _Up>
1008 _LIBCPP_INLINE_VISIBILITY
1009 static constexpr _Up*
1010 __operator_arrow(false_type, _Up& __x)
1016 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1018 optional(T) -> optional<T>;
1021 // Comparisons between optionals
1022 template <class _Tp, class _Up>
1023 _LIBCPP_INLINE_VISIBILITY constexpr
1025 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1026 _VSTD::declval<const _Up&>()), bool>,
1029 operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1031 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1033 if (!static_cast<bool>(__x))
1035 return *__x == *__y;
1038 template <class _Tp, class _Up>
1039 _LIBCPP_INLINE_VISIBILITY constexpr
1041 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1042 _VSTD::declval<const _Up&>()), bool>,
1045 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1047 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1049 if (!static_cast<bool>(__x))
1051 return *__x != *__y;
1054 template <class _Tp, class _Up>
1055 _LIBCPP_INLINE_VISIBILITY constexpr
1057 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1058 _VSTD::declval<const _Up&>()), bool>,
1061 operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1063 if (!static_cast<bool>(__y))
1065 if (!static_cast<bool>(__x))
1070 template <class _Tp, class _Up>
1071 _LIBCPP_INLINE_VISIBILITY constexpr
1073 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1074 _VSTD::declval<const _Up&>()), bool>,
1077 operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1079 if (!static_cast<bool>(__x))
1081 if (!static_cast<bool>(__y))
1086 template <class _Tp, class _Up>
1087 _LIBCPP_INLINE_VISIBILITY constexpr
1089 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1090 _VSTD::declval<const _Up&>()), bool>,
1093 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1095 if (!static_cast<bool>(__x))
1097 if (!static_cast<bool>(__y))
1099 return *__x <= *__y;
1102 template <class _Tp, class _Up>
1103 _LIBCPP_INLINE_VISIBILITY constexpr
1105 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1106 _VSTD::declval<const _Up&>()), bool>,
1109 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1111 if (!static_cast<bool>(__y))
1113 if (!static_cast<bool>(__x))
1115 return *__x >= *__y;
1118 // Comparisons with nullopt
1119 template <class _Tp>
1120 _LIBCPP_INLINE_VISIBILITY constexpr
1122 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1124 return !static_cast<bool>(__x);
1127 template <class _Tp>
1128 _LIBCPP_INLINE_VISIBILITY constexpr
1130 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1132 return !static_cast<bool>(__x);
1135 template <class _Tp>
1136 _LIBCPP_INLINE_VISIBILITY constexpr
1138 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1140 return static_cast<bool>(__x);
1143 template <class _Tp>
1144 _LIBCPP_INLINE_VISIBILITY constexpr
1146 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1148 return static_cast<bool>(__x);
1151 template <class _Tp>
1152 _LIBCPP_INLINE_VISIBILITY constexpr
1154 operator<(const optional<_Tp>&, nullopt_t) noexcept
1159 template <class _Tp>
1160 _LIBCPP_INLINE_VISIBILITY constexpr
1162 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1164 return static_cast<bool>(__x);
1167 template <class _Tp>
1168 _LIBCPP_INLINE_VISIBILITY constexpr
1170 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1172 return !static_cast<bool>(__x);
1175 template <class _Tp>
1176 _LIBCPP_INLINE_VISIBILITY constexpr
1178 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1183 template <class _Tp>
1184 _LIBCPP_INLINE_VISIBILITY constexpr
1186 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1188 return static_cast<bool>(__x);
1191 template <class _Tp>
1192 _LIBCPP_INLINE_VISIBILITY constexpr
1194 operator>(nullopt_t, const optional<_Tp>&) noexcept
1199 template <class _Tp>
1200 _LIBCPP_INLINE_VISIBILITY constexpr
1202 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1207 template <class _Tp>
1208 _LIBCPP_INLINE_VISIBILITY constexpr
1210 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1212 return !static_cast<bool>(__x);
1215 // Comparisons with T
1216 template <class _Tp, class _Up>
1217 _LIBCPP_INLINE_VISIBILITY constexpr
1219 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1220 _VSTD::declval<const _Up&>()), bool>,
1223 operator==(const optional<_Tp>& __x, const _Up& __v)
1225 return static_cast<bool>(__x) ? *__x == __v : false;
1228 template <class _Tp, class _Up>
1229 _LIBCPP_INLINE_VISIBILITY constexpr
1231 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1232 _VSTD::declval<const _Up&>()), bool>,
1235 operator==(const _Tp& __v, const optional<_Up>& __x)
1237 return static_cast<bool>(__x) ? __v == *__x : false;
1240 template <class _Tp, class _Up>
1241 _LIBCPP_INLINE_VISIBILITY constexpr
1243 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1244 _VSTD::declval<const _Up&>()), bool>,
1247 operator!=(const optional<_Tp>& __x, const _Up& __v)
1249 return static_cast<bool>(__x) ? *__x != __v : true;
1252 template <class _Tp, class _Up>
1253 _LIBCPP_INLINE_VISIBILITY constexpr
1255 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1256 _VSTD::declval<const _Up&>()), bool>,
1259 operator!=(const _Tp& __v, const optional<_Up>& __x)
1261 return static_cast<bool>(__x) ? __v != *__x : true;
1264 template <class _Tp, class _Up>
1265 _LIBCPP_INLINE_VISIBILITY constexpr
1267 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1268 _VSTD::declval<const _Up&>()), bool>,
1271 operator<(const optional<_Tp>& __x, const _Up& __v)
1273 return static_cast<bool>(__x) ? *__x < __v : true;
1276 template <class _Tp, class _Up>
1277 _LIBCPP_INLINE_VISIBILITY constexpr
1279 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1280 _VSTD::declval<const _Up&>()), bool>,
1283 operator<(const _Tp& __v, const optional<_Up>& __x)
1285 return static_cast<bool>(__x) ? __v < *__x : false;
1288 template <class _Tp, class _Up>
1289 _LIBCPP_INLINE_VISIBILITY constexpr
1291 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1292 _VSTD::declval<const _Up&>()), bool>,
1295 operator<=(const optional<_Tp>& __x, const _Up& __v)
1297 return static_cast<bool>(__x) ? *__x <= __v : true;
1300 template <class _Tp, class _Up>
1301 _LIBCPP_INLINE_VISIBILITY constexpr
1303 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1304 _VSTD::declval<const _Up&>()), bool>,
1307 operator<=(const _Tp& __v, const optional<_Up>& __x)
1309 return static_cast<bool>(__x) ? __v <= *__x : false;
1312 template <class _Tp, class _Up>
1313 _LIBCPP_INLINE_VISIBILITY constexpr
1315 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1316 _VSTD::declval<const _Up&>()), bool>,
1319 operator>(const optional<_Tp>& __x, const _Up& __v)
1321 return static_cast<bool>(__x) ? *__x > __v : false;
1324 template <class _Tp, class _Up>
1325 _LIBCPP_INLINE_VISIBILITY constexpr
1327 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1328 _VSTD::declval<const _Up&>()), bool>,
1331 operator>(const _Tp& __v, const optional<_Up>& __x)
1333 return static_cast<bool>(__x) ? __v > *__x : true;
1336 template <class _Tp, class _Up>
1337 _LIBCPP_INLINE_VISIBILITY constexpr
1339 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1340 _VSTD::declval<const _Up&>()), bool>,
1343 operator>=(const optional<_Tp>& __x, const _Up& __v)
1345 return static_cast<bool>(__x) ? *__x >= __v : false;
1348 template <class _Tp, class _Up>
1349 _LIBCPP_INLINE_VISIBILITY constexpr
1351 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1352 _VSTD::declval<const _Up&>()), bool>,
1355 operator>=(const _Tp& __v, const optional<_Up>& __x)
1357 return static_cast<bool>(__x) ? __v >= *__x : true;
1361 template <class _Tp>
1362 inline _LIBCPP_INLINE_VISIBILITY
1364 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1367 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1372 template <class _Tp>
1373 _LIBCPP_INLINE_VISIBILITY constexpr
1374 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1376 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1379 template <class _Tp, class... _Args>
1380 _LIBCPP_INLINE_VISIBILITY constexpr
1381 optional<_Tp> make_optional(_Args&&... __args)
1383 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1386 template <class _Tp, class _Up, class... _Args>
1387 _LIBCPP_INLINE_VISIBILITY constexpr
1388 optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1390 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1393 template <class _Tp>
1394 struct _LIBCPP_TEMPLATE_VIS hash<
1395 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1398 typedef optional<_Tp> argument_type;
1399 typedef size_t result_type;
1401 _LIBCPP_INLINE_VISIBILITY
1402 result_type operator()(const argument_type& __opt) const
1404 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1408 _LIBCPP_END_NAMESPACE_STD
1410 #endif // _LIBCPP_STD_VER > 14
1414 #endif // _LIBCPP_OPTIONAL