30#ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL
31#define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1
35#if __cplusplus >= 201402L
47namespace std _GLIBCXX_VISIBILITY(default)
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
53inline namespace fundamentals_v1
66#define __cpp_lib_experimental_optional 201411
71 template<
typename _Tp>
90 enum class _Construct { _Token };
93 explicit constexpr nullopt_t(_Construct) { }
120 [[noreturn]]
inline void
121 __throw_bad_optional_access(
const char* __s)
136 template<
typename _Tp,
bool _ShouldProvideDestructor =
144 using _Stored_type = remove_const_t<_Tp>;
150 constexpr _Optional_base() noexcept
153 constexpr _Optional_base(nullopt_t) noexcept
154 : _Optional_base{} { }
157 template<
typename... _Args>
158 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
159 : _M_payload(
std::
forward<_Args>(__args)...), _M_engaged(true) { }
161 template<
typename _Up,
typename... _Args,
163 initializer_list<_Up>&,
166 constexpr explicit _Optional_base(in_place_t,
167 initializer_list<_Up> __il,
169 : _M_payload(__il,
std::
forward<_Args>(__args)...),
173 _Optional_base(
const _Optional_base& __other)
175 if (__other._M_engaged)
176 this->_M_construct(__other._M_get());
179 _Optional_base(_Optional_base&& __other)
180 noexcept(is_nothrow_move_constructible<_Tp>())
182 if (__other._M_engaged)
183 this->_M_construct(
std::move(__other._M_get()));
188 operator=(
const _Optional_base& __other)
190 if (this->_M_engaged && __other._M_engaged)
191 this->_M_get() = __other._M_get();
194 if (__other._M_engaged)
195 this->_M_construct(__other._M_get());
204 operator=(_Optional_base&& __other)
205 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
206 is_nothrow_move_assignable<_Tp>>())
208 if (this->_M_engaged && __other._M_engaged)
209 this->_M_get() =
std::move(__other._M_get());
212 if (__other._M_engaged)
213 this->_M_construct(
std::move(__other._M_get()));
223 if (this->_M_engaged)
224 this->_M_payload.~_Stored_type();
230 constexpr bool _M_is_engaged() const noexcept
231 {
return this->_M_engaged; }
236 {
return _M_payload; }
239 _M_get() const noexcept
240 {
return _M_payload; }
244 template<
typename... _Args>
246 _M_construct(_Args&&... __args)
247 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
250 _Stored_type(std::forward<_Args>(__args)...);
251 this->_M_engaged =
true;
257 this->_M_engaged =
false;
258 this->_M_payload.~_Stored_type();
265 if (this->_M_engaged)
270 struct _Empty_byte { };
272 _Empty_byte _M_empty;
273 _Stored_type _M_payload;
275 bool _M_engaged =
false;
280 template<
typename _Tp>
281 class _Optional_base<_Tp, false>
284 using _Stored_type = remove_const_t<_Tp>;
287 constexpr _Optional_base() noexcept
290 constexpr _Optional_base(nullopt_t) noexcept
291 : _Optional_base{} { }
293 template<
typename... _Args>
294 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
295 : _M_payload(
std::
forward<_Args>(__args)...), _M_engaged(true) { }
297 template<
typename _Up,
typename... _Args,
299 initializer_list<_Up>&,
302 constexpr explicit _Optional_base(in_place_t,
303 initializer_list<_Up> __il,
305 : _M_payload(__il,
std::
forward<_Args>(__args)...),
308 _Optional_base(
const _Optional_base& __other)
310 if (__other._M_engaged)
311 this->_M_construct(__other._M_get());
314 _Optional_base(_Optional_base&& __other)
315 noexcept(is_nothrow_move_constructible<_Tp>())
317 if (__other._M_engaged)
318 this->_M_construct(
std::move(__other._M_get()));
322 operator=(
const _Optional_base& __other)
324 if (this->_M_engaged && __other._M_engaged)
325 this->_M_get() = __other._M_get();
328 if (__other._M_engaged)
329 this->_M_construct(__other._M_get());
337 operator=(_Optional_base&& __other)
338 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
339 is_nothrow_move_assignable<_Tp>>())
341 if (this->_M_engaged && __other._M_engaged)
342 this->_M_get() =
std::move(__other._M_get());
345 if (__other._M_engaged)
346 this->_M_construct(
std::move(__other._M_get()));
357 constexpr bool _M_is_engaged() const noexcept
358 {
return this->_M_engaged; }
362 {
return _M_payload; }
365 _M_get() const noexcept
366 {
return _M_payload; }
368 template<
typename... _Args>
370 _M_construct(_Args&&... __args)
371 noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
374 _Stored_type(std::forward<_Args>(__args)...);
375 this->_M_engaged =
true;
381 this->_M_engaged =
false;
382 this->_M_payload.~_Stored_type();
388 if (this->_M_engaged)
393 struct _Empty_byte { };
396 _Empty_byte _M_empty;
397 _Stored_type _M_payload;
399 bool _M_engaged =
false;
402 template<
typename _Tp,
typename _Up>
403 using __converts_from_optional =
404 __or_<is_constructible<_Tp, const optional<_Up>&>,
405 is_constructible<_Tp, optional<_Up>&>,
406 is_constructible<_Tp, const optional<_Up>&&>,
407 is_constructible<_Tp, optional<_Up>&&>,
408 is_convertible<const optional<_Up>&, _Tp>,
409 is_convertible<optional<_Up>&, _Tp>,
410 is_convertible<const optional<_Up>&&, _Tp>,
411 is_convertible<optional<_Up>&&, _Tp>>;
413 template<
typename _Tp,
typename _Up>
414 using __assigns_from_optional =
415 __or_<is_assignable<_Tp&, const optional<_Up>&>,
416 is_assignable<_Tp&, optional<_Up>&>,
417 is_assignable<_Tp&, const optional<_Up>&&>,
418 is_assignable<_Tp&, optional<_Up>&&>>;
425 template<
typename _Tp>
427 :
private _Optional_base<_Tp>,
428 private _Enable_copy_move<
430 is_copy_constructible<_Tp>::value,
432 __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
434 is_move_constructible<_Tp>::value,
436 __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
440 static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>,
nullopt_t>>,
441 __not_<is_same<remove_cv_t<_Tp>,
in_place_t>>,
442 __not_<is_reference<_Tp>>>(),
443 "Invalid instantiation of optional<T>");
446 using _Base = _Optional_base<_Tp>;
449 using value_type = _Tp;
456 template <
typename _Up = _Tp,
461 >::value,
bool> =
true>
463 : _Base(
in_place, std::forward<_Up>(__t)) { }
465 template <
typename _Up = _Tp,
469 __not_<is_convertible<_Up&&, _Tp>>
470 >::value,
bool> =
false>
471 explicit constexpr optional(_Up&& __t)
472 : _Base(
in_place, std::forward<_Up>(__t)) { }
474 template <
typename _Up,
476 __not_<is_same<_Tp, _Up>>,
479 __not_<__converts_from_optional<_Tp, _Up>>
480 >::value,
bool> =
true>
487 template <
typename _Up,
489 __not_<is_same<_Tp, _Up>>,
491 __not_<is_convertible<const _Up&, _Tp>>,
492 __not_<__converts_from_optional<_Tp, _Up>>
493 >::value,
bool> =
false>
500 template <
typename _Up,
502 __not_<is_same<_Tp, _Up>>,
505 __not_<__converts_from_optional<_Tp, _Up>>
506 >::value,
bool> =
true>
513 template <
typename _Up,
515 __not_<is_same<_Tp, _Up>>,
517 __not_<is_convertible<_Up&&, _Tp>>,
518 __not_<__converts_from_optional<_Tp, _Up>>
519 >::value,
bool> =
false>
534 template<
typename _Up = _Tp>
538 __not_<__and_<is_scalar<_Tp>,
544 if (this->_M_is_engaged())
545 this->_M_get() = std::forward<_Up>(__u);
547 this->_M_construct(std::forward<_Up>(__u));
552 template<
typename _Up>
554 __not_<is_same<_Tp, _Up>>,
557 __not_<__converts_from_optional<_Tp, _Up>>,
558 __not_<__assigns_from_optional<_Tp, _Up>>
565 if (this->_M_is_engaged())
566 this->_M_get() = *__u;
568 this->_M_construct(*__u);
577 template<
typename _Up>
579 __not_<is_same<_Tp, _Up>>,
582 __not_<__converts_from_optional<_Tp, _Up>>,
583 __not_<__assigns_from_optional<_Tp, _Up>>
590 if (this->_M_is_engaged())
603 template<
typename... _Args>
605 emplace(_Args&&... __args)
608 this->_M_construct(std::forward<_Args>(__args)...);
611 template<
typename _Up,
typename... _Args>
617 this->_M_construct(__il, std::forward<_Args>(__args)...);
626 && __is_nothrow_swappable<_Tp>::value)
630 if (this->_M_is_engaged() && __other._M_is_engaged())
631 swap(this->_M_get(), __other._M_get());
632 else if (this->_M_is_engaged())
634 __other._M_construct(
std::move(this->_M_get()));
637 else if (__other._M_is_engaged())
639 this->_M_construct(
std::move(__other._M_get()));
640 __other._M_destruct();
655 {
return this->_M_get(); }
659 {
return this->_M_get(); }
665 constexpr const _Tp&&
669 constexpr explicit operator bool()
const noexcept
670 {
return this->_M_is_engaged(); }
675 if (this->_M_is_engaged())
676 return this->_M_get();
677 __throw_bad_optional_access(
"Attempt to access value of a "
678 "disengaged optional object");
684 if (this->_M_is_engaged())
685 return this->_M_get();
686 __throw_bad_optional_access(
"Attempt to access value of a "
687 "disengaged optional object");
693 if (this->_M_is_engaged())
695 __throw_bad_optional_access(
"Attempt to access value of a "
696 "disengaged optional object");
699 constexpr const _Tp&&
702 if (this->_M_is_engaged())
704 __throw_bad_optional_access(
"Attempt to access value of a "
705 "disengaged optional object");
708 template<
typename _Up>
710 value_or(_Up&& __u)
const&
712 static_assert(__and_<is_copy_constructible<_Tp>,
714 "Cannot return value");
716 if (this->_M_is_engaged())
717 return this->_M_get();
719 return static_cast<_Tp
>(std::forward<_Up>(__u));
722 template<
typename _Up>
724 value_or(_Up&& __u) &&
726 static_assert(__and_<is_move_constructible<_Tp>,
728 "Cannot return value" );
730 if (this->_M_is_engaged())
733 return static_cast<_Tp
>(std::forward<_Up>(__u));
740 template<
typename _Tp>
744 return static_cast<bool>(__lhs) ==
static_cast<bool>(__rhs)
745 && (!__lhs || *__lhs == *__rhs);
748 template<
typename _Tp>
751 {
return !(__lhs == __rhs); }
753 template<
typename _Tp>
755 operator<(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
757 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
760 template<
typename _Tp>
762 operator>(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
763 {
return __rhs < __lhs; }
765 template<
typename _Tp>
767 operator<=(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
768 {
return !(__rhs < __lhs); }
770 template<
typename _Tp>
772 operator>=(
const optional<_Tp>& __lhs,
const optional<_Tp>& __rhs)
773 {
return !(__lhs < __rhs); }
776 template<
typename _Tp>
778 operator==(
const optional<_Tp>& __lhs, nullopt_t)
noexcept
781 template<
typename _Tp>
783 operator==(nullopt_t,
const optional<_Tp>& __rhs)
noexcept
786 template<
typename _Tp>
788 operator!=(
const optional<_Tp>& __lhs, nullopt_t)
noexcept
789 {
return static_cast<bool>(__lhs); }
791 template<
typename _Tp>
793 operator!=(nullopt_t,
const optional<_Tp>& __rhs)
noexcept
794 {
return static_cast<bool>(__rhs); }
796 template<
typename _Tp>
798 operator<(
const optional<_Tp>& , nullopt_t)
noexcept
801 template<
typename _Tp>
803 operator<(nullopt_t,
const optional<_Tp>& __rhs)
noexcept
804 {
return static_cast<bool>(__rhs); }
806 template<
typename _Tp>
808 operator>(
const optional<_Tp>& __lhs, nullopt_t)
noexcept
809 {
return static_cast<bool>(__lhs); }
811 template<
typename _Tp>
813 operator>(nullopt_t,
const optional<_Tp>& )
noexcept
816 template<
typename _Tp>
818 operator<=(
const optional<_Tp>& __lhs, nullopt_t)
noexcept
821 template<
typename _Tp>
823 operator<=(nullopt_t,
const optional<_Tp>& )
noexcept
826 template<
typename _Tp>
828 operator>=(
const optional<_Tp>& , nullopt_t)
noexcept
831 template<
typename _Tp>
833 operator>=(nullopt_t,
const optional<_Tp>& __rhs)
noexcept
837 template<
typename _Tp>
839 operator==(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
840 {
return __lhs && *__lhs == __rhs; }
842 template<
typename _Tp>
844 operator==(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
845 {
return __rhs && __lhs == *__rhs; }
847 template<
typename _Tp>
849 operator!=(
const optional<_Tp>& __lhs, _Tp
const& __rhs)
850 {
return !__lhs || !(*__lhs == __rhs); }
852 template<
typename _Tp>
854 operator!=(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
855 {
return !__rhs || !(__lhs == *__rhs); }
857 template<
typename _Tp>
859 operator<(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
860 {
return !__lhs || *__lhs < __rhs; }
862 template<
typename _Tp>
864 operator<(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
865 {
return __rhs && __lhs < *__rhs; }
867 template<
typename _Tp>
869 operator>(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
870 {
return __lhs && __rhs < *__lhs; }
872 template<
typename _Tp>
874 operator>(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
875 {
return !__rhs || *__rhs < __lhs; }
877 template<
typename _Tp>
879 operator<=(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
880 {
return !__lhs || !(__rhs < *__lhs); }
882 template<
typename _Tp>
884 operator<=(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
885 {
return __rhs && !(*__rhs < __lhs); }
887 template<
typename _Tp>
889 operator>=(
const optional<_Tp>& __lhs,
const _Tp& __rhs)
890 {
return __lhs && !(*__lhs < __rhs); }
892 template<
typename _Tp>
894 operator>=(
const _Tp& __lhs,
const optional<_Tp>& __rhs)
895 {
return !__rhs || !(__lhs < *__rhs); }
898 template<
typename _Tp>
900 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
901 noexcept(
noexcept(__lhs.swap(__rhs)))
902 { __lhs.swap(__rhs); }
904 template<
typename _Tp>
905 constexpr optional<decay_t<_Tp>>
906 make_optional(_Tp&& __t)
907 {
return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; }
917 template<
typename _Tp>
918 struct hash<experimental::optional<_Tp>>
920 using result_type = size_t;
929 constexpr size_t __magic_disengaged_hash =
static_cast<size_t>(-3333);
930 return __t ?
hash<_Tp> {}(*__t) : __magic_disengaged_hash;
934_GLIBCXX_END_NAMESPACE_VERSION
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
typename decay< _Tp >::type decay_t
Alias template for decay.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
constexpr nullopt_t nullopt
Tag to disengage optional objects.
constexpr in_place_t in_place
Tag for in-place construction.
ISO C++ entities toplevel namespace is std.
One of two subclasses of exception.
Primary class template hash.
is_nothrow_move_constructible
is_trivially_destructible
Class template for optional values.
Tag type for in-place construction.
Tag type to disengage optional objects.
Exception class thrown when a disengaged optional object is dereferenced.