29 #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL 30 #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1 44 #if __cplusplus <= 201103L 58 namespace std _GLIBCXX_VISIBILITY(default)
60 namespace experimental
62 inline namespace fundamentals_v1
64 _GLIBCXX_BEGIN_NAMESPACE_VERSION
77 #define __cpp_lib_experimental_optional 201411 82 template<
typename _Tp>
101 enum class _Construct { _Token };
104 explicit constexpr
nullopt_t(_Construct) { }
129 __throw_bad_optional_access(
const char*)
130 __attribute__((__noreturn__));
134 __throw_bad_optional_access(
const char* __s)
137 template<
typename _Tp,
typename =
void>
140 template<
typename _Tp>
141 struct _Has_addressof_mem<_Tp,
142 __void_t<decltype( std::declval<const _Tp&>().operator&() )>
146 template<
typename _Tp,
typename =
void>
149 template<
typename _Tp>
150 struct _Has_addressof_free<_Tp,
151 __void_t<decltype( operator&(std::declval<const _Tp&>()) )>
162 template<
typename _Tp>
164 : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type
173 template<typename _Tp, enable_if_t<!_Has_addressof<_Tp>::value,
int>...>
180 template<typename _Tp, enable_if_t<_Has_addressof<_Tp>::value,
int>...>
196 template<
typename _Tp,
bool _ShouldProvideDestructor =
197 !is_trivially_destructible<_Tp>::value>
204 using _Stored_type = remove_const_t<_Tp>;
217 template<
typename... _Args>
219 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(
true) { }
221 template<
typename _Up,
typename... _Args,
222 enable_if_t<is_constructible<_Tp,
227 initializer_list<_Up> __il,
229 : _M_payload(__il, std::forward<_Args>(__args)...),
233 _Optional_base(
const _Optional_base& __other)
235 if (__other._M_engaged)
236 this->_M_construct(__other._M_get());
239 _Optional_base(_Optional_base&& __other)
240 noexcept(is_nothrow_move_constructible<_Tp>())
242 if (__other._M_engaged)
243 this->_M_construct(std::move(__other._M_get()));
248 operator=(
const _Optional_base& __other)
250 if (this->_M_engaged && __other._M_engaged)
251 this->_M_get() = __other._M_get();
254 if (__other._M_engaged)
255 this->_M_construct(__other._M_get());
264 operator=(_Optional_base&& __other)
265 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
266 is_nothrow_move_assignable<_Tp>>())
268 if (this->_M_engaged && __other._M_engaged)
269 this->_M_get() = std::move(__other._M_get());
272 if (__other._M_engaged)
273 this->_M_construct(std::move(__other._M_get()));
283 if (this->_M_engaged)
284 this->_M_payload.~_Stored_type();
290 constexpr
bool _M_is_engaged()
const noexcept
291 {
return this->_M_engaged; }
296 {
return _M_payload; }
299 _M_get()
const noexcept
300 {
return _M_payload; }
304 template<
typename... _Args>
306 _M_construct(_Args&&... __args)
307 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
310 _Stored_type(std::forward<_Args>(__args)...);
311 this->_M_engaged =
true;
317 this->_M_engaged =
false;
318 this->_M_payload.~_Stored_type();
325 if (this->_M_engaged)
330 struct _Empty_byte { };
332 _Empty_byte _M_empty;
333 _Stored_type _M_payload;
335 bool _M_engaged =
false;
340 template<
typename _Tp>
344 using _Stored_type = remove_const_t<_Tp>;
353 template<
typename... _Args>
355 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(
true) { }
357 template<
typename _Up,
typename... _Args,
358 enable_if_t<is_constructible<_Tp,
363 initializer_list<_Up> __il,
365 : _M_payload(__il, std::forward<_Args>(__args)...),
368 _Optional_base(
const _Optional_base& __other)
370 if (__other._M_engaged)
371 this->_M_construct(__other._M_get());
374 _Optional_base(_Optional_base&& __other)
375 noexcept(is_nothrow_move_constructible<_Tp>())
377 if (__other._M_engaged)
378 this->_M_construct(std::move(__other._M_get()));
382 operator=(
const _Optional_base& __other)
384 if (this->_M_engaged && __other._M_engaged)
385 this->_M_get() = __other._M_get();
388 if (__other._M_engaged)
389 this->_M_construct(__other._M_get());
397 operator=(_Optional_base&& __other)
398 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
399 is_nothrow_move_assignable<_Tp>>())
401 if (this->_M_engaged && __other._M_engaged)
402 this->_M_get() = std::move(__other._M_get());
405 if (__other._M_engaged)
406 this->_M_construct(std::move(__other._M_get()));
417 constexpr
bool _M_is_engaged()
const noexcept
418 {
return this->_M_engaged; }
422 {
return _M_payload; }
425 _M_get()
const noexcept
426 {
return _M_payload; }
428 template<
typename... _Args>
430 _M_construct(_Args&&... __args)
431 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
434 _Stored_type(std::forward<_Args>(__args)...);
435 this->_M_engaged =
true;
441 this->_M_engaged =
false;
442 this->_M_payload.~_Stored_type();
448 if (this->_M_engaged)
453 struct _Empty_byte { };
456 _Empty_byte _M_empty;
457 _Stored_type _M_payload;
459 bool _M_engaged =
false;
462 template<
typename _Tp>
465 template<
typename _Tp,
typename _Up>
466 using __converts_from_optional =
467 __or_<is_constructible<_Tp, const optional<_Up>&>,
468 is_constructible<_Tp, optional<_Up>&>,
469 is_constructible<_Tp, const optional<_Up>&&>,
470 is_constructible<_Tp, optional<_Up>&&>,
471 is_convertible<const optional<_Up>&, _Tp>,
472 is_convertible<optional<_Up>&, _Tp>,
473 is_convertible<const optional<_Up>&&, _Tp>,
474 is_convertible<optional<_Up>&&, _Tp>>;
476 template<
typename _Tp,
typename _Up>
477 using __assigns_from_optional =
478 __or_<is_assignable<_Tp&, const optional<_Up>&>,
479 is_assignable<_Tp&, optional<_Up>&>,
480 is_assignable<_Tp&, const optional<_Up>&&>,
481 is_assignable<_Tp&, optional<_Up>&&>>;
486 template<
typename _Tp>
491 is_copy_constructible<_Tp>::value,
493 __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
495 is_move_constructible<_Tp>::value,
497 __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
501 static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>,
nullopt_t>>,
502 __not_<is_same<remove_cv_t<_Tp>,
in_place_t>>,
504 "Invalid instantiation of optional<T>");
510 using value_type = _Tp;
517 template <
typename _Up = _Tp,
519 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
520 is_constructible<_Tp, _Up&&>,
521 is_convertible<_Up&&, _Tp>
522 >::value,
bool> =
true>
524 : _Base(
in_place, std::forward<_Up>(__t)) { }
526 template <
typename _Up = _Tp,
528 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
529 is_constructible<_Tp, _Up&&>,
530 __not_<is_convertible<_Up&&, _Tp>>
531 >::value,
bool> =
false>
532 explicit constexpr optional(_Up&& __t)
533 : _Base(
in_place, std::forward<_Up>(__t)) { }
535 template <
typename _Up,
537 __not_<is_same<_Tp, _Up>>,
538 is_constructible<_Tp, const _Up&>,
539 is_convertible<const _Up&, _Tp>,
540 __not_<__converts_from_optional<_Tp, _Up>>
541 >::value,
bool> =
true>
548 template <
typename _Up,
550 __not_<is_same<_Tp, _Up>>,
551 is_constructible<_Tp, const _Up&>,
552 __not_<is_convertible<const _Up&, _Tp>>,
553 __not_<__converts_from_optional<_Tp, _Up>>
554 >::value,
bool> =
false>
561 template <
typename _Up,
563 __not_<is_same<_Tp, _Up>>,
564 is_constructible<_Tp, _Up&&>,
565 is_convertible<_Up&&, _Tp>,
566 __not_<__converts_from_optional<_Tp, _Up>>
567 >::value,
bool> =
true>
571 emplace(std::move(*__t));
574 template <
typename _Up,
576 __not_<is_same<_Tp, _Up>>,
577 is_constructible<_Tp, _Up&&>,
578 __not_<is_convertible<_Up&&, _Tp>>,
579 __not_<__converts_from_optional<_Tp, _Up>>
580 >::value,
bool> =
false>
584 emplace(std::move(*__t));
595 template<
typename _Up = _Tp>
597 __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
598 is_constructible<_Tp, _Up>,
599 __not_<__and_<is_scalar<_Tp>,
600 is_same<_Tp, decay_t<_Up>>>>,
601 is_assignable<_Tp&, _Up>>::value,
605 if (this->_M_is_engaged())
606 this->_M_get() = std::forward<_Up>(__u);
608 this->_M_construct(std::forward<_Up>(__u));
613 template<
typename _Up>
615 __not_<is_same<_Tp, _Up>>,
616 is_constructible<_Tp, const _Up&>,
617 is_assignable<_Tp&, _Up>,
618 __not_<__converts_from_optional<_Tp, _Up>>,
619 __not_<__assigns_from_optional<_Tp, _Up>>
626 if (this->_M_is_engaged())
627 this->_M_get() = *__u;
629 this->_M_construct(*__u);
638 template<
typename _Up>
640 __not_<is_same<_Tp, _Up>>,
641 is_constructible<_Tp, _Up>,
642 is_assignable<_Tp&, _Up>,
643 __not_<__converts_from_optional<_Tp, _Up>>,
644 __not_<__assigns_from_optional<_Tp, _Up>>
651 if (this->_M_is_engaged())
652 this->_M_get() = std::move(*__u);
654 this->_M_construct(std::move(*__u));
664 template<
typename... _Args>
665 enable_if_t<is_constructible<_Tp, _Args&&...>::value>
666 emplace(_Args&&... __args)
669 this->_M_construct(std::forward<_Args>(__args)...);
672 template<
typename _Up,
typename... _Args>
673 enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
678 this->_M_construct(__il, std::forward<_Args>(__args)...);
685 swap(optional& __other)
686 noexcept(is_nothrow_move_constructible<_Tp>()
687 && noexcept(swap(declval<_Tp&>(), declval<_Tp&>())))
691 if (this->_M_is_engaged() && __other._M_is_engaged())
692 swap(this->_M_get(), __other._M_get());
693 else if (this->_M_is_engaged())
695 __other._M_construct(std::move(this->_M_get()));
698 else if (__other._M_is_engaged())
700 this->_M_construct(std::move(__other._M_get()));
701 __other._M_destruct();
716 {
return this->_M_get(); }
720 {
return this->_M_get(); }
724 {
return std::move(this->_M_get()); }
726 constexpr
const _Tp&&
728 {
return std::move(this->_M_get()); }
730 constexpr
explicit operator bool()
const noexcept
731 {
return this->_M_is_engaged(); }
736 return this->_M_is_engaged()
738 : (__throw_bad_optional_access(
"Attempt to access value of a " 739 "disengaged optional object"),
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()
757 ? std::move(this->_M_get())
758 : (__throw_bad_optional_access(
"Attempt to access value of a " 759 "disengaged optional object"),
760 std::move(this->_M_get()));
763 constexpr
const _Tp&&
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 template<
typename _Up>
775 value_or(_Up&& __u)
const&
777 static_assert(__and_<is_copy_constructible<_Tp>,
778 is_convertible<_Up&&, _Tp>>(),
779 "Cannot return value");
781 return this->_M_is_engaged()
783 :
static_cast<_Tp
>(std::forward<_Up>(__u));
786 template<
typename _Up>
788 value_or(_Up&& __u) &&
790 static_assert(__and_<is_move_constructible<_Tp>,
791 is_convertible<_Up&&, _Tp>>(),
792 "Cannot return value" );
794 return this->_M_is_engaged()
795 ? std::move(this->_M_get())
796 :
static_cast<_Tp
>(std::forward<_Up>(__u));
801 template<
typename _Tp>
805 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
806 && (!__lhs || *__lhs == *__rhs);
809 template<
typename _Tp>
812 {
return !(__lhs == __rhs); }
814 template<
typename _Tp>
816 operator<(const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
818 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
821 template<
typename _Tp>
824 {
return __rhs < __lhs; }
826 template<
typename _Tp>
828 operator<=(const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
829 {
return !(__rhs < __lhs); }
831 template<
typename _Tp>
834 {
return !(__lhs < __rhs); }
837 template<
typename _Tp>
842 template<
typename _Tp>
847 template<
typename _Tp>
850 {
return static_cast<bool>(__lhs); }
852 template<
typename _Tp>
855 {
return static_cast<bool>(__rhs); }
857 template<
typename _Tp>
859 operator<(const optional<_Tp>& ,
nullopt_t) noexcept
862 template<
typename _Tp>
864 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
865 {
return static_cast<bool>(__rhs); }
867 template<
typename _Tp>
870 {
return static_cast<bool>(__lhs); }
872 template<
typename _Tp>
877 template<
typename _Tp>
879 operator<=(const optional<_Tp>& __lhs,
nullopt_t) noexcept
882 template<
typename _Tp>
884 operator<=(nullopt_t, const optional<_Tp>& ) noexcept
887 template<
typename _Tp>
892 template<
typename _Tp>
898 template<
typename _Tp>
901 {
return __lhs && *__lhs == __rhs; }
903 template<
typename _Tp>
906 {
return __rhs && __lhs == *__rhs; }
908 template<
typename _Tp>
911 {
return !__lhs || !(*__lhs == __rhs); }
913 template<
typename _Tp>
916 {
return !__rhs || !(__lhs == *__rhs); }
918 template<
typename _Tp>
920 operator<(const optional<_Tp>& __lhs,
const _Tp& __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>
931 {
return __lhs && __rhs < *__lhs; }
933 template<
typename _Tp>
936 {
return !__rhs || *__rhs < __lhs; }
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>
951 {
return __lhs && !(*__lhs < __rhs); }
953 template<
typename _Tp>
956 {
return !__rhs || !(__lhs < *__rhs); }
959 template<
typename _Tp>
962 noexcept(noexcept(__lhs.swap(__rhs)))
963 { __lhs.swap(__rhs); }
965 template<
typename _Tp>
967 make_optional(_Tp&& __t)
971 _GLIBCXX_END_NAMESPACE_VERSION
976 template<
typename _Tp>
979 using result_type = size_t;
980 using argument_type = experimental::optional<_Tp>;
983 operator()(
const experimental::optional<_Tp>& __t)
const 988 constexpr
size_t __magic_disengaged_hash =
static_cast<size_t>(-3333);
989 return __t ?
hash<_Tp> {}(*__t) : __magic_disengaged_hash;
996 #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL Primary class template hash.
A mixin helper to conditionally enable or disable the copy/move special members.
constexpr in_place_t in_place
Tag for in-place construction.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
ISO C++ entities toplevel namespace is std.
One of two subclasses of exception.
Tag type to disengage optional objects.
complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Class template that holds the necessary state for Optional values and that has the responsibility for...
Tag type for in-place construction.
Exception class thrown when a disengaged optional object is dereferenced.
Class template for optional values.
constexpr nullopt_t nullopt
Tag to disengage optional objects.
constexpr _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.
Trait that detects the presence of an overloaded unary operator&.