29 #ifndef _GLIBCXX_OPTIONAL
30 #define _GLIBCXX_OPTIONAL 1
32 #pragma GCC system_header
34 #if __cplusplus >= 201703L
37 #include <type_traits>
45 namespace std _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
54 #define __cpp_lib_optional 201606L
56 template<
typename _Tp>
74 inline constexpr nullopt_t
nullopt { nullopt_t::_Construct::_Token };
81 class bad_optional_access :
public exception
84 bad_optional_access() { }
86 virtual const char* what() const noexcept
override
87 {
return "bad optional access"; }
89 virtual ~bad_optional_access() noexcept = default;
93 __throw_bad_optional_access()
94 __attribute__((__noreturn__));
98 __throw_bad_optional_access()
99 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }
103 template <
typename _Tp>
104 struct _Optional_payload_base
106 using _Stored_type = remove_const_t<_Tp>;
108 _Optional_payload_base() =
default;
109 ~_Optional_payload_base() =
default;
111 template<
typename... _Args>
113 _Optional_payload_base(in_place_t __tag, _Args&&... __args)
114 : _M_payload(__tag,
std::
forward<_Args>(__args)...),
118 template<
typename _Up,
typename... _Args>
122 : _M_payload(__il,
std::
forward<_Args>(__args)...),
129 _Optional_payload_base(
bool __engaged,
130 const _Optional_payload_base& __other)
132 if (__other._M_engaged)
133 this->_M_construct(__other._M_get());
139 _Optional_payload_base(
bool __engaged,
140 _Optional_payload_base&& __other)
142 if (__other._M_engaged)
143 this->_M_construct(
std::move(__other._M_get()));
148 _Optional_payload_base(
const _Optional_payload_base&) =
default;
152 _Optional_payload_base(_Optional_payload_base&&) =
default;
154 _Optional_payload_base&
155 operator=(
const _Optional_payload_base&) =
default;
157 _Optional_payload_base&
158 operator=(_Optional_payload_base&&) =
default;
162 _M_copy_assign(
const _Optional_payload_base& __other)
164 if (this->_M_engaged && __other._M_engaged)
165 this->_M_get() = __other._M_get();
168 if (__other._M_engaged)
169 this->_M_construct(__other._M_get());
177 _M_move_assign(_Optional_payload_base&& __other)
178 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
179 is_nothrow_move_assignable<_Tp>>)
181 if (this->_M_engaged && __other._M_engaged)
182 this->_M_get() =
std::move(__other._M_get());
185 if (__other._M_engaged)
186 this->_M_construct(
std::move(__other._M_get()));
192 struct _Empty_byte { };
194 template<
typename _Up,
bool = is_trivially_destructible_v<_Up>>
197 constexpr _Storage() noexcept : _M_empty() { }
199 template<
typename... _Args>
201 _Storage(in_place_t, _Args&&... __args)
205 template<
typename _Vp,
typename... _Args>
208 : _M_value(__il,
std::
forward<_Args>(__args)...)
211 _Empty_byte _M_empty;
215 template<
typename _Up>
216 union _Storage<_Up, false>
218 constexpr _Storage() noexcept : _M_empty() { }
220 template<
typename... _Args>
222 _Storage(in_place_t, _Args&&... __args)
226 template<
typename _Vp,
typename... _Args>
229 : _M_value(__il,
std::
forward<_Args>(__args)...)
235 _Empty_byte _M_empty;
239 _Storage<_Stored_type> _M_payload;
241 bool _M_engaged =
false;
243 template<
typename... _Args>
245 _M_construct(_Args&&... __args)
246 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
249 _Stored_type(std::forward<_Args>(__args)...);
250 this->_M_engaged =
true;
254 _M_destroy() noexcept
257 _M_payload._M_value.~_Stored_type();
266 {
return this->_M_payload._M_value; }
269 _M_get() const noexcept
270 {
return this->_M_payload._M_value; }
276 if (this->_M_engaged)
282 template <
typename _Tp,
284 is_trivially_destructible_v<_Tp>,
286 is_trivially_copy_assignable_v<_Tp>
287 && is_trivially_copy_constructible_v<_Tp>,
289 is_trivially_move_assignable_v<_Tp>
290 && is_trivially_move_constructible_v<_Tp>>
291 struct _Optional_payload;
294 template <
typename _Tp>
295 struct _Optional_payload<_Tp, true, true, true>
296 : _Optional_payload_base<_Tp>
298 using _Optional_payload_base<_Tp>::_Optional_payload_base;
300 _Optional_payload() =
default;
304 template <
typename _Tp>
305 struct _Optional_payload<_Tp, true, false, true>
306 : _Optional_payload_base<_Tp>
308 using _Optional_payload_base<_Tp>::_Optional_payload_base;
310 _Optional_payload() =
default;
311 ~_Optional_payload() =
default;
312 _Optional_payload(
const _Optional_payload&) =
default;
313 _Optional_payload(_Optional_payload&&) =
default;
314 _Optional_payload& operator=(_Optional_payload&&) =
default;
319 operator=(
const _Optional_payload& __other)
321 this->_M_copy_assign(__other);
327 template <
typename _Tp>
328 struct _Optional_payload<_Tp, true, true, false>
329 : _Optional_payload_base<_Tp>
331 using _Optional_payload_base<_Tp>::_Optional_payload_base;
333 _Optional_payload() =
default;
334 ~_Optional_payload() =
default;
335 _Optional_payload(
const _Optional_payload&) =
default;
336 _Optional_payload(_Optional_payload&&) =
default;
337 _Optional_payload& operator=(
const _Optional_payload&) =
default;
342 operator=(_Optional_payload&& __other)
343 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
344 is_nothrow_move_assignable<_Tp>>)
346 this->_M_move_assign(
std::move(__other));
352 template <
typename _Tp>
353 struct _Optional_payload<_Tp, true, false, false>
354 : _Optional_payload_base<_Tp>
356 using _Optional_payload_base<_Tp>::_Optional_payload_base;
358 _Optional_payload() =
default;
359 ~_Optional_payload() =
default;
360 _Optional_payload(
const _Optional_payload&) =
default;
361 _Optional_payload(_Optional_payload&&) =
default;
366 operator=(
const _Optional_payload& __other)
368 this->_M_copy_assign(__other);
375 operator=(_Optional_payload&& __other)
376 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
377 is_nothrow_move_assignable<_Tp>>)
379 this->_M_move_assign(
std::move(__other));
385 template <
typename _Tp,
bool _Copy,
bool _Move>
386 struct _Optional_payload<_Tp, false, _Copy, _Move>
387 : _Optional_payload<_Tp, true, false, false>
390 using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
391 _Optional_payload() =
default;
392 _Optional_payload(
const _Optional_payload&) =
default;
393 _Optional_payload(_Optional_payload&&) =
default;
394 _Optional_payload& operator=(
const _Optional_payload&) =
default;
395 _Optional_payload& operator=(_Optional_payload&&) =
default;
398 ~_Optional_payload() { this->_M_reset(); }
403 template<
typename _Tp,
typename _Dp>
404 class _Optional_base_impl
407 using _Stored_type = remove_const_t<_Tp>;
411 template<
typename... _Args>
413 _M_construct(_Args&&... __args)
414 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
419 static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
423 _M_destruct() noexcept
424 { static_cast<_Dp*>(
this)->_M_payload._M_destroy(); }
429 { static_cast<_Dp*>(
this)->_M_payload._M_reset(); }
431 constexpr
bool _M_is_engaged() const noexcept
432 {
return static_cast<const _Dp*>(
this)->_M_payload._M_engaged; }
438 __glibcxx_assert(this->_M_is_engaged());
439 return static_cast<_Dp*>(
this)->_M_payload._M_get();
443 _M_get() const noexcept
445 __glibcxx_assert(this->_M_is_engaged());
446 return static_cast<const _Dp*>(
this)->_M_payload._M_get();
468 template<
typename _Tp,
469 bool = is_trivially_copy_constructible_v<_Tp>,
470 bool = is_trivially_move_constructible_v<_Tp>>
471 struct _Optional_base
472 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
475 constexpr _Optional_base() =
default;
478 template<
typename... _Args,
479 enable_if_t<is_constructible_v<_Tp, _Args&&...>,
bool> =
false>
480 constexpr
explicit _Optional_base(in_place_t, _Args&&... __args)
484 template<
typename _Up,
typename... _Args,
486 initializer_list<_Up>&,
487 _Args&&...>,
bool> =
false>
488 constexpr
explicit _Optional_base(in_place_t,
489 initializer_list<_Up> __il,
496 constexpr _Optional_base(
const _Optional_base& __other)
497 : _M_payload(__other._M_payload._M_engaged,
501 constexpr _Optional_base(_Optional_base&& __other)
502 noexcept(is_nothrow_move_constructible_v<_Tp>)
503 : _M_payload(__other._M_payload._M_engaged,
508 _Optional_base& operator=(
const _Optional_base&) =
default;
509 _Optional_base& operator=(_Optional_base&&) =
default;
511 _Optional_payload<_Tp> _M_payload;
514 template<
typename _Tp>
515 struct _Optional_base<_Tp, false, true>
516 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
519 constexpr _Optional_base() =
default;
522 template<
typename... _Args,
523 enable_if_t<is_constructible_v<_Tp, _Args&&...>,
bool> =
false>
524 constexpr
explicit _Optional_base(in_place_t, _Args&&... __args)
528 template<
typename _Up,
typename... _Args,
530 initializer_list<_Up>&,
531 _Args&&...>,
bool> =
false>
532 constexpr
explicit _Optional_base(in_place_t,
533 initializer_list<_Up> __il,
540 constexpr _Optional_base(
const _Optional_base& __other)
541 : _M_payload(__other._M_payload._M_engaged,
545 constexpr _Optional_base(_Optional_base&& __other) =
default;
548 _Optional_base& operator=(
const _Optional_base&) =
default;
549 _Optional_base& operator=(_Optional_base&&) =
default;
551 _Optional_payload<_Tp> _M_payload;
554 template<
typename _Tp>
555 struct _Optional_base<_Tp, true, false>
556 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
559 constexpr _Optional_base() =
default;
562 template<
typename... _Args,
563 enable_if_t<is_constructible_v<_Tp, _Args&&...>,
bool> =
false>
564 constexpr
explicit _Optional_base(in_place_t, _Args&&... __args)
568 template<
typename _Up,
typename... _Args,
570 initializer_list<_Up>&,
571 _Args&&...>,
bool> =
false>
572 constexpr
explicit _Optional_base(in_place_t,
573 initializer_list<_Up> __il,
580 constexpr _Optional_base(
const _Optional_base& __other) =
default;
582 constexpr _Optional_base(_Optional_base&& __other)
583 noexcept(is_nothrow_move_constructible_v<_Tp>)
584 : _M_payload(__other._M_payload._M_engaged,
589 _Optional_base& operator=(
const _Optional_base&) =
default;
590 _Optional_base& operator=(_Optional_base&&) =
default;
592 _Optional_payload<_Tp> _M_payload;
595 template<
typename _Tp>
596 struct _Optional_base<_Tp, true, true>
597 : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
600 constexpr _Optional_base() =
default;
603 template<
typename... _Args,
604 enable_if_t<is_constructible_v<_Tp, _Args&&...>,
bool> =
false>
605 constexpr
explicit _Optional_base(in_place_t, _Args&&... __args)
609 template<
typename _Up,
typename... _Args,
611 initializer_list<_Up>&,
612 _Args&&...>,
bool> =
false>
613 constexpr
explicit _Optional_base(in_place_t,
614 initializer_list<_Up> __il,
621 constexpr _Optional_base(
const _Optional_base& __other) =
default;
622 constexpr _Optional_base(_Optional_base&& __other) =
default;
625 _Optional_base& operator=(
const _Optional_base&) =
default;
626 _Optional_base& operator=(_Optional_base&&) =
default;
628 _Optional_payload<_Tp> _M_payload;
631 template<
typename _Tp>
634 template<
typename _Tp,
typename _Up>
635 using __converts_from_optional =
636 __or_<is_constructible<_Tp, const optional<_Up>&>,
637 is_constructible<_Tp, optional<_Up>&>,
638 is_constructible<_Tp, const optional<_Up>&&>,
639 is_constructible<_Tp, optional<_Up>&&>,
640 is_convertible<const optional<_Up>&, _Tp>,
641 is_convertible<optional<_Up>&, _Tp>,
642 is_convertible<const optional<_Up>&&, _Tp>,
643 is_convertible<optional<_Up>&&, _Tp>>;
645 template<
typename _Tp,
typename _Up>
646 using __assigns_from_optional =
647 __or_<is_assignable<_Tp&, const optional<_Up>&>,
648 is_assignable<_Tp&, optional<_Up>&>,
649 is_assignable<_Tp&, const optional<_Up>&&>,
650 is_assignable<_Tp&, optional<_Up>&&>>;
655 template<
typename _Tp>
657 :
private _Optional_base<_Tp>,
658 private _Enable_copy_move<
660 is_copy_constructible_v<_Tp>,
662 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
664 is_move_constructible_v<_Tp>,
666 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
670 static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
671 static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
672 static_assert(!is_reference_v<_Tp>);
675 using _Base = _Optional_base<_Tp>;
678 template<
typename _Up>
679 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
680 template<
typename _Up>
681 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
682 template<
typename... _Cond>
683 using _Requires =
enable_if_t<__and_v<_Cond...>,
bool>;
686 using value_type = _Tp;
688 constexpr optional() =
default;
690 constexpr optional(nullopt_t) noexcept { }
693 template<
typename _Up = _Tp,
694 _Requires<__not_self<_Up>, __not_tag<_Up>,
695 is_constructible<_Tp, _Up&&>,
696 is_convertible<_Up&&, _Tp>> =
true>
701 template<
typename _Up = _Tp,
702 _Requires<__not_self<_Up>, __not_tag<_Up>,
703 is_constructible<_Tp, _Up&&>,
704 __not_<is_convertible<_Up&&, _Tp>>> =
false>
709 template<
typename _Up,
710 _Requires<__not_<is_same<_Tp, _Up>>,
711 is_constructible<_Tp, const _Up&>,
712 is_convertible<const _Up&, _Tp>,
713 __not_<__converts_from_optional<_Tp, _Up>>> =
true>
715 optional(
const optional<_Up>& __t)
721 template<
typename _Up,
722 _Requires<__not_<is_same<_Tp, _Up>>,
723 is_constructible<_Tp, const _Up&>,
724 __not_<is_convertible<const _Up&, _Tp>>,
725 __not_<__converts_from_optional<_Tp, _Up>>> =
false>
727 optional(
const optional<_Up>& __t)
733 template <
typename _Up,
734 _Requires<__not_<is_same<_Tp, _Up>>,
735 is_constructible<_Tp, _Up&&>,
736 is_convertible<_Up&&, _Tp>,
737 __not_<__converts_from_optional<_Tp, _Up>>> =
true>
739 optional(optional<_Up>&& __t)
745 template <
typename _Up,
746 _Requires<__not_<is_same<_Tp, _Up>>,
747 is_constructible<_Tp, _Up&&>,
748 __not_<is_convertible<_Up&&, _Tp>>,
749 __not_<__converts_from_optional<_Tp, _Up>>> =
false>
751 optional(optional<_Up>&& __t)
757 template<
typename... _Args,
758 _Requires<is_constructible<_Tp, _Args&&...>> =
false>
760 optional(in_place_t, _Args&&... __args)
763 template<
typename _Up,
typename... _Args,
764 _Requires<is_constructible<_Tp,
765 initializer_list<_Up>&,
766 _Args&&...>> =
false>
768 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
773 operator=(nullopt_t) noexcept
779 template<
typename _Up = _Tp>
780 enable_if_t<__and_v<__not_self<_Up>,
781 __not_<__and_<is_scalar<_Tp>,
782 is_same<_Tp, decay_t<_Up>>>>,
783 is_constructible<_Tp, _Up>,
784 is_assignable<_Tp&, _Up>>,
788 if (this->_M_is_engaged())
789 this->_M_get() = std::forward<_Up>(__u);
791 this->_M_construct(std::forward<_Up>(__u));
796 template<
typename _Up>
797 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
798 is_constructible<_Tp, const _Up&>,
799 is_assignable<_Tp&, _Up>,
800 __not_<__converts_from_optional<_Tp, _Up>>,
801 __not_<__assigns_from_optional<_Tp, _Up>>>,
803 operator=(
const optional<_Up>& __u)
807 if (this->_M_is_engaged())
808 this->_M_get() = *__u;
810 this->_M_construct(*__u);
819 template<
typename _Up>
820 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
821 is_constructible<_Tp, _Up>,
822 is_assignable<_Tp&, _Up>,
823 __not_<__converts_from_optional<_Tp, _Up>>,
824 __not_<__assigns_from_optional<_Tp, _Up>>>,
826 operator=(optional<_Up>&& __u)
830 if (this->_M_is_engaged())
843 template<
typename... _Args>
844 enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
845 emplace(_Args&&... __args)
848 this->_M_construct(std::forward<_Args>(__args)...);
849 return this->_M_get();
852 template<
typename _Up,
typename... _Args>
853 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
855 emplace(initializer_list<_Up> __il, _Args&&... __args)
858 this->_M_construct(__il, std::forward<_Args>(__args)...);
859 return this->_M_get();
866 swap(optional& __other)
867 noexcept(is_nothrow_move_constructible_v<_Tp>
868 && is_nothrow_swappable_v<_Tp>)
872 if (this->_M_is_engaged() && __other._M_is_engaged())
873 swap(this->_M_get(), __other._M_get());
874 else if (this->_M_is_engaged())
876 __other._M_construct(
std::move(this->_M_get()));
879 else if (__other._M_is_engaged())
881 this->_M_construct(
std::move(__other._M_get()));
882 __other._M_destruct();
897 {
return this->_M_get(); }
901 {
return this->_M_get(); }
907 constexpr
const _Tp&&
911 constexpr
explicit operator bool() const noexcept
912 {
return this->_M_is_engaged(); }
914 constexpr
bool has_value() const noexcept
915 {
return this->_M_is_engaged(); }
920 return this->_M_is_engaged()
922 : (__throw_bad_optional_access(), this->_M_get());
928 return this->_M_is_engaged()
930 : (__throw_bad_optional_access(), this->_M_get());
936 return this->_M_is_engaged()
938 : (__throw_bad_optional_access(),
std::
move(this->_M_get()));
941 constexpr
const _Tp&&
944 return this->_M_is_engaged()
946 : (__throw_bad_optional_access(),
std::
move(this->_M_get()));
949 template<
typename _Up>
951 value_or(_Up&& __u)
const&
953 static_assert(is_copy_constructible_v<_Tp>);
954 static_assert(is_convertible_v<_Up&&, _Tp>);
956 return this->_M_is_engaged()
957 ? this->_M_get() : static_cast<_Tp>(
std::
forward<_Up>(__u));
960 template<
typename _Up>
962 value_or(_Up&& __u) &&
964 static_assert(is_move_constructible_v<_Tp>);
965 static_assert(is_convertible_v<_Up&&, _Tp>);
967 return this->_M_is_engaged()
972 void reset() noexcept { this->_M_reset(); }
975 template<
typename _Tp>
976 using __optional_relop_t =
977 enable_if_t<is_convertible<_Tp, bool>::value,
bool>;
980 template<
typename _Tp,
typename _Up>
982 operator==(
const optional<_Tp>& __lhs,
const optional<_Up>& __rhs)
983 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
985 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
986 && (!__lhs || *__lhs == *__rhs);
989 template<
typename _Tp,
typename _Up>
991 operator!=(
const optional<_Tp>& __lhs,
const optional<_Up>& __rhs)
992 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
994 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
995 || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
998 template<
typename _Tp,
typename _Up>
1000 operator<(
const optional<_Tp>& __lhs,
const optional<_Up>& __rhs)
1001 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1003 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
1006 template<
typename _Tp,
typename _Up>
1008 operator>(
const optional<_Tp>& __lhs,
const optional<_Up>& __rhs)
1009 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1011 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
1014 template<
typename _Tp,
typename _Up>
1016 operator<=(
const optional<_Tp>& __lhs,
const optional<_Up>& __rhs)
1017 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1019 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
1022 template<
typename _Tp,
typename _Up>
1024 operator>=(
const optional<_Tp>& __lhs,
const optional<_Up>& __rhs)
1025 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1027 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
1031 template<
typename _Tp>
1033 operator==(
const optional<_Tp>& __lhs, nullopt_t) noexcept
1036 template<
typename _Tp>
1038 operator==(nullopt_t,
const optional<_Tp>& __rhs) noexcept
1041 template<
typename _Tp>
1043 operator!=(
const optional<_Tp>& __lhs, nullopt_t) noexcept
1044 {
return static_cast<bool>(__lhs); }
1046 template<
typename _Tp>
1048 operator!=(nullopt_t,
const optional<_Tp>& __rhs) noexcept
1049 {
return static_cast<bool>(__rhs); }
1051 template<
typename _Tp>
1053 operator<(
const optional<_Tp>& , nullopt_t) noexcept
1056 template<
typename _Tp>
1058 operator<(nullopt_t,
const optional<_Tp>& __rhs) noexcept
1059 {
return static_cast<bool>(__rhs); }
1061 template<
typename _Tp>
1063 operator>(
const optional<_Tp>& __lhs, nullopt_t) noexcept
1064 {
return static_cast<bool>(__lhs); }
1066 template<
typename _Tp>
1068 operator>(nullopt_t,
const optional<_Tp>& ) noexcept
1071 template<
typename _Tp>
1073 operator<=(
const optional<_Tp>& __lhs, nullopt_t) noexcept
1076 template<
typename _Tp>
1078 operator<=(nullopt_t,
const optional<_Tp>& ) noexcept
1081 template<
typename _Tp>
1083 operator>=(
const optional<_Tp>& , nullopt_t) noexcept
1086 template<
typename _Tp>
1088 operator>=(nullopt_t,
const optional<_Tp>& __rhs) noexcept
1092 template<
typename _Tp,
typename _Up>
1094 operator==(
const optional<_Tp>& __lhs,
const _Up& __rhs)
1095 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())>
1096 {
return __lhs && *__lhs == __rhs; }
1098 template<
typename _Tp,
typename _Up>
1100 operator==(
const _Up& __lhs,
const optional<_Tp>& __rhs)
1101 -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())>
1102 {
return __rhs && __lhs == *__rhs; }
1104 template<
typename _Tp,
typename _Up>
1106 operator!=(
const optional<_Tp>& __lhs,
const _Up& __rhs)
1107 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())>
1108 {
return !__lhs || *__lhs != __rhs; }
1110 template<
typename _Tp,
typename _Up>
1112 operator!=(
const _Up& __lhs,
const optional<_Tp>& __rhs)
1113 -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())>
1114 {
return !__rhs || __lhs != *__rhs; }
1116 template<
typename _Tp,
typename _Up>
1118 operator<(
const optional<_Tp>& __lhs,
const _Up& __rhs)
1119 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())>
1120 {
return !__lhs || *__lhs < __rhs; }
1122 template<
typename _Tp,
typename _Up>
1124 operator<(
const _Up& __lhs,
const optional<_Tp>& __rhs)
1125 -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())>
1126 {
return __rhs && __lhs < *__rhs; }
1128 template<
typename _Tp,
typename _Up>
1130 operator>(
const optional<_Tp>& __lhs,
const _Up& __rhs)
1131 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())>
1132 {
return __lhs && *__lhs > __rhs; }
1134 template<
typename _Tp,
typename _Up>
1136 operator>(
const _Up& __lhs,
const optional<_Tp>& __rhs)
1137 -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())>
1138 {
return !__rhs || __lhs > *__rhs; }
1140 template<
typename _Tp,
typename _Up>
1142 operator<=(
const optional<_Tp>& __lhs,
const _Up& __rhs)
1143 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())>
1144 {
return !__lhs || *__lhs <= __rhs; }
1146 template<
typename _Tp,
typename _Up>
1148 operator<=(
const _Up& __lhs,
const optional<_Tp>& __rhs)
1149 -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())>
1150 {
return __rhs && __lhs <= *__rhs; }
1152 template<
typename _Tp,
typename _Up>
1154 operator>=(
const optional<_Tp>& __lhs,
const _Up& __rhs)
1155 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())>
1156 {
return __lhs && *__lhs >= __rhs; }
1158 template<
typename _Tp,
typename _Up>
1160 operator>=(
const _Up& __lhs,
const optional<_Tp>& __rhs)
1161 -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())>
1162 {
return !__rhs || __lhs >= *__rhs; }
1168 template<
typename _Tp>
1169 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
1170 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
1171 noexcept(noexcept(__lhs.swap(__rhs)))
1172 { __lhs.swap(__rhs); }
1174 template<
typename _Tp>
1175 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
1176 swap(optional<_Tp>&, optional<_Tp>&) =
delete;
1178 template<
typename _Tp>
1179 constexpr optional<decay_t<_Tp>>
1180 make_optional(_Tp&& __t)
1181 {
return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
1183 template<
typename _Tp,
typename ..._Args>
1184 constexpr optional<_Tp>
1185 make_optional(_Args&&... __args)
1186 {
return optional<_Tp> {
in_place, std::forward<_Args>(__args)... }; }
1188 template<
typename _Tp,
typename _Up,
typename ..._Args>
1189 constexpr optional<_Tp>
1190 make_optional(initializer_list<_Up> __il, _Args&&... __args)
1191 {
return optional<_Tp> {
in_place, __il, std::forward<_Args>(__args)... }; }
1195 template<
typename _Tp,
typename _Up = remove_const_t<_Tp>,
1196 bool = __poison_hash<_Up>::__enable_hash_call>
1197 struct __optional_hash_call_base
1200 operator()(
const optional<_Tp>& __t)
const
1201 noexcept(noexcept(hash<_Up>{}(*__t)))
1205 constexpr
size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
1206 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
1210 template<
typename _Tp,
typename _Up>
1211 struct __optional_hash_call_base<_Tp, _Up, false> {};
1213 template<
typename _Tp>
1214 struct hash<optional<_Tp>>
1215 :
private __poison_hash<remove_const_t<_Tp>>,
1216 public __optional_hash_call_base<_Tp>
1218 using result_type [[__deprecated__]] = size_t;
1219 using argument_type [[__deprecated__]] = optional<_Tp>;
1222 template<
typename _Tp>
1223 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
1228 #if __cpp_deduction_guides >= 201606
1229 template <
typename _Tp> optional(_Tp) -> optional<_Tp>;
1232 _GLIBCXX_END_NAMESPACE_VERSION
1237 #endif // _GLIBCXX_OPTIONAL