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,
231 initializer_list<_Up> __il,
233 : _M_payload(__il, std::forward<_Args>(__args)...),
237 _Optional_base(
const _Optional_base& __other)
239 if (__other._M_engaged)
240 this->_M_construct(__other._M_get());
243 _Optional_base(_Optional_base&& __other)
246 if (__other._M_engaged)
247 this->_M_construct(std::move(__other._M_get()));
252 operator=(
const _Optional_base& __other)
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());
268 operator=(_Optional_base&& __other)
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,
367 initializer_list<_Up> __il,
369 : _M_payload(__il, std::forward<_Args>(__args)...),
372 _Optional_base(
const _Optional_base& __other)
374 if (__other._M_engaged)
375 this->_M_construct(__other._M_get());
378 _Optional_base(_Optional_base&& __other)
381 if (__other._M_engaged)
382 this->_M_construct(std::move(__other._M_get()));
386 operator=(
const _Optional_base& __other)
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());
401 operator=(_Optional_base&& __other)
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>&>,
474 is_constructible<_Tp, optional<_Up>&&>,
477 is_convertible<const optional<_Up>&&, _Tp>,
478 is_convertible<optional<_Up>&&, _Tp>>;
480 template<
typename _Tp,
typename _Up>
481 using __assigns_from_optional =
482 __or_<is_assignable<_Tp&, const optional<_Up>&>,
485 is_assignable<_Tp&, 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>
528 : _Base(
in_place, std::forward<_Up>(__t)) { }
530 template <
typename _Up = _Tp,
532 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
533 is_constructible<_Tp, _Up&&>,
534 __not_<is_convertible<_Up&&, _Tp>>
535 >::value,
bool> =
false>
536 explicit constexpr optional(_Up&& __t)
537 : _Base(
in_place, std::forward<_Up>(__t)) { }
539 template <
typename _Up,
541 __not_<is_same<_Tp, _Up>>,
544 __not_<__converts_from_optional<_Tp, _Up>>
545 >::value,
bool> =
true>
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>
565 template <
typename _Up,
567 __not_<is_same<_Tp, _Up>>,
568 is_constructible<_Tp, _Up&&>,
570 __not_<__converts_from_optional<_Tp, _Up>>
571 >::value,
bool> =
true>
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>
588 emplace(std::move(*__t));
599 template<
typename _Up = _Tp>
601 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
603 __not_<__and_<is_scalar<_Tp>,
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&>,
622 __not_<__converts_from_optional<_Tp, _Up>>,
623 __not_<__assigns_from_optional<_Tp, _Up>>
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>>
655 if (this->_M_is_engaged())
656 this->_M_get() = std::move(*__u);
658 this->_M_construct(std::move(*__u));
668 template<
typename... _Args>
670 emplace(_Args&&... __args)
673 this->_M_construct(std::forward<_Args>(__args)...);
676 template<
typename _Up,
typename... _Args>
682 this->_M_construct(__il, std::forward<_Args>(__args)...);
689 swap(optional& __other)
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&
788 is_convertible<_Up&&, _Tp>>(),
789 "Cannot return value");
791 return this->_M_is_engaged()
793 :
static_cast<_Tp
>(std::forward<_Up>(__u));
796 template<
typename _Up>
798 value_or(_Up&& __u) &&
801 is_convertible<_Up&&, _Tp>>(),
802 "Cannot return value" );
804 return this->_M_is_engaged()
805 ? std::move(this->_M_get())
806 :
static_cast<_Tp
>(std::forward<_Up>(__u));
811 template<
typename _Tp>
815 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
816 && (!__lhs || *__lhs == *__rhs);
819 template<
typename _Tp>
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>
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>
844 {
return !(__lhs < __rhs); }
847 template<
typename _Tp>
852 template<
typename _Tp>
857 template<
typename _Tp>
860 {
return static_cast<bool>(__lhs); }
862 template<
typename _Tp>
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>
880 {
return static_cast<bool>(__lhs); }
882 template<
typename _Tp>
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>
902 template<
typename _Tp>
908 template<
typename _Tp>
911 {
return __lhs && *__lhs == __rhs; }
913 template<
typename _Tp>
916 {
return __rhs && __lhs == *__rhs; }
918 template<
typename _Tp>
921 {
return !__lhs || !(*__lhs == __rhs); }
923 template<
typename _Tp>
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>
941 {
return __lhs && __rhs < *__lhs; }
943 template<
typename _Tp>
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>
961 {
return __lhs && !(*__lhs < __rhs); }
963 template<
typename _Tp>
966 {
return !__rhs || !(__lhs < *__rhs); }
969 template<
typename _Tp>
972 noexcept(noexcept(__lhs.swap(__rhs)))
973 { __lhs.swap(__rhs); }
975 template<
typename _Tp>
977 make_optional(_Tp&& __t)
985 template<
typename _Tp>
988 using result_type = size_t;
989 using argument_type = experimental::optional<_Tp>;
992 operator()(
const experimental::optional<_Tp>& __t)
const 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 _GLIBCXX20_CONSTEXPR complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
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 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.
Primary class template hash.
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.