1 // <expected> -*- C++ -*-
3 // Copyright The GNU Toolchain Authors
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/expected
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_EXPECTED
30 #define _GLIBCXX_EXPECTED
32 #pragma GCC system_header
34 #if __cplusplus > 202002L && __cpp_concepts >= 202002L
36 #include <initializer_list>
37 #include <bits/exception.h> // exception
38 #include <bits/stl_construct.h> // construct_at
39 #include <bits/utility.h> // in_place_t
41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 * @defgroup expected_values Expected values
47 * @addtogroup utilities
52 #define __cpp_lib_expected 202202L
54 /// Discriminated union that holds an expected value or an error value.
58 template<typename _Tp, typename _Er>
61 /// Wrapper type used to pass an error value to a `std::expected`.
65 template<typename _Er>
68 /// Exception thrown by std::expected when the value() is not present.
72 template<typename _Er>
73 class bad_expected_access;
76 class bad_expected_access<void> : public exception
79 bad_expected_access() noexcept { }
80 bad_expected_access(const bad_expected_access&) = default;
81 bad_expected_access(bad_expected_access&&) = default;
82 bad_expected_access& operator=(const bad_expected_access&) = default;
83 bad_expected_access& operator=(bad_expected_access&&) = default;
84 ~bad_expected_access() = default;
90 what() const noexcept override
91 { return "bad access to std::expected without expected value"; }
94 template<typename _Er>
95 class bad_expected_access : public bad_expected_access<void> {
98 bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
100 // XXX const char* what() const noexcept override;
109 error() const & noexcept
115 { return std::move(_M_unex); }
119 error() const && noexcept
120 { return std::move(_M_unex); }
126 /// Tag type for constructing unexpected values in a std::expected
132 explicit unexpect_t() = default;
135 /// Tag for constructing unexpected values in a std::expected
139 inline constexpr unexpect_t unexpect{};
144 template<typename _Tp>
145 constexpr bool __is_expected = false;
146 template<typename _Tp, typename _Er>
147 constexpr bool __is_expected<expected<_Tp, _Er>> = true;
149 template<typename _Tp>
150 constexpr bool __is_unexpected = false;
151 template<typename _Tp>
152 constexpr bool __is_unexpected<unexpected<_Tp>> = true;
154 template<typename _Er>
155 concept __can_be_unexpected
156 = is_object_v<_Er> && (!is_array_v<_Er>)
157 && (!__expected::__is_unexpected<_Er>)
158 && (!is_const_v<_Er>) && (!is_volatile_v<_Er>);
162 template<typename _Er>
165 static_assert( __expected::__can_be_unexpected<_Er> );
168 constexpr unexpected(const unexpected&) = default;
169 constexpr unexpected(unexpected&&) = default;
171 template<typename _Err = _Er>
172 requires (!is_same_v<remove_cvref_t<_Err>, unexpected>)
173 && (!is_same_v<remove_cvref_t<_Err>, in_place_t>)
174 && is_constructible_v<_Er, _Err>
176 unexpected(_Err&& __e)
177 noexcept(is_nothrow_constructible_v<_Er, _Err>)
178 : _M_unex(std::forward<_Err>(__e))
181 template<typename... _Args>
182 requires is_constructible_v<_Er, _Args...>
184 unexpected(in_place_t, _Args&&... __args)
185 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
186 : _M_unex(std::forward<_Args>(__args)...)
189 template<typename _Up, typename... _Args>
190 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
192 unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
193 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
195 : _M_unex(__il, std::forward<_Args>(__args)...)
198 constexpr unexpected& operator=(const unexpected&) = default;
199 constexpr unexpected& operator=(unexpected&&) = default;
204 error() const & noexcept { return _M_unex; }
208 error() & noexcept { return _M_unex; }
211 constexpr const _Er&&
212 error() const && noexcept { return std::move(_M_unex); }
216 error() && noexcept { return std::move(_M_unex); }
219 swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
221 static_assert( is_swappable_v<_Er> );
223 swap(_M_unex, __other._M_unex);
226 template<typename _Err>
228 friend constexpr bool
229 operator==(const unexpected& __x, const unexpected<_Err>& __y)
230 { return __x._M_unex == __y.error(); }
232 friend constexpr void
233 swap(unexpected& __x, unexpected& __y)
234 noexcept(noexcept(__x.swap(__y)))
235 requires requires {__x.swap(__y);}
242 template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
247 template<typename _Tp>
250 static_assert( is_nothrow_move_constructible_v<_Tp> );
254 : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
255 { std::destroy_at(_M_guarded); }
260 if (_M_guarded) [[unlikely]]
261 std::construct_at(_M_guarded, std::move(_M_tmp));
264 _Guard(const _Guard&) = delete;
265 _Guard& operator=(const _Guard&) = delete;
270 _M_guarded = nullptr;
271 return std::move(_M_tmp);
279 // reinit-expected helper from [expected.object.assign]
280 template<typename _Tp, typename _Up, typename _Vp>
282 __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
283 noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
285 if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
287 std::destroy_at(__oldval);
288 std::construct_at(__newval, std::forward<_Vp>(__arg));
290 else if constexpr (is_nothrow_move_constructible_v<_Tp>)
292 _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
293 std::destroy_at(__oldval);
294 std::construct_at(__newval, std::move(__tmp));
298 _Guard<_Up> __guard(*__oldval);
299 std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
306 template<typename _Tp, typename _Er>
309 static_assert( ! is_reference_v<_Tp> );
310 static_assert( ! is_function_v<_Tp> );
311 static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
312 static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
313 static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
314 static_assert( __expected::__can_be_unexpected<_Er> );
316 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
317 static constexpr bool __cons_from_expected
318 = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
319 is_constructible<_Tp, expected<_Up, _Err>>,
320 is_constructible<_Tp, const expected<_Up, _Err>&>,
321 is_constructible<_Tp, const expected<_Up, _Err>>,
322 is_convertible<expected<_Up, _Err>&, _Tp>,
323 is_convertible<expected<_Up, _Err>, _Tp>,
324 is_convertible<const expected<_Up, _Err>&, _Tp>,
325 is_convertible<const expected<_Up, _Err>, _Tp>,
326 is_constructible<_Unex, expected<_Up, _Err>&>,
327 is_constructible<_Unex, expected<_Up, _Err>>,
328 is_constructible<_Unex, const expected<_Up, _Err>&>,
329 is_constructible<_Unex, const expected<_Up, _Err>>
332 template<typename _Up, typename _Err>
333 constexpr static bool __explicit_conv
334 = __or_v<__not_<is_convertible<_Up, _Tp>>,
335 __not_<is_convertible<_Err, _Er>>
339 using value_type = _Tp;
340 using error_type = _Er;
341 using unexpected_type = unexpected<_Er>;
343 template<typename _Up>
344 using rebind = expected<_Up, error_type>;
348 noexcept(is_nothrow_default_constructible_v<_Tp>)
349 requires is_default_constructible_v<_Tp>
350 : _M_val(), _M_has_value(true)
353 expected(const expected&) = default;
356 expected(const expected& __x)
357 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
358 is_nothrow_copy_constructible<_Er>>)
359 requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
360 && (!is_trivially_copy_constructible_v<_Tp>
361 || !is_trivially_copy_constructible_v<_Er>)
362 : _M_invalid(), _M_has_value(__x._M_has_value)
365 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
367 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
370 expected(expected&&) = default;
373 expected(expected&& __x)
374 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
375 is_nothrow_move_constructible<_Er>>)
376 requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
377 && (!is_trivially_move_constructible_v<_Tp>
378 || !is_trivially_move_constructible_v<_Er>)
379 : _M_invalid(), _M_has_value(__x._M_has_value)
382 std::construct_at(__builtin_addressof(_M_val),
383 std::move(__x)._M_val);
385 std::construct_at(__builtin_addressof(_M_unex),
386 std::move(__x)._M_unex);
389 template<typename _Up, typename _Gr>
390 requires is_constructible_v<_Tp, const _Up&>
391 && is_constructible_v<_Er, const _Gr&>
392 && (!__cons_from_expected<_Up, _Gr>)
393 constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
394 expected(const expected<_Up, _Gr>& __x)
395 noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
396 is_nothrow_constructible<_Er, const _Gr&>>)
397 : _M_invalid(), _M_has_value(__x._M_has_value)
400 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
402 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
405 template<typename _Up, typename _Gr>
406 requires is_constructible_v<_Tp, _Up>
407 && is_constructible_v<_Er, _Gr>
408 && (!__cons_from_expected<_Up, _Gr>)
409 constexpr explicit(__explicit_conv<_Up, _Gr>)
410 expected(expected<_Up, _Gr>&& __x)
411 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
412 is_nothrow_constructible<_Er, _Gr>>)
413 : _M_invalid(), _M_has_value(__x._M_has_value)
416 std::construct_at(__builtin_addressof(_M_val),
417 std::move(__x)._M_val);
419 std::construct_at(__builtin_addressof(_M_unex),
420 std::move(__x)._M_unex);
423 template<typename _Up = _Tp>
424 requires (!is_same_v<remove_cvref_t<_Up>, expected>)
425 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
426 && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
427 && is_constructible_v<_Tp, _Up>
428 constexpr explicit(!is_convertible_v<_Up, _Tp>)
430 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
431 : _M_val(std::forward<_Up>(__v)), _M_has_value(true)
434 template<typename _Gr = _Er>
435 requires is_constructible_v<_Er, const _Gr&>
436 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
437 expected(const unexpected<_Gr>& __u)
438 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
439 : _M_unex(__u.error()), _M_has_value(false)
442 template<typename _Gr = _Er>
443 requires is_constructible_v<_Er, _Gr>
444 constexpr explicit(!is_convertible_v<_Gr, _Er>)
445 expected(unexpected<_Gr>&& __u)
446 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
447 : _M_unex(std::move(__u).error()), _M_has_value(false)
450 template<typename... _Args>
451 requires is_constructible_v<_Tp, _Args...>
453 expected(in_place_t, _Args&&... __args)
454 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
455 : _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
458 template<typename _Up, typename... _Args>
459 requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
461 expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
462 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
464 : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
467 template<typename... _Args>
468 requires is_constructible_v<_Er, _Args...>
470 expected(unexpect_t, _Args&&... __args)
471 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
472 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
475 template<typename _Up, typename... _Args>
476 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
478 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
479 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
481 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
484 constexpr ~expected() = default;
486 constexpr ~expected()
487 requires (!is_trivially_destructible_v<_Tp>)
488 || (!is_trivially_destructible_v<_Er>)
491 std::destroy_at(__builtin_addressof(_M_val));
493 std::destroy_at(__builtin_addressof(_M_unex));
498 expected& operator=(const expected&) = delete;
501 operator=(const expected& __x)
502 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
503 is_nothrow_copy_constructible<_Er>,
504 is_nothrow_copy_assignable<_Tp>,
505 is_nothrow_copy_assignable<_Er>>)
506 requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
507 && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
508 && (is_nothrow_move_constructible_v<_Tp>
509 || is_nothrow_move_constructible_v<_Er>)
511 if (__x._M_has_value)
512 this->_M_assign_val(__x._M_val);
514 this->_M_assign_unex(__x._M_unex);
519 operator=(expected&& __x)
520 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
521 is_nothrow_move_constructible<_Er>,
522 is_nothrow_move_assignable<_Tp>,
523 is_nothrow_move_assignable<_Er>>)
524 requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
525 && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
526 && (is_nothrow_move_constructible_v<_Tp>
527 || is_nothrow_move_constructible_v<_Er>)
529 if (__x._M_has_value)
530 _M_assign_val(std::move(__x._M_val));
532 _M_assign_unex(std::move(__x._M_unex));
536 template<typename _Up = _Tp>
537 requires (!is_same_v<expected, remove_cvref_t<_Up>>)
538 && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
539 && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
540 && (is_nothrow_constructible_v<_Tp, _Up>
541 || is_nothrow_move_constructible_v<_Tp>
542 || is_nothrow_move_constructible_v<_Er>)
546 _M_assign_val(std::forward<_Up>(__v));
550 template<typename _Gr>
551 requires is_constructible_v<_Er, const _Gr&>
552 && is_assignable_v<_Er&, const _Gr&>
553 && (is_nothrow_constructible_v<_Er, const _Gr&>
554 || is_nothrow_move_constructible_v<_Tp>
555 || is_nothrow_move_constructible_v<_Er>)
557 operator=(const unexpected<_Gr>& __e)
559 _M_assign_unex(__e.error());
563 template<typename _Gr>
564 requires is_constructible_v<_Er, _Gr>
565 && is_assignable_v<_Er&, _Gr>
566 && (is_nothrow_constructible_v<_Er, _Gr>
567 || is_nothrow_move_constructible_v<_Tp>
568 || is_nothrow_move_constructible_v<_Er>)
570 operator=(unexpected<_Gr>&& __e)
572 _M_assign_unex(std::move(__e).error());
578 template<typename... _Args>
579 requires is_nothrow_constructible_v<_Tp, _Args...>
581 emplace(_Args&&... __args) noexcept
584 std::destroy_at(__builtin_addressof(_M_val));
587 std::destroy_at(__builtin_addressof(_M_unex));
590 std::construct_at(__builtin_addressof(_M_val),
591 std::forward<_Args>(__args)...);
595 template<typename _Up, typename... _Args>
596 requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
599 emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
602 std::destroy_at(__builtin_addressof(_M_val));
605 std::destroy_at(__builtin_addressof(_M_unex));
608 std::construct_at(__builtin_addressof(_M_val),
609 __il, std::forward<_Args>(__args)...);
616 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
617 is_nothrow_move_constructible<_Er>,
618 is_nothrow_swappable<_Tp&>,
619 is_nothrow_swappable<_Er&>>)
620 requires is_swappable_v<_Tp> && is_swappable_v<_Er>
621 && is_move_constructible_v<_Tp>
622 && is_move_constructible_v<_Er>
623 && (is_nothrow_move_constructible_v<_Tp>
624 || is_nothrow_move_constructible_v<_Er>)
628 if (__x._M_has_value)
631 swap(_M_val, __x._M_val);
634 this->_M_swap_val_unex(__x);
638 if (__x._M_has_value)
639 __x._M_swap_val_unex(*this);
643 swap(_M_unex, __x._M_unex);
652 operator->() const noexcept
654 __glibcxx_assert(_M_has_value);
655 return __builtin_addressof(_M_val);
660 operator->() noexcept
662 __glibcxx_assert(_M_has_value);
663 return __builtin_addressof(_M_val);
668 operator*() const & noexcept
670 __glibcxx_assert(_M_has_value);
676 operator*() & noexcept
678 __glibcxx_assert(_M_has_value);
683 constexpr const _Tp&&
684 operator*() const && noexcept
686 __glibcxx_assert(_M_has_value);
687 return std::move(_M_val);
692 operator*() && noexcept
694 __glibcxx_assert(_M_has_value);
695 return std::move(_M_val);
700 operator bool() const noexcept { return _M_has_value; }
703 constexpr bool has_value() const noexcept { return _M_has_value; }
708 if (_M_has_value) [[likely]]
710 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
716 if (_M_has_value) [[likely]]
718 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
721 constexpr const _Tp&&
724 if (_M_has_value) [[likely]]
725 return std::move(_M_val);
726 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(
727 std::move(_M_unex)));
733 if (_M_has_value) [[likely]]
734 return std::move(_M_val);
735 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(
736 std::move(_M_unex)));
740 error() const & noexcept
742 __glibcxx_assert(!_M_has_value);
749 __glibcxx_assert(!_M_has_value);
753 constexpr const _Er&&
754 error() const && noexcept
756 __glibcxx_assert(!_M_has_value);
757 return std::move(_M_unex);
763 __glibcxx_assert(!_M_has_value);
764 return std::move(_M_unex);
767 template<typename _Up>
769 value_or(_Up&& __v) const &
770 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
771 is_nothrow_convertible<_Up, _Tp>>)
773 static_assert( is_copy_constructible_v<_Tp> );
774 static_assert( is_convertible_v<_Up, _Tp> );
778 return static_cast<_Tp>(std::forward<_Up>(__v));
781 template<typename _Up>
783 value_or(_Up&& __v) &&
784 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
785 is_nothrow_convertible<_Up, _Tp>>)
787 static_assert( is_move_constructible_v<_Tp> );
788 static_assert( is_convertible_v<_Up, _Tp> );
791 return std::move(_M_val);
792 return static_cast<_Tp>(std::forward<_Up>(__v));
795 // equality operators
797 template<typename _Up, typename _Er2>
798 requires (!is_void_v<_Up>)
799 friend constexpr bool
800 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
801 noexcept(noexcept(bool(*__x == *__y))
802 && noexcept(bool(__x.error() == __y.error())))
805 return __y.has_value() && bool(*__x == *__y);
807 return !__y.has_value() && bool(__x.error() == __y.error());
810 template<typename _Up>
811 friend constexpr bool
812 operator==(const expected& __x, const _Up& __v)
813 noexcept(noexcept(bool(*__x == __v)))
814 { return __x.has_value() && bool(*__x == __v); }
816 template<typename _Er2>
817 friend constexpr bool
818 operator==(const expected& __x, const unexpected<_Er2>& __e)
819 noexcept(noexcept(bool(__x.error() == __e.error())))
820 { return !__x.has_value() && bool(__x.error() == __e.error()); }
822 friend constexpr void
823 swap(expected& __x, expected& __y)
824 noexcept(noexcept(__x.swap(__y)))
825 requires requires {__x.swap(__y);}
829 template<typename, typename> friend class expected;
831 template<typename _Vp>
833 _M_assign_val(_Vp&& __v)
836 _M_val = std::forward<_Vp>(__v);
839 __expected::__reinit(__builtin_addressof(_M_val),
840 __builtin_addressof(_M_unex),
841 std::forward<_Vp>(__v));
846 template<typename _Vp>
848 _M_assign_unex(_Vp&& __v)
852 __expected::__reinit(__builtin_addressof(_M_unex),
853 __builtin_addressof(_M_val),
854 std::forward<_Vp>(__v));
855 _M_has_value = false;
858 _M_unex = std::forward<_Vp>(__v);
861 // Swap two expected objects when only one has a value.
862 // Precondition: this->_M_has_value && !__rhs._M_has_value
864 _M_swap_val_unex(expected& __rhs)
865 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
866 is_nothrow_move_constructible<_Tp>>)
868 if constexpr (is_nothrow_move_constructible_v<_Er>)
870 __expected::_Guard<_Er> __guard(__rhs._M_unex);
871 std::construct_at(__builtin_addressof(__rhs._M_val),
872 std::move(_M_val)); // might throw
873 __rhs._M_has_value = true;
874 std::destroy_at(__builtin_addressof(_M_val));
875 std::construct_at(__builtin_addressof(_M_unex),
877 _M_has_value = false;
881 __expected::_Guard<_Tp> __guard(__rhs._M_val);
882 std::construct_at(__builtin_addressof(_M_unex),
883 std::move(__rhs._M_unex)); // might throw
884 _M_has_value = false;
885 std::destroy_at(__builtin_addressof(__rhs._M_unex));
886 std::construct_at(__builtin_addressof(__rhs._M_val),
888 __rhs._M_has_value = true;
893 struct { } _M_invalid;
901 // Partial specialization for std::expected<cv void, E>
902 template<typename _Tp, typename _Er> requires is_void_v<_Tp>
903 class expected<_Tp, _Er>
905 static_assert( __expected::__can_be_unexpected<_Er> );
907 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
908 static constexpr bool __cons_from_expected
909 = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
910 is_constructible<_Unex, expected<_Up, _Err>>,
911 is_constructible<_Unex, const expected<_Up, _Err>&>,
912 is_constructible<_Unex, const expected<_Up, _Err>>
916 using value_type = _Tp;
917 using error_type = _Er;
918 using unexpected_type = unexpected<_Er>;
920 template<typename _Up>
921 using rebind = expected<_Up, error_type>;
925 : _M_void(), _M_has_value(true)
928 expected(const expected&) = default;
931 expected(const expected& __x)
932 noexcept(is_nothrow_copy_constructible_v<_Er>)
933 requires is_copy_constructible_v<_Er>
934 && (!is_trivially_copy_constructible_v<_Er>)
935 : _M_void(), _M_has_value(__x._M_has_value)
938 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
941 expected(expected&&) = default;
944 expected(expected&& __x)
945 noexcept(is_nothrow_move_constructible_v<_Er>)
946 requires is_move_constructible_v<_Er>
947 && (!is_trivially_move_constructible_v<_Er>)
948 : _M_void(), _M_has_value(__x._M_has_value)
951 std::construct_at(__builtin_addressof(_M_unex),
952 std::move(__x)._M_unex);
955 template<typename _Up, typename _Gr>
956 requires is_void_v<_Up>
957 && is_constructible_v<_Er, const _Gr&>
958 && (!__cons_from_expected<_Up, _Gr>)
959 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
960 expected(const expected<_Up, _Gr>& __x)
961 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
962 : _M_void(), _M_has_value(__x._M_has_value)
965 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
968 template<typename _Up, typename _Gr>
969 requires is_void_v<_Up>
970 && is_constructible_v<_Er, _Gr>
971 && (!__cons_from_expected<_Up, _Gr>)
972 constexpr explicit(!is_convertible_v<_Gr, _Er>)
973 expected(expected<_Up, _Gr>&& __x)
974 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
975 : _M_void(), _M_has_value(__x._M_has_value)
978 std::construct_at(__builtin_addressof(_M_unex),
979 std::move(__x)._M_unex);
982 template<typename _Gr = _Er>
983 requires is_constructible_v<_Er, const _Gr&>
984 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
985 expected(const unexpected<_Gr>& __u)
986 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
987 : _M_unex(__u.error()), _M_has_value(false)
990 template<typename _Gr = _Er>
991 requires is_constructible_v<_Er, _Gr>
992 constexpr explicit(!is_convertible_v<_Gr, _Er>)
993 expected(unexpected<_Gr>&& __u)
994 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
995 : _M_unex(std::move(__u).error()), _M_has_value(false)
998 template<typename... _Args>
1000 expected(in_place_t) noexcept
1004 template<typename... _Args>
1005 requires is_constructible_v<_Er, _Args...>
1007 expected(unexpect_t, _Args&&... __args)
1008 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1009 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1012 template<typename _Up, typename... _Args>
1013 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1015 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1016 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1018 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1021 constexpr ~expected() = default;
1023 constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1026 std::destroy_at(__builtin_addressof(_M_unex));
1031 expected& operator=(const expected&) = delete;
1034 operator=(const expected& __x)
1035 noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1036 is_nothrow_copy_assignable<_Er>>)
1037 requires is_copy_constructible_v<_Er>
1038 && is_copy_assignable_v<_Er>
1040 if (__x._M_has_value)
1043 _M_assign_unex(__x._M_unex);
1048 operator=(expected&& __x)
1049 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1050 is_nothrow_move_assignable<_Er>>)
1051 requires is_move_constructible_v<_Er>
1052 && is_move_assignable_v<_Er>
1054 if (__x._M_has_value)
1057 _M_assign_unex(std::move(__x._M_unex));
1061 template<typename _Gr>
1062 requires is_constructible_v<_Er, const _Gr&>
1063 && is_assignable_v<_Er&, const _Gr&>
1065 operator=(const unexpected<_Gr>& __e)
1067 _M_assign_unex(__e.error());
1071 template<typename _Gr>
1072 requires is_constructible_v<_Er, _Gr>
1073 && is_assignable_v<_Er&, _Gr>
1075 operator=(unexpected<_Gr>&& __e)
1077 _M_assign_unex(std::move(__e.error()));
1088 std::destroy_at(__builtin_addressof(_M_unex));
1089 _M_has_value = true;
1096 noexcept(__and_v<is_nothrow_swappable<_Er&>,
1097 is_nothrow_move_constructible<_Er>>)
1098 requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1102 if (!__x._M_has_value)
1104 std::construct_at(__builtin_addressof(_M_unex),
1105 std::move(__x._M_unex)); // might throw
1106 std::destroy_at(__builtin_addressof(__x._M_unex));
1107 _M_has_value = false;
1108 __x._M_has_value = true;
1113 if (__x._M_has_value)
1115 std::construct_at(__builtin_addressof(__x._M_unex),
1116 std::move(_M_unex)); // might throw
1117 std::destroy_at(__builtin_addressof(_M_unex));
1118 _M_has_value = true;
1119 __x._M_has_value = false;
1124 swap(_M_unex, __x._M_unex);
1133 operator bool() const noexcept { return _M_has_value; }
1136 constexpr bool has_value() const noexcept { return _M_has_value; }
1139 operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1144 if (_M_has_value) [[likely]]
1146 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1152 if (_M_has_value) [[likely]]
1154 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1157 constexpr const _Er&
1158 error() const & noexcept
1160 __glibcxx_assert(!_M_has_value);
1167 __glibcxx_assert(!_M_has_value);
1171 constexpr const _Er&&
1172 error() const && noexcept
1174 __glibcxx_assert(!_M_has_value);
1175 return std::move(_M_unex);
1181 __glibcxx_assert(!_M_has_value);
1182 return std::move(_M_unex);
1185 // equality operators
1187 template<typename _Up, typename _Er2>
1188 requires is_void_v<_Up>
1189 friend constexpr bool
1190 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1191 noexcept(noexcept(bool(__x.error() == __y.error())))
1193 if (__x.has_value())
1194 return __y.has_value();
1196 return !__y.has_value() && bool(__x.error() == __y.error());
1199 template<typename _Er2>
1200 friend constexpr bool
1201 operator==(const expected& __x, const unexpected<_Er2>& __e)
1202 noexcept(noexcept(bool(__x.error() == __e.error())))
1203 { return !__x.has_value() && bool(__x.error() == __e.error()); }
1205 friend constexpr void
1206 swap(expected& __x, expected& __y)
1207 noexcept(noexcept(__x.swap(__y)))
1208 requires requires { __x.swap(__y); }
1212 template<typename, typename> friend class expected;
1214 template<typename _Vp>
1216 _M_assign_unex(_Vp&& __v)
1220 std::construct_at(__builtin_addressof(_M_unex),
1221 std::forward<_Vp>(__v));
1222 _M_has_value = false;
1225 _M_unex = std::forward<_Vp>(__v);
1238 _GLIBCXX_END_NAMESPACE_VERSION
1242 #endif // _GLIBCXX_EXPECTED