2 //===-------------------------- optional ----------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_OPTIONAL
11 #define _LIBCPP_OPTIONAL
19 // 23.6.3, optional for object types
20 template <class T> class optional;
22 // 23.6.4, no-value state indicator
23 struct nullopt_t{see below };
24 inline constexpr nullopt_t nullopt(unspecified );
26 // 23.6.5, class bad_optional_access
27 class bad_optional_access;
29 // 23.6.6, relational operators
30 template <class T, class U>
31 constexpr bool operator==(const optional<T>&, const optional<U>&);
32 template <class T, class U>
33 constexpr bool operator!=(const optional<T>&, const optional<U>&);
34 template <class T, class U>
35 constexpr bool operator<(const optional<T>&, const optional<U>&);
36 template <class T, class U>
37 constexpr bool operator>(const optional<T>&, const optional<U>&);
38 template <class T, class U>
39 constexpr bool operator<=(const optional<T>&, const optional<U>&);
40 template <class T, class U>
41 constexpr bool operator>=(const optional<T>&, const optional<U>&);
43 // 23.6.7 comparison with nullopt
44 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
45 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
46 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
47 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
48 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
49 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
50 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
51 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
52 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
53 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
54 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
55 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
57 // 23.6.8, comparison with T
58 template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
59 template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
60 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
61 template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
62 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
63 template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
64 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
65 template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
66 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
67 template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
68 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
69 template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
71 // 23.6.9, specialized algorithms
72 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below );
73 template <class T> constexpr optional<see below > make_optional(T&&);
74 template <class T, class... Args>
75 constexpr optional<T> make_optional(Args&&... args);
76 template <class T, class U, class... Args>
77 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
79 // 23.6.10, hash support
80 template <class T> struct hash;
81 template <class T> struct hash<optional<T>>;
83 template <class T> class optional {
87 // 23.6.3.1, constructors
88 constexpr optional() noexcept;
89 constexpr optional(nullopt_t) noexcept;
90 optional(const optional &);
91 optional(optional &&) noexcept(see below);
92 template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
93 template <class U, class... Args>
94 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
95 template <class U = T>
96 constexpr EXPLICIT optional(U &&);
98 constexpr EXPLICIT optional(const optional<U> &);
100 constexpr EXPLICIT optional(optional<U> &&);
102 // 23.6.3.2, destructor
105 // 23.6.3.3, assignment
106 optional &operator=(nullopt_t) noexcept;
107 optional &operator=(const optional &); // constexpr in C++20
108 optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
109 template <class U = T> optional &operator=(U &&);
110 template <class U> optional &operator=(const optional<U> &);
111 template <class U> optional &operator=(optional<U> &&);
112 template <class... Args> T& emplace(Args &&...);
113 template <class U, class... Args>
114 T& emplace(initializer_list<U>, Args &&...);
117 void swap(optional &) noexcept(see below );
119 // 23.6.3.5, observers
120 constexpr T const *operator->() const;
121 constexpr T *operator->();
122 constexpr T const &operator*() const &;
123 constexpr T &operator*() &;
124 constexpr T &&operator*() &&;
125 constexpr const T &&operator*() const &&;
126 constexpr explicit operator bool() const noexcept;
127 constexpr bool has_value() const noexcept;
128 constexpr T const &value() const &;
129 constexpr T &value() &;
130 constexpr T &&value() &&;
131 constexpr const T &&value() const &&;
132 template <class U> constexpr T value_or(U &&) const &;
133 template <class U> constexpr T value_or(U &&) &&;
135 // 23.6.3.6, modifiers
136 void reset() noexcept;
139 T *val; // exposition only
143 optional(T) -> optional<T>;
151 #include <__functional_base>
152 #include <functional>
153 #include <initializer_list>
156 #include <type_traits>
160 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
161 #pragma GCC system_header
165 #include <__undef_macros>
168 namespace std // purposefully not using versioning namespace
171 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
175 // Get the key function ~bad_optional_access() into the dylib
176 virtual ~bad_optional_access() _NOEXCEPT;
177 virtual const char* what() const _NOEXCEPT;
182 #if _LIBCPP_STD_VER > 14
184 _LIBCPP_BEGIN_NAMESPACE_STD
187 inline _LIBCPP_INLINE_VISIBILITY
188 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
189 void __throw_bad_optional_access() {
190 #ifndef _LIBCPP_NO_EXCEPTIONS
191 throw bad_optional_access();
199 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
200 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
203 _LIBCPP_INLINE_VAR constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
205 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
206 struct __optional_destruct_base;
209 struct __optional_destruct_base<_Tp, false>
211 typedef _Tp value_type;
212 static_assert(is_object_v<value_type>,
213 "instantiation of optional with a non-object type is undefined behavior");
221 _LIBCPP_INLINE_VISIBILITY
222 ~__optional_destruct_base()
225 __val_.~value_type();
228 _LIBCPP_INLINE_VISIBILITY
229 constexpr __optional_destruct_base() noexcept
233 template <class... _Args>
234 _LIBCPP_INLINE_VISIBILITY
235 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
236 : __val_(_VSTD::forward<_Args>(__args)...),
239 _LIBCPP_INLINE_VISIBILITY
240 void reset() noexcept
244 __val_.~value_type();
251 struct __optional_destruct_base<_Tp, true>
253 typedef _Tp value_type;
254 static_assert(is_object_v<value_type>,
255 "instantiation of optional with a non-object type is undefined behavior");
263 _LIBCPP_INLINE_VISIBILITY
264 constexpr __optional_destruct_base() noexcept
268 template <class... _Args>
269 _LIBCPP_INLINE_VISIBILITY
270 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
271 : __val_(_VSTD::forward<_Args>(__args)...),
274 _LIBCPP_INLINE_VISIBILITY
275 void reset() noexcept
284 template <class _Tp, bool = is_reference<_Tp>::value>
285 struct __optional_storage_base : __optional_destruct_base<_Tp>
287 using __base = __optional_destruct_base<_Tp>;
288 using value_type = _Tp;
289 using __base::__base;
291 _LIBCPP_INLINE_VISIBILITY
292 constexpr bool has_value() const noexcept
294 return this->__engaged_;
297 _LIBCPP_INLINE_VISIBILITY
298 constexpr value_type& __get() & noexcept
302 _LIBCPP_INLINE_VISIBILITY
303 constexpr const value_type& __get() const& noexcept
307 _LIBCPP_INLINE_VISIBILITY
308 constexpr value_type&& __get() && noexcept
310 return _VSTD::move(this->__val_);
312 _LIBCPP_INLINE_VISIBILITY
313 constexpr const value_type&& __get() const&& noexcept
315 return _VSTD::move(this->__val_);
318 template <class... _Args>
319 _LIBCPP_INLINE_VISIBILITY
320 void __construct(_Args&&... __args)
322 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
323 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
324 this->__engaged_ = true;
327 template <class _That>
328 _LIBCPP_INLINE_VISIBILITY
329 void __construct_from(_That&& __opt)
331 if (__opt.has_value())
332 __construct(_VSTD::forward<_That>(__opt).__get());
335 template <class _That>
336 _LIBCPP_INLINE_VISIBILITY
337 void __assign_from(_That&& __opt)
339 if (this->__engaged_ == __opt.has_value())
341 if (this->__engaged_)
342 this->__val_ = _VSTD::forward<_That>(__opt).__get();
346 if (this->__engaged_)
349 __construct(_VSTD::forward<_That>(__opt).__get());
354 // optional<T&> is currently required ill-formed, however it may to be in the
355 // future. For this reason it has already been implemented to ensure we can
356 // make the change in an ABI compatible manner.
358 struct __optional_storage_base<_Tp, true>
360 using value_type = _Tp;
361 using __raw_type = remove_reference_t<_Tp>;
362 __raw_type* __value_;
365 static constexpr bool __can_bind_reference() {
366 using _RawUp = typename remove_reference<_Up>::type;
367 using _UpPtr = _RawUp*;
368 using _RawTp = typename remove_reference<_Tp>::type;
369 using _TpPtr = _RawTp*;
370 using _CheckLValueArg = integral_constant<bool,
371 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
372 || is_same<_RawUp, reference_wrapper<_RawTp>>::value
373 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
375 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
376 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
377 is_convertible<_UpPtr, _TpPtr>::value);
380 _LIBCPP_INLINE_VISIBILITY
381 constexpr __optional_storage_base() noexcept
382 : __value_(nullptr) {}
384 template <class _UArg>
385 _LIBCPP_INLINE_VISIBILITY
386 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
387 : __value_(_VSTD::addressof(__uarg))
389 static_assert(__can_bind_reference<_UArg>(),
390 "Attempted to construct a reference element in tuple from a "
391 "possible temporary");
394 _LIBCPP_INLINE_VISIBILITY
395 void reset() noexcept { __value_ = nullptr; }
397 _LIBCPP_INLINE_VISIBILITY
398 constexpr bool has_value() const noexcept
399 { return __value_ != nullptr; }
401 _LIBCPP_INLINE_VISIBILITY
402 constexpr value_type& __get() const& noexcept
403 { return *__value_; }
405 _LIBCPP_INLINE_VISIBILITY
406 constexpr value_type&& __get() const&& noexcept
407 { return _VSTD::forward<value_type>(*__value_); }
409 template <class _UArg>
410 _LIBCPP_INLINE_VISIBILITY
411 void __construct(_UArg&& __val)
413 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
414 static_assert(__can_bind_reference<_UArg>(),
415 "Attempted to construct a reference element in tuple from a "
416 "possible temporary");
417 __value_ = _VSTD::addressof(__val);
420 template <class _That>
421 _LIBCPP_INLINE_VISIBILITY
422 void __construct_from(_That&& __opt)
424 if (__opt.has_value())
425 __construct(_VSTD::forward<_That>(__opt).__get());
428 template <class _That>
429 _LIBCPP_INLINE_VISIBILITY
430 void __assign_from(_That&& __opt)
432 if (has_value() == __opt.has_value())
435 *__value_ = _VSTD::forward<_That>(__opt).__get();
442 __construct(_VSTD::forward<_That>(__opt).__get());
447 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
448 struct __optional_copy_base : __optional_storage_base<_Tp>
450 using __optional_storage_base<_Tp>::__optional_storage_base;
454 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
456 using __optional_storage_base<_Tp>::__optional_storage_base;
458 _LIBCPP_INLINE_VISIBILITY
459 __optional_copy_base() = default;
461 _LIBCPP_INLINE_VISIBILITY
462 __optional_copy_base(const __optional_copy_base& __opt)
464 this->__construct_from(__opt);
467 _LIBCPP_INLINE_VISIBILITY
468 __optional_copy_base(__optional_copy_base&&) = default;
469 _LIBCPP_INLINE_VISIBILITY
470 __optional_copy_base& operator=(const __optional_copy_base&) = default;
471 _LIBCPP_INLINE_VISIBILITY
472 __optional_copy_base& operator=(__optional_copy_base&&) = default;
475 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
476 struct __optional_move_base : __optional_copy_base<_Tp>
478 using __optional_copy_base<_Tp>::__optional_copy_base;
482 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
484 using value_type = _Tp;
485 using __optional_copy_base<_Tp>::__optional_copy_base;
487 _LIBCPP_INLINE_VISIBILITY
488 __optional_move_base() = default;
489 _LIBCPP_INLINE_VISIBILITY
490 __optional_move_base(const __optional_move_base&) = default;
492 _LIBCPP_INLINE_VISIBILITY
493 __optional_move_base(__optional_move_base&& __opt)
494 noexcept(is_nothrow_move_constructible_v<value_type>)
496 this->__construct_from(_VSTD::move(__opt));
499 _LIBCPP_INLINE_VISIBILITY
500 __optional_move_base& operator=(const __optional_move_base&) = default;
501 _LIBCPP_INLINE_VISIBILITY
502 __optional_move_base& operator=(__optional_move_base&&) = default;
505 template <class _Tp, bool =
506 is_trivially_destructible<_Tp>::value &&
507 is_trivially_copy_constructible<_Tp>::value &&
508 is_trivially_copy_assignable<_Tp>::value>
509 struct __optional_copy_assign_base : __optional_move_base<_Tp>
511 using __optional_move_base<_Tp>::__optional_move_base;
515 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
517 using __optional_move_base<_Tp>::__optional_move_base;
519 _LIBCPP_INLINE_VISIBILITY
520 __optional_copy_assign_base() = default;
521 _LIBCPP_INLINE_VISIBILITY
522 __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
523 _LIBCPP_INLINE_VISIBILITY
524 __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
526 _LIBCPP_INLINE_VISIBILITY
527 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
529 this->__assign_from(__opt);
533 _LIBCPP_INLINE_VISIBILITY
534 __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
537 template <class _Tp, bool =
538 is_trivially_destructible<_Tp>::value &&
539 is_trivially_move_constructible<_Tp>::value &&
540 is_trivially_move_assignable<_Tp>::value>
541 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
543 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
547 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
549 using value_type = _Tp;
550 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
552 _LIBCPP_INLINE_VISIBILITY
553 __optional_move_assign_base() = default;
554 _LIBCPP_INLINE_VISIBILITY
555 __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
556 _LIBCPP_INLINE_VISIBILITY
557 __optional_move_assign_base(__optional_move_assign_base&&) = default;
558 _LIBCPP_INLINE_VISIBILITY
559 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
561 _LIBCPP_INLINE_VISIBILITY
562 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
563 noexcept(is_nothrow_move_assignable_v<value_type> &&
564 is_nothrow_move_constructible_v<value_type>)
566 this->__assign_from(_VSTD::move(__opt));
572 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
573 is_copy_constructible<_Tp>::value,
574 is_move_constructible<_Tp>::value
578 using __optional_sfinae_assign_base_t = __sfinae_assign_base<
579 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
580 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
585 : private __optional_move_assign_base<_Tp>
586 , private __optional_sfinae_ctor_base_t<_Tp>
587 , private __optional_sfinae_assign_base_t<_Tp>
589 using __base = __optional_move_assign_base<_Tp>;
591 using value_type = _Tp;
594 // Disable the reference extension using this static assert.
595 static_assert(!is_same_v<__uncvref_t<value_type>, in_place_t>,
596 "instantiation of optional with in_place_t is ill-formed");
597 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
598 "instantiation of optional with nullopt_t is ill-formed");
599 static_assert(!is_reference_v<value_type>,
600 "instantiation of optional with a reference type is ill-formed");
601 static_assert(is_destructible_v<value_type>,
602 "instantiation of optional with a non-destructible type is ill-formed");
603 static_assert(!is_array_v<value_type>,
604 "instantiation of optional with an array type is ill-formed");
606 // LWG2756: conditionally explicit conversion from _Up
607 struct _CheckOptionalArgsConstructor {
609 static constexpr bool __enable_implicit() {
610 return is_constructible_v<_Tp, _Up&&> &&
611 is_convertible_v<_Up&&, _Tp>;
615 static constexpr bool __enable_explicit() {
616 return is_constructible_v<_Tp, _Up&&> &&
617 !is_convertible_v<_Up&&, _Tp>;
621 using _CheckOptionalArgsCtor = _If<
622 _IsNotSame<__uncvref_t<_Up>, in_place_t>::value &&
623 _IsNotSame<__uncvref_t<_Up>, optional>::value,
624 _CheckOptionalArgsConstructor,
625 __check_tuple_constructor_fail
627 template <class _QualUp>
628 struct _CheckOptionalLikeConstructor {
629 template <class _Up, class _Opt = optional<_Up>>
630 using __check_constructible_from_opt = _Or<
631 is_constructible<_Tp, _Opt&>,
632 is_constructible<_Tp, _Opt const&>,
633 is_constructible<_Tp, _Opt&&>,
634 is_constructible<_Tp, _Opt const&&>,
635 is_convertible<_Opt&, _Tp>,
636 is_convertible<_Opt const&, _Tp>,
637 is_convertible<_Opt&&, _Tp>,
638 is_convertible<_Opt const&&, _Tp>
640 template <class _Up, class _Opt = optional<_Up>>
641 using __check_assignable_from_opt = _Or<
642 is_assignable<_Tp&, _Opt&>,
643 is_assignable<_Tp&, _Opt const&>,
644 is_assignable<_Tp&, _Opt&&>,
645 is_assignable<_Tp&, _Opt const&&>
647 template <class _Up, class _QUp = _QualUp>
648 static constexpr bool __enable_implicit() {
649 return is_convertible<_QUp, _Tp>::value &&
650 !__check_constructible_from_opt<_Up>::value;
652 template <class _Up, class _QUp = _QualUp>
653 static constexpr bool __enable_explicit() {
654 return !is_convertible<_QUp, _Tp>::value &&
655 !__check_constructible_from_opt<_Up>::value;
657 template <class _Up, class _QUp = _QualUp>
658 static constexpr bool __enable_assign() {
659 // Construction and assignability of _Qup to _Tp has already been
661 return !__check_constructible_from_opt<_Up>::value &&
662 !__check_assignable_from_opt<_Up>::value;
666 template <class _Up, class _QualUp>
667 using _CheckOptionalLikeCtor = _If<
669 _IsNotSame<_Up, _Tp>,
670 is_constructible<_Tp, _QualUp>
672 _CheckOptionalLikeConstructor<_QualUp>,
673 __check_tuple_constructor_fail
675 template <class _Up, class _QualUp>
676 using _CheckOptionalLikeAssign = _If<
678 _IsNotSame<_Up, _Tp>,
679 is_constructible<_Tp, _QualUp>,
680 is_assignable<_Tp&, _QualUp>
682 _CheckOptionalLikeConstructor<_QualUp>,
683 __check_tuple_constructor_fail
687 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
688 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
689 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
690 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
692 template <class _InPlaceT, class... _Args, class = _EnableIf<
694 _IsSame<_InPlaceT, in_place_t>,
695 is_constructible<value_type, _Args...>
699 _LIBCPP_INLINE_VISIBILITY
700 constexpr explicit optional(_InPlaceT, _Args&&... __args)
701 : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
703 template <class _Up, class... _Args, class = _EnableIf<
704 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
706 _LIBCPP_INLINE_VISIBILITY
707 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
708 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
710 template <class _Up = value_type, _EnableIf<
711 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
713 _LIBCPP_INLINE_VISIBILITY
714 constexpr optional(_Up&& __v)
715 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
717 template <class _Up, _EnableIf<
718 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
720 _LIBCPP_INLINE_VISIBILITY
721 constexpr explicit optional(_Up&& __v)
722 : __base(in_place, _VSTD::forward<_Up>(__v)) {}
724 // LWG2756: conditionally explicit conversion from const optional<_Up>&
725 template <class _Up, _EnableIf<
726 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
728 _LIBCPP_INLINE_VISIBILITY
729 optional(const optional<_Up>& __v)
731 this->__construct_from(__v);
733 template <class _Up, _EnableIf<
734 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
736 _LIBCPP_INLINE_VISIBILITY
737 explicit optional(const optional<_Up>& __v)
739 this->__construct_from(__v);
742 // LWG2756: conditionally explicit conversion from optional<_Up>&&
743 template <class _Up, _EnableIf<
744 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
746 _LIBCPP_INLINE_VISIBILITY
747 optional(optional<_Up>&& __v)
749 this->__construct_from(_VSTD::move(__v));
751 template <class _Up, _EnableIf<
752 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
754 _LIBCPP_INLINE_VISIBILITY
755 explicit optional(optional<_Up>&& __v)
757 this->__construct_from(_VSTD::move(__v));
760 _LIBCPP_INLINE_VISIBILITY
761 optional& operator=(nullopt_t) noexcept
767 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
768 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
771 template <class _Up = value_type,
774 _IsNotSame<__uncvref_t<_Up>, optional>,
776 _IsNotSame<__uncvref_t<_Up>, value_type>,
777 _Not<is_scalar<value_type>>
779 is_constructible<value_type, _Up>,
780 is_assignable<value_type&, _Up>
783 _LIBCPP_INLINE_VISIBILITY
787 if (this->has_value())
788 this->__get() = _VSTD::forward<_Up>(__v);
790 this->__construct(_VSTD::forward<_Up>(__v));
795 template <class _Up, _EnableIf<
796 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
798 _LIBCPP_INLINE_VISIBILITY
800 operator=(const optional<_Up>& __v)
802 this->__assign_from(__v);
807 template <class _Up, _EnableIf<
808 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
810 _LIBCPP_INLINE_VISIBILITY
812 operator=(optional<_Up>&& __v)
814 this->__assign_from(_VSTD::move(__v));
818 template <class... _Args,
821 is_constructible_v<value_type, _Args...>
824 _LIBCPP_INLINE_VISIBILITY
826 emplace(_Args&&... __args)
829 this->__construct(_VSTD::forward<_Args>(__args)...);
830 return this->__get();
833 template <class _Up, class... _Args,
836 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
839 _LIBCPP_INLINE_VISIBILITY
841 emplace(initializer_list<_Up> __il, _Args&&... __args)
844 this->__construct(__il, _VSTD::forward<_Args>(__args)...);
845 return this->__get();
848 _LIBCPP_INLINE_VISIBILITY
849 void swap(optional& __opt)
850 noexcept(is_nothrow_move_constructible_v<value_type> &&
851 is_nothrow_swappable_v<value_type>)
853 if (this->has_value() == __opt.has_value())
856 if (this->has_value())
857 swap(this->__get(), __opt.__get());
861 if (this->has_value())
863 __opt.__construct(_VSTD::move(this->__get()));
868 this->__construct(_VSTD::move(__opt.__get()));
874 _LIBCPP_INLINE_VISIBILITY
876 add_pointer_t<value_type const>
879 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
880 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
881 return _VSTD::addressof(this->__get());
883 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
887 _LIBCPP_INLINE_VISIBILITY
889 add_pointer_t<value_type>
892 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value");
893 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
894 return _VSTD::addressof(this->__get());
896 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get());
900 _LIBCPP_INLINE_VISIBILITY
905 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
906 return this->__get();
909 _LIBCPP_INLINE_VISIBILITY
914 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
915 return this->__get();
918 _LIBCPP_INLINE_VISIBILITY
923 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
924 return _VSTD::move(this->__get());
927 _LIBCPP_INLINE_VISIBILITY
932 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value");
933 return _VSTD::move(this->__get());
936 _LIBCPP_INLINE_VISIBILITY
937 constexpr explicit operator bool() const noexcept { return has_value(); }
939 using __base::has_value;
942 _LIBCPP_INLINE_VISIBILITY
943 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
944 constexpr value_type const& value() const&
946 if (!this->has_value())
947 __throw_bad_optional_access();
948 return this->__get();
951 _LIBCPP_INLINE_VISIBILITY
952 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
953 constexpr value_type& value() &
955 if (!this->has_value())
956 __throw_bad_optional_access();
957 return this->__get();
960 _LIBCPP_INLINE_VISIBILITY
961 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
962 constexpr value_type&& value() &&
964 if (!this->has_value())
965 __throw_bad_optional_access();
966 return _VSTD::move(this->__get());
969 _LIBCPP_INLINE_VISIBILITY
970 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
971 constexpr value_type const&& value() const&&
973 if (!this->has_value())
974 __throw_bad_optional_access();
975 return _VSTD::move(this->__get());
979 _LIBCPP_INLINE_VISIBILITY
980 constexpr value_type value_or(_Up&& __v) const&
982 static_assert(is_copy_constructible_v<value_type>,
983 "optional<T>::value_or: T must be copy constructible");
984 static_assert(is_convertible_v<_Up, value_type>,
985 "optional<T>::value_or: U must be convertible to T");
986 return this->has_value() ? this->__get() :
987 static_cast<value_type>(_VSTD::forward<_Up>(__v));
991 _LIBCPP_INLINE_VISIBILITY
992 constexpr value_type value_or(_Up&& __v) &&
994 static_assert(is_move_constructible_v<value_type>,
995 "optional<T>::value_or: T must be move constructible");
996 static_assert(is_convertible_v<_Up, value_type>,
997 "optional<T>::value_or: U must be convertible to T");
998 return this->has_value() ? _VSTD::move(this->__get()) :
999 static_cast<value_type>(_VSTD::forward<_Up>(__v));
1002 using __base::reset;
1005 template <class _Up>
1006 _LIBCPP_INLINE_VISIBILITY
1008 __operator_arrow(true_type, _Up& __x)
1010 return _VSTD::addressof(__x);
1013 template <class _Up>
1014 _LIBCPP_INLINE_VISIBILITY
1015 static constexpr _Up*
1016 __operator_arrow(false_type, _Up& __x)
1022 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1024 optional(T) -> optional<T>;
1027 // Comparisons between optionals
1028 template <class _Tp, class _Up>
1029 _LIBCPP_INLINE_VISIBILITY constexpr
1031 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1032 _VSTD::declval<const _Up&>()), bool>,
1035 operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
1037 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1039 if (!static_cast<bool>(__x))
1041 return *__x == *__y;
1044 template <class _Tp, class _Up>
1045 _LIBCPP_INLINE_VISIBILITY constexpr
1047 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1048 _VSTD::declval<const _Up&>()), bool>,
1051 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
1053 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1055 if (!static_cast<bool>(__x))
1057 return *__x != *__y;
1060 template <class _Tp, class _Up>
1061 _LIBCPP_INLINE_VISIBILITY constexpr
1063 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1064 _VSTD::declval<const _Up&>()), bool>,
1067 operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
1069 if (!static_cast<bool>(__y))
1071 if (!static_cast<bool>(__x))
1076 template <class _Tp, class _Up>
1077 _LIBCPP_INLINE_VISIBILITY constexpr
1079 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1080 _VSTD::declval<const _Up&>()), bool>,
1083 operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
1085 if (!static_cast<bool>(__x))
1087 if (!static_cast<bool>(__y))
1092 template <class _Tp, class _Up>
1093 _LIBCPP_INLINE_VISIBILITY constexpr
1095 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1096 _VSTD::declval<const _Up&>()), bool>,
1099 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
1101 if (!static_cast<bool>(__x))
1103 if (!static_cast<bool>(__y))
1105 return *__x <= *__y;
1108 template <class _Tp, class _Up>
1109 _LIBCPP_INLINE_VISIBILITY constexpr
1111 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1112 _VSTD::declval<const _Up&>()), bool>,
1115 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
1117 if (!static_cast<bool>(__y))
1119 if (!static_cast<bool>(__x))
1121 return *__x >= *__y;
1124 // Comparisons with nullopt
1125 template <class _Tp>
1126 _LIBCPP_INLINE_VISIBILITY constexpr
1128 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
1130 return !static_cast<bool>(__x);
1133 template <class _Tp>
1134 _LIBCPP_INLINE_VISIBILITY constexpr
1136 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
1138 return !static_cast<bool>(__x);
1141 template <class _Tp>
1142 _LIBCPP_INLINE_VISIBILITY constexpr
1144 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
1146 return static_cast<bool>(__x);
1149 template <class _Tp>
1150 _LIBCPP_INLINE_VISIBILITY constexpr
1152 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
1154 return static_cast<bool>(__x);
1157 template <class _Tp>
1158 _LIBCPP_INLINE_VISIBILITY constexpr
1160 operator<(const optional<_Tp>&, nullopt_t) noexcept
1165 template <class _Tp>
1166 _LIBCPP_INLINE_VISIBILITY constexpr
1168 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
1170 return static_cast<bool>(__x);
1173 template <class _Tp>
1174 _LIBCPP_INLINE_VISIBILITY constexpr
1176 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
1178 return !static_cast<bool>(__x);
1181 template <class _Tp>
1182 _LIBCPP_INLINE_VISIBILITY constexpr
1184 operator<=(nullopt_t, const optional<_Tp>&) noexcept
1189 template <class _Tp>
1190 _LIBCPP_INLINE_VISIBILITY constexpr
1192 operator>(const optional<_Tp>& __x, nullopt_t) noexcept
1194 return static_cast<bool>(__x);
1197 template <class _Tp>
1198 _LIBCPP_INLINE_VISIBILITY constexpr
1200 operator>(nullopt_t, const optional<_Tp>&) noexcept
1205 template <class _Tp>
1206 _LIBCPP_INLINE_VISIBILITY constexpr
1208 operator>=(const optional<_Tp>&, nullopt_t) noexcept
1213 template <class _Tp>
1214 _LIBCPP_INLINE_VISIBILITY constexpr
1216 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
1218 return !static_cast<bool>(__x);
1221 // Comparisons with T
1222 template <class _Tp, class _Up>
1223 _LIBCPP_INLINE_VISIBILITY constexpr
1225 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1226 _VSTD::declval<const _Up&>()), bool>,
1229 operator==(const optional<_Tp>& __x, const _Up& __v)
1231 return static_cast<bool>(__x) ? *__x == __v : false;
1234 template <class _Tp, class _Up>
1235 _LIBCPP_INLINE_VISIBILITY constexpr
1237 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() ==
1238 _VSTD::declval<const _Up&>()), bool>,
1241 operator==(const _Tp& __v, const optional<_Up>& __x)
1243 return static_cast<bool>(__x) ? __v == *__x : false;
1246 template <class _Tp, class _Up>
1247 _LIBCPP_INLINE_VISIBILITY constexpr
1249 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1250 _VSTD::declval<const _Up&>()), bool>,
1253 operator!=(const optional<_Tp>& __x, const _Up& __v)
1255 return static_cast<bool>(__x) ? *__x != __v : true;
1258 template <class _Tp, class _Up>
1259 _LIBCPP_INLINE_VISIBILITY constexpr
1261 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() !=
1262 _VSTD::declval<const _Up&>()), bool>,
1265 operator!=(const _Tp& __v, const optional<_Up>& __x)
1267 return static_cast<bool>(__x) ? __v != *__x : true;
1270 template <class _Tp, class _Up>
1271 _LIBCPP_INLINE_VISIBILITY constexpr
1273 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1274 _VSTD::declval<const _Up&>()), bool>,
1277 operator<(const optional<_Tp>& __x, const _Up& __v)
1279 return static_cast<bool>(__x) ? *__x < __v : true;
1282 template <class _Tp, class _Up>
1283 _LIBCPP_INLINE_VISIBILITY constexpr
1285 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <
1286 _VSTD::declval<const _Up&>()), bool>,
1289 operator<(const _Tp& __v, const optional<_Up>& __x)
1291 return static_cast<bool>(__x) ? __v < *__x : false;
1294 template <class _Tp, class _Up>
1295 _LIBCPP_INLINE_VISIBILITY constexpr
1297 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1298 _VSTD::declval<const _Up&>()), bool>,
1301 operator<=(const optional<_Tp>& __x, const _Up& __v)
1303 return static_cast<bool>(__x) ? *__x <= __v : true;
1306 template <class _Tp, class _Up>
1307 _LIBCPP_INLINE_VISIBILITY constexpr
1309 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <=
1310 _VSTD::declval<const _Up&>()), bool>,
1313 operator<=(const _Tp& __v, const optional<_Up>& __x)
1315 return static_cast<bool>(__x) ? __v <= *__x : false;
1318 template <class _Tp, class _Up>
1319 _LIBCPP_INLINE_VISIBILITY constexpr
1321 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1322 _VSTD::declval<const _Up&>()), bool>,
1325 operator>(const optional<_Tp>& __x, const _Up& __v)
1327 return static_cast<bool>(__x) ? *__x > __v : false;
1330 template <class _Tp, class _Up>
1331 _LIBCPP_INLINE_VISIBILITY constexpr
1333 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >
1334 _VSTD::declval<const _Up&>()), bool>,
1337 operator>(const _Tp& __v, const optional<_Up>& __x)
1339 return static_cast<bool>(__x) ? __v > *__x : true;
1342 template <class _Tp, class _Up>
1343 _LIBCPP_INLINE_VISIBILITY constexpr
1345 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1346 _VSTD::declval<const _Up&>()), bool>,
1349 operator>=(const optional<_Tp>& __x, const _Up& __v)
1351 return static_cast<bool>(__x) ? *__x >= __v : false;
1354 template <class _Tp, class _Up>
1355 _LIBCPP_INLINE_VISIBILITY constexpr
1357 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >=
1358 _VSTD::declval<const _Up&>()), bool>,
1361 operator>=(const _Tp& __v, const optional<_Up>& __x)
1363 return static_cast<bool>(__x) ? __v >= *__x : true;
1367 template <class _Tp>
1368 inline _LIBCPP_INLINE_VISIBILITY
1370 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
1373 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
1378 template <class _Tp>
1379 _LIBCPP_INLINE_VISIBILITY constexpr
1380 optional<decay_t<_Tp>> make_optional(_Tp&& __v)
1382 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
1385 template <class _Tp, class... _Args>
1386 _LIBCPP_INLINE_VISIBILITY constexpr
1387 optional<_Tp> make_optional(_Args&&... __args)
1389 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
1392 template <class _Tp, class _Up, class... _Args>
1393 _LIBCPP_INLINE_VISIBILITY constexpr
1394 optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
1396 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
1399 template <class _Tp>
1400 struct _LIBCPP_TEMPLATE_VIS hash<
1401 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
1404 typedef optional<_Tp> argument_type;
1405 typedef size_t result_type;
1407 _LIBCPP_INLINE_VISIBILITY
1408 result_type operator()(const argument_type& __opt) const
1410 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1414 _LIBCPP_END_NAMESPACE_STD
1416 #endif // _LIBCPP_STD_VER > 14
1420 #endif // _LIBCPP_OPTIONAL