29 #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL 30 #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1 44 #if __cplusplus >= 201402L 56 namespace std _GLIBCXX_VISIBILITY(default)
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
60 namespace experimental
62 inline namespace fundamentals_v1
75 #define __cpp_lib_experimental_optional 201411 80 template<
typename _Tp>
99 enum class _Construct { _Token };
102 explicit constexpr
nullopt_t(_Construct) { }
127 __throw_bad_optional_access(
const char*)
128 __attribute__((__noreturn__));
132 __throw_bad_optional_access(
const char* __s)
135 #ifndef __cpp_lib_addressof_constexpr 136 template<
typename _Tp,
typename =
void>
139 template<
typename _Tp>
140 struct _Has_addressof_mem<_Tp,
141 __void_t<decltype(
std::declval<const _Tp&>().operator&() )>
145 template<
typename _Tp,
typename =
void>
148 template<
typename _Tp>
149 struct _Has_addressof_free<_Tp,
150 __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
161 template<
typename _Tp>
163 : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
172 template<
typename _Tp>
181 template<
typename _Tp>
186 #endif // __cpp_lib_addressof_constexpr 200 template<
typename _Tp,
bool _ShouldProvideDestructor =
221 template<
typename... _Args>
223 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(
true) { }
225 template<
typename _Up,
typename... _Args,
233 : _M_payload(__il, std::forward<_Args>(__args)...),
239 if (__other._M_engaged)
240 this->_M_construct(__other._M_get());
246 if (__other._M_engaged)
247 this->_M_construct(std::move(__other._M_get()));
254 if (this->_M_engaged && __other._M_engaged)
255 this->_M_get() = __other._M_get();
258 if (__other._M_engaged)
259 this->_M_construct(__other._M_get());
272 if (this->_M_engaged && __other._M_engaged)
273 this->_M_get() = std::move(__other._M_get());
276 if (__other._M_engaged)
277 this->_M_construct(std::move(__other._M_get()));
287 if (this->_M_engaged)
288 this->_M_payload.~_Stored_type();
294 constexpr
bool _M_is_engaged()
const noexcept
295 {
return this->_M_engaged; }
300 {
return _M_payload; }
303 _M_get()
const noexcept
304 {
return _M_payload; }
308 template<
typename... _Args>
310 _M_construct(_Args&&... __args)
314 _Stored_type(std::forward<_Args>(__args)...);
315 this->_M_engaged =
true;
321 this->_M_engaged =
false;
322 this->_M_payload.~_Stored_type();
329 if (this->_M_engaged)
334 struct _Empty_byte { };
336 _Empty_byte _M_empty;
337 _Stored_type _M_payload;
339 bool _M_engaged =
false;
344 template<
typename _Tp>
357 template<
typename... _Args>
359 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(
true) { }
361 template<
typename _Up,
typename... _Args,
369 : _M_payload(__il, std::forward<_Args>(__args)...),
374 if (__other._M_engaged)
375 this->_M_construct(__other._M_get());
381 if (__other._M_engaged)
382 this->_M_construct(std::move(__other._M_get()));
388 if (this->_M_engaged && __other._M_engaged)
389 this->_M_get() = __other._M_get();
392 if (__other._M_engaged)
393 this->_M_construct(__other._M_get());
405 if (this->_M_engaged && __other._M_engaged)
406 this->_M_get() = std::move(__other._M_get());
409 if (__other._M_engaged)
410 this->_M_construct(std::move(__other._M_get()));
421 constexpr
bool _M_is_engaged()
const noexcept
422 {
return this->_M_engaged; }
426 {
return _M_payload; }
429 _M_get()
const noexcept
430 {
return _M_payload; }
432 template<
typename... _Args>
434 _M_construct(_Args&&... __args)
438 _Stored_type(std::forward<_Args>(__args)...);
439 this->_M_engaged =
true;
445 this->_M_engaged =
false;
446 this->_M_payload.~_Stored_type();
452 if (this->_M_engaged)
457 struct _Empty_byte { };
460 _Empty_byte _M_empty;
461 _Stored_type _M_payload;
463 bool _M_engaged =
false;
466 template<
typename _Tp>
469 template<
typename _Tp,
typename _Up>
470 using __converts_from_optional =
471 __or_<is_constructible<_Tp, const optional<_Up>&>,
480 template<
typename _Tp,
typename _Up>
481 using __assigns_from_optional =
482 __or_<is_assignable<_Tp&, const optional<_Up>&>,
490 template<
typename _Tp>
495 is_copy_constructible<_Tp>::value,
497 __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
499 is_move_constructible<_Tp>::value,
501 __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
508 "Invalid instantiation of optional<T>");
514 using value_type = _Tp;
521 template <
typename _Up = _Tp,
526 >::value,
bool> =
true>
530 template <
typename _Up = _Tp,
534 __not_<is_convertible<_Up&&, _Tp>>
535 >::value,
bool> =
false>
536 explicit constexpr optional(_Up&& __t)
539 template <
typename _Up,
541 __not_<is_same<_Tp, _Up>>,
544 __not_<__converts_from_optional<_Tp, _Up>>
545 >::value,
bool> =
true>
546 constexpr optional(
const optional<_Up>& __t)
552 template <
typename _Up,
554 __not_<is_same<_Tp, _Up>>,
555 is_constructible<_Tp, const _Up&>,
556 __not_<is_convertible<const _Up&, _Tp>>,
557 __not_<__converts_from_optional<_Tp, _Up>>
558 >::value,
bool> =
false>
559 explicit constexpr optional(
const optional<_Up>& __t)
565 template <
typename _Up,
567 __not_<is_same<_Tp, _Up>>,
568 is_constructible<_Tp, _Up&&>,
569 is_convertible<_Up&&, _Tp>,
570 __not_<__converts_from_optional<_Tp, _Up>>
571 >::value,
bool> =
true>
572 constexpr optional(optional<_Up>&& __t)
575 emplace(std::move(*__t));
578 template <
typename _Up,
580 __not_<is_same<_Tp, _Up>>,
581 is_constructible<_Tp, _Up&&>,
582 __not_<is_convertible<_Up&&, _Tp>>,
583 __not_<__converts_from_optional<_Tp, _Up>>
584 >::value,
bool> =
false>
585 explicit constexpr optional(optional<_Up>&& __t)
588 emplace(std::move(*__t));
593 operator=(nullopt_t) noexcept
599 template<
typename _Up = _Tp>
601 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
602 is_constructible<_Tp, _Up>,
603 __not_<__and_<is_scalar<_Tp>,
604 is_same<_Tp, decay_t<_Up>>>>,
605 is_assignable<_Tp&, _Up>>::value,
609 if (this->_M_is_engaged())
610 this->_M_get() = std::forward<_Up>(__u);
612 this->_M_construct(std::forward<_Up>(__u));
617 template<
typename _Up>
619 __not_<is_same<_Tp, _Up>>,
620 is_constructible<_Tp, const _Up&>,
621 is_assignable<_Tp&, _Up>,
622 __not_<__converts_from_optional<_Tp, _Up>>,
623 __not_<__assigns_from_optional<_Tp, _Up>>
626 operator=(
const optional<_Up>& __u)
630 if (this->_M_is_engaged())
631 this->_M_get() = *__u;
633 this->_M_construct(*__u);
642 template<
typename _Up>
644 __not_<is_same<_Tp, _Up>>,
645 is_constructible<_Tp, _Up>,
646 is_assignable<_Tp&, _Up>,
647 __not_<__converts_from_optional<_Tp, _Up>>,
648 __not_<__assigns_from_optional<_Tp, _Up>>
651 operator=(optional<_Up>&& __u)
655 if (this->_M_is_engaged())
656 this->_M_get() = std::move(*__u);
658 this->_M_construct(std::move(*__u));
668 template<
typename... _Args>
669 enable_if_t<is_constructible<_Tp, _Args&&...>::value>
670 emplace(_Args&&... __args)
673 this->_M_construct(std::forward<_Args>(__args)...);
676 template<
typename _Up,
typename... _Args>
677 enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
679 emplace(initializer_list<_Up> __il, _Args&&... __args)
682 this->_M_construct(__il, std::forward<_Args>(__args)...);
689 swap(optional& __other)
690 noexcept(is_nothrow_move_constructible<_Tp>()
691 && __is_nothrow_swappable<_Tp>::value)
695 if (this->_M_is_engaged() && __other._M_is_engaged())
696 swap(this->_M_get(), __other._M_get());
697 else if (this->_M_is_engaged())
699 __other._M_construct(std::move(this->_M_get()));
702 else if (__other._M_is_engaged())
704 this->_M_construct(std::move(__other._M_get()));
705 __other._M_destruct();
713 #ifndef __cpp_lib_addressof_constexpr 726 {
return this->_M_get(); }
730 {
return this->_M_get(); }
734 {
return std::move(this->_M_get()); }
736 constexpr
const _Tp&&
738 {
return std::move(this->_M_get()); }
740 constexpr
explicit operator bool() const noexcept
741 {
return this->_M_is_engaged(); }
746 return this->_M_is_engaged()
748 : (__throw_bad_optional_access(
"Attempt to access value of a " 749 "disengaged optional object"),
756 return this->_M_is_engaged()
758 : (__throw_bad_optional_access(
"Attempt to access value of a " 759 "disengaged optional object"),
766 return this->_M_is_engaged()
767 ? std::move(this->_M_get())
768 : (__throw_bad_optional_access(
"Attempt to access value of a " 769 "disengaged optional object"),
770 std::move(this->_M_get()));
773 constexpr
const _Tp&&
776 return this->_M_is_engaged()
777 ? std::move(this->_M_get())
778 : (__throw_bad_optional_access(
"Attempt to access value of a " 779 "disengaged optional object"),
780 std::move(this->_M_get()));
783 template<
typename _Up>
785 value_or(_Up&& __u)
const&
787 static_assert(__and_<is_copy_constructible<_Tp>,
788 is_convertible<_Up&&, _Tp>>(),
789 "Cannot return value");
791 return this->_M_is_engaged()
796 template<
typename _Up>
798 value_or(_Up&& __u) &&
800 static_assert(__and_<is_move_constructible<_Tp>,
801 is_convertible<_Up&&, _Tp>>(),
802 "Cannot return value" );
804 return this->_M_is_engaged()
805 ? std::move(this->_M_get())
811 template<
typename _Tp>
813 operator==(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
815 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
816 && (!__lhs || *__lhs == *__rhs);
819 template<
typename _Tp>
821 operator!=(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
822 {
return !(__lhs == __rhs); }
824 template<
typename _Tp>
826 operator<(const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
828 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
831 template<
typename _Tp>
833 operator>(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
834 {
return __rhs < __lhs; }
836 template<
typename _Tp>
838 operator<=(const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
839 {
return !(__rhs < __lhs); }
841 template<
typename _Tp>
843 operator>=(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
844 {
return !(__lhs < __rhs); }
847 template<
typename _Tp>
849 operator==(
const optional<_Tp>& __lhs, nullopt_t) noexcept
852 template<
typename _Tp>
854 operator==(nullopt_t,
const optional<_Tp>& __rhs) noexcept
857 template<
typename _Tp>
859 operator!=(
const optional<_Tp>& __lhs, nullopt_t) noexcept
860 {
return static_cast<bool>(__lhs); }
862 template<
typename _Tp>
864 operator!=(nullopt_t,
const optional<_Tp>& __rhs) noexcept
865 {
return static_cast<bool>(__rhs); }
867 template<
typename _Tp>
869 operator<(const optional<_Tp>& , nullopt_t) noexcept
872 template<
typename _Tp>
874 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
875 {
return static_cast<bool>(__rhs); }
877 template<
typename _Tp>
879 operator>(
const optional<_Tp>& __lhs, nullopt_t) noexcept
880 {
return static_cast<bool>(__lhs); }
882 template<
typename _Tp>
884 operator>(nullopt_t,
const optional<_Tp>& ) noexcept
887 template<
typename _Tp>
889 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
892 template<
typename _Tp>
894 operator<=(nullopt_t, const optional<_Tp>& ) noexcept
897 template<
typename _Tp>
899 operator>=(
const optional<_Tp>& , nullopt_t) noexcept
902 template<
typename _Tp>
904 operator>=(nullopt_t,
const optional<_Tp>& __rhs) noexcept
908 template<
typename _Tp>
910 operator==(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
911 {
return __lhs && *__lhs == __rhs; }
913 template<
typename _Tp>
915 operator==(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
916 {
return __rhs && __lhs == *__rhs; }
918 template<
typename _Tp>
920 operator!=(
const optional<_Tp>& __lhs, _Tp
const& __rhs)
921 {
return !__lhs || !(*__lhs == __rhs); }
923 template<
typename _Tp>
925 operator!=(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
926 {
return !__rhs || !(__lhs == *__rhs); }
928 template<
typename _Tp>
930 operator<(const optional<_Tp>& __lhs,
const _Tp& __rhs)
931 {
return !__lhs || *__lhs < __rhs; }
933 template<
typename _Tp>
935 operator<(const _Tp& __lhs, const optional<_Tp>& __rhs)
936 {
return __rhs && __lhs < *__rhs; }
938 template<
typename _Tp>
940 operator>(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
941 {
return __lhs && __rhs < *__lhs; }
943 template<
typename _Tp>
945 operator>(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
946 {
return !__rhs || *__rhs < __lhs; }
948 template<
typename _Tp>
950 operator<=(const optional<_Tp>& __lhs,
const _Tp& __rhs)
951 {
return !__lhs || !(__rhs < *__lhs); }
953 template<
typename _Tp>
955 operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs)
956 {
return __rhs && !(*__rhs < __lhs); }
958 template<
typename _Tp>
960 operator>=(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
961 {
return __lhs && !(*__lhs < __rhs); }
963 template<
typename _Tp>
965 operator>=(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
966 {
return !__rhs || !(__lhs < *__rhs); }
969 template<
typename _Tp>
971 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
972 noexcept(noexcept(__lhs.swap(__rhs)))
973 { __lhs.swap(__rhs); }
975 template<
typename _Tp>
976 constexpr optional<decay_t<_Tp>>
977 make_optional(_Tp&& __t)
978 {
return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
985 template<
typename _Tp>
986 struct hash<experimental::optional<_Tp>>
988 using result_type = size_t;
989 using argument_type = experimental::optional<_Tp>;
992 operator()(
const experimental::optional<_Tp>& __t)
const 993 noexcept(noexcept(hash<_Tp> {}(*__t)))
997 constexpr
size_t __magic_disengaged_hash =
static_cast<size_t>(-3333);
998 return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash;
1002 _GLIBCXX_END_NAMESPACE_VERSION
1007 #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL logic_error(const string &__arg) _GLIBCXX_TXN_SAFE
Exception class thrown when a disengaged optional object is dereferenced.
ISO C++ entities toplevel namespace is std.
is_nothrow_move_constructible
One of two subclasses of exception.
constexpr nullopt_t nullopt
Tag to disengage optional objects.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
constexpr enable_if_t<!_Has_addressof< _Tp >::value, _Tp * > __constexpr_addressof(_Tp &__t)
An overload that attempts to take the address of an lvalue as a constant expression. Falls back to __addressof in the presence of an overloaded addressof operator (unary operator&), in which case the call will not be a constant expression.
is_nothrow_move_assignable
typename remove_cv< _Tp >::type remove_cv_t
Alias template for remove_cv.
is_trivially_destructible
A mixin helper to conditionally enable or disable the copy/move special members.
Class template for optional values.
Class template that holds the necessary state for Optional values and that has the responsibility for...
Trait that detects the presence of an overloaded unary operator&.
constexpr in_place_t in_place
Tag for in-place construction.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Tag type to disengage optional objects.
typename decay< _Tp >::type decay_t
Alias template for decay.
typename remove_const< _Tp >::type remove_const_t
Alias template for remove_const.
Tag type for in-place construction.