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
41namespace 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>)
220 requires 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) noexcept(noexcept(__x.swap(__y)))
234 requires is_swappable_v<_Er>
241 template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
246 template<typename _Tp>
249 static_assert( is_nothrow_move_constructible_v<_Tp> );
253 : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
254 { std::destroy_at(_M_guarded); }
259 if (_M_guarded) [[unlikely]]
260 std::construct_at(_M_guarded, std::move(_M_tmp));
263 _Guard(const _Guard&) = delete;
264 _Guard& operator=(const _Guard&) = delete;
269 _M_guarded = nullptr;
270 return std::move(_M_tmp);
278 // reinit-expected helper from [expected.object.assign]
279 template<typename _Tp, typename _Up, typename _Vp>
281 __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
282 noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
284 if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
286 std::destroy_at(__oldval);
287 std::construct_at(__newval, std::forward<_Vp>(__arg));
289 else if constexpr (is_nothrow_move_constructible_v<_Tp>)
291 _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
292 std::destroy_at(__oldval);
293 std::construct_at(__newval, std::move(__tmp));
297 _Guard<_Up> __guard(*__oldval);
298 std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
305 template<typename _Tp, typename _Er>
308 static_assert( ! is_reference_v<_Tp> );
309 static_assert( ! is_function_v<_Tp> );
310 static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
311 static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
312 static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
313 static_assert( __expected::__can_be_unexpected<_Er> );
315 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
316 static constexpr bool __cons_from_expected
317 = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
318 is_constructible<_Tp, expected<_Up, _Err>>,
319 is_constructible<_Tp, const expected<_Up, _Err>&>,
320 is_constructible<_Tp, const expected<_Up, _Err>>,
321 is_convertible<expected<_Up, _Err>&, _Tp>,
322 is_convertible<expected<_Up, _Err>, _Tp>,
323 is_convertible<const expected<_Up, _Err>&, _Tp>,
324 is_convertible<const expected<_Up, _Err>, _Tp>,
325 is_constructible<_Unex, expected<_Up, _Err>&>,
326 is_constructible<_Unex, expected<_Up, _Err>>,
327 is_constructible<_Unex, const expected<_Up, _Err>&>,
328 is_constructible<_Unex, const expected<_Up, _Err>>
331 template<typename _Up, typename _Err>
332 constexpr static bool __explicit_conv
333 = __or_v<__not_<is_convertible<_Up, _Tp>>,
334 __not_<is_convertible<_Err, _Er>>
338 using value_type = _Tp;
339 using error_type = _Er;
340 using unexpected_type = unexpected<_Er>;
342 template<typename _Up>
343 using rebind = expected<_Up, error_type>;
347 noexcept(is_nothrow_default_constructible_v<_Tp>)
348 requires is_default_constructible_v<_Tp>
349 : _M_val(), _M_has_value(true)
352 expected(const expected&) = default;
355 expected(const expected& __x)
356 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
357 is_nothrow_copy_constructible<_Er>>)
358 requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
359 && (!is_trivially_copy_constructible_v<_Tp>
360 || !is_trivially_copy_constructible_v<_Er>)
361 : _M_has_value(__x._M_has_value)
364 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
366 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
369 expected(expected&&) = default;
372 expected(expected&& __x)
373 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
374 is_nothrow_move_constructible<_Er>>)
375 requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
376 && (!is_trivially_move_constructible_v<_Tp>
377 || !is_trivially_move_constructible_v<_Er>)
378 : _M_has_value(__x._M_has_value)
381 std::construct_at(__builtin_addressof(_M_val),
382 std::move(__x)._M_val);
384 std::construct_at(__builtin_addressof(_M_unex),
385 std::move(__x)._M_unex);
388 template<typename _Up, typename _Gr>
389 requires is_constructible_v<_Tp, const _Up&>
390 && is_constructible_v<_Er, const _Gr&>
391 && (!__cons_from_expected<_Up, _Gr>)
392 constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
393 expected(const expected<_Up, _Gr>& __x)
394 noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
395 is_nothrow_constructible<_Er, const _Gr&>>)
396 : _M_has_value(__x._M_has_value)
399 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
401 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
404 template<typename _Up, typename _Gr>
405 requires is_constructible_v<_Tp, _Up>
406 && is_constructible_v<_Er, _Gr>
407 && (!__cons_from_expected<_Up, _Gr>)
408 constexpr explicit(__explicit_conv<_Up, _Gr>)
409 expected(expected<_Up, _Gr>&& __x)
410 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
411 is_nothrow_constructible<_Er, _Gr>>)
412 : _M_has_value(__x._M_has_value)
415 std::construct_at(__builtin_addressof(_M_val),
416 std::move(__x)._M_val);
418 std::construct_at(__builtin_addressof(_M_unex),
419 std::move(__x)._M_unex);
422 template<typename _Up = _Tp>
423 requires (!is_same_v<remove_cvref_t<_Up>, expected>)
424 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
425 && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
426 && is_constructible_v<_Tp, _Up>
427 constexpr explicit(!is_convertible_v<_Up, _Tp>)
429 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
430 : _M_val(std::forward<_Up>(__v)), _M_has_value(true)
433 template<typename _Gr = _Er>
434 requires is_constructible_v<_Er, const _Gr&>
435 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
436 expected(const unexpected<_Gr>& __u)
437 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
438 : _M_unex(__u.error()), _M_has_value(false)
441 template<typename _Gr = _Er>
442 requires is_constructible_v<_Er, _Gr>
443 constexpr explicit(!is_convertible_v<_Gr, _Er>)
444 expected(unexpected<_Gr>&& __u)
445 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
446 : _M_unex(std::move(__u).error()), _M_has_value(false)
449 template<typename... _Args>
450 requires is_constructible_v<_Tp, _Args...>
452 expected(in_place_t, _Args&&... __args)
453 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
454 : _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
457 template<typename _Up, typename... _Args>
458 requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
460 expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
461 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
463 : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
466 template<typename... _Args>
467 requires is_constructible_v<_Er, _Args...>
469 expected(unexpect_t, _Args&&... __args)
470 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
471 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
474 template<typename _Up, typename... _Args>
475 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
477 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
478 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
480 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
483 constexpr ~expected() = default;
485 constexpr ~expected()
486 requires (!is_trivially_destructible_v<_Tp>)
487 || (!is_trivially_destructible_v<_Er>)
490 std::destroy_at(__builtin_addressof(_M_val));
492 std::destroy_at(__builtin_addressof(_M_unex));
497 expected& operator=(const expected&) = delete;
500 operator=(const expected& __x)
501 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
502 is_nothrow_copy_constructible<_Er>,
503 is_nothrow_copy_assignable<_Tp>,
504 is_nothrow_copy_assignable<_Er>>)
505 requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
506 && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
507 && (is_nothrow_move_constructible_v<_Tp>
508 || is_nothrow_move_constructible_v<_Er>)
510 if (__x._M_has_value)
511 this->_M_assign_val(__x._M_val);
513 this->_M_assign_unex(__x._M_unex);
518 operator=(expected&& __x)
519 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
520 is_nothrow_move_constructible<_Er>,
521 is_nothrow_move_assignable<_Tp>,
522 is_nothrow_move_assignable<_Er>>)
523 requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
524 && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
525 && (is_nothrow_move_constructible_v<_Tp>
526 || is_nothrow_move_constructible_v<_Er>)
528 if (__x._M_has_value)
529 _M_assign_val(std::move(__x._M_val));
531 _M_assign_unex(std::move(__x._M_unex));
535 template<typename _Up = _Tp>
536 requires (!is_same_v<expected, remove_cvref_t<_Up>>)
537 && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
538 && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
539 && (is_nothrow_constructible_v<_Tp, _Up>
540 || is_nothrow_move_constructible_v<_Tp>
541 || is_nothrow_move_constructible_v<_Er>)
545 _M_assign_val(std::forward<_Up>(__v));
549 template<typename _Gr>
550 requires is_constructible_v<_Er, const _Gr&>
551 && is_assignable_v<_Er&, const _Gr&>
552 && (is_nothrow_constructible_v<_Er, const _Gr&>
553 || is_nothrow_move_constructible_v<_Tp>
554 || is_nothrow_move_constructible_v<_Er>)
556 operator=(const unexpected<_Gr>& __e)
558 _M_assign_unex(__e.error());
562 template<typename _Gr>
563 requires is_constructible_v<_Er, _Gr>
564 && is_assignable_v<_Er&, _Gr>
565 && (is_nothrow_constructible_v<_Er, _Gr>
566 || is_nothrow_move_constructible_v<_Tp>
567 || is_nothrow_move_constructible_v<_Er>)
569 operator=(unexpected<_Gr>&& __e)
571 _M_assign_unex(std::move(__e).error());
577 template<typename... _Args>
578 requires is_nothrow_constructible_v<_Tp, _Args...>
580 emplace(_Args&&... __args) noexcept
583 std::destroy_at(__builtin_addressof(_M_val));
586 std::destroy_at(__builtin_addressof(_M_unex));
589 std::construct_at(__builtin_addressof(_M_val),
590 std::forward<_Args>(__args)...);
594 template<typename _Up, typename... _Args>
595 requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
598 emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
601 std::destroy_at(__builtin_addressof(_M_val));
604 std::destroy_at(__builtin_addressof(_M_unex));
607 std::construct_at(__builtin_addressof(_M_val),
608 __il, std::forward<_Args>(__args)...);
615 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
616 is_nothrow_move_constructible<_Er>,
617 is_nothrow_swappable<_Tp&>,
618 is_nothrow_swappable<_Er&>>)
619 requires is_swappable_v<_Tp> && is_swappable_v<_Er>
620 && is_move_constructible_v<_Tp>
621 && is_move_constructible_v<_Er>
622 && (is_nothrow_move_constructible_v<_Tp>
623 || is_nothrow_move_constructible_v<_Er>)
627 if (__x._M_has_value)
630 swap(_M_val, __x._M_val);
633 this->_M_swap_val_unex(__x);
637 if (__x._M_has_value)
638 __x._M_swap_val_unex(*this);
642 swap(_M_unex, __x._M_unex);
651 operator->() const noexcept
653 __glibcxx_assert(_M_has_value);
654 return __builtin_addressof(_M_val);
659 operator->() noexcept
661 __glibcxx_assert(_M_has_value);
662 return __builtin_addressof(_M_val);
667 operator*() const & noexcept
669 __glibcxx_assert(_M_has_value);
675 operator*() & noexcept
677 __glibcxx_assert(_M_has_value);
682 constexpr const _Tp&&
683 operator*() const && noexcept
685 __glibcxx_assert(_M_has_value);
686 return std::move(_M_val);
691 operator*() && noexcept
693 __glibcxx_assert(_M_has_value);
694 return std::move(_M_val);
699 operator bool() const noexcept { return _M_has_value; }
702 constexpr bool has_value() const noexcept { return _M_has_value; }
707 if (_M_has_value) [[likely]]
709 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
715 if (_M_has_value) [[likely]]
717 const auto& __unex = _M_unex;
718 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__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 // FIXME: 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 // FIXME: 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 // FIXME: 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(_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;
900 // Partial specialization for std::expected<cv void, E>
901 template<typename _Tp, typename _Er> requires is_void_v<_Tp>
902 class expected<_Tp, _Er>
904 static_assert( __expected::__can_be_unexpected<_Er> );
906 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
907 static constexpr bool __cons_from_expected
908 = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
909 is_constructible<_Unex, expected<_Up, _Err>>,
910 is_constructible<_Unex, const expected<_Up, _Err>&>,
911 is_constructible<_Unex, const expected<_Up, _Err>>
915 using value_type = _Tp;
916 using error_type = _Er;
917 using unexpected_type = unexpected<_Er>;
919 template<typename _Up>
920 using rebind = expected<_Up, error_type>;
924 : _M_void(), _M_has_value(true)
927 expected(const expected&) = default;
930 expected(const expected& __x)
931 noexcept(is_nothrow_copy_constructible_v<_Er>)
932 requires is_copy_constructible_v<_Er>
933 && (!is_trivially_copy_constructible_v<_Er>)
934 : _M_void(), _M_has_value(__x._M_has_value)
937 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
940 expected(expected&&) = default;
943 expected(expected&& __x)
944 noexcept(is_nothrow_move_constructible_v<_Er>)
945 requires is_move_constructible_v<_Er>
946 && (!is_trivially_move_constructible_v<_Er>)
947 : _M_void(), _M_has_value(__x._M_has_value)
950 std::construct_at(__builtin_addressof(_M_unex),
951 std::move(__x)._M_unex);
954 template<typename _Up, typename _Gr>
955 requires is_void_v<_Up>
956 && is_constructible_v<_Er, const _Gr&>
957 && (!__cons_from_expected<_Up, _Gr>)
958 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
959 expected(const expected<_Up, _Gr>& __x)
960 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
961 : _M_void(), _M_has_value(__x._M_has_value)
964 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
967 template<typename _Up, typename _Gr>
968 requires is_void_v<_Up>
969 && is_constructible_v<_Er, _Gr>
970 && (!__cons_from_expected<_Up, _Gr>)
971 constexpr explicit(!is_convertible_v<_Gr, _Er>)
972 expected(expected<_Up, _Gr>&& __x)
973 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
974 : _M_void(), _M_has_value(__x._M_has_value)
977 std::construct_at(__builtin_addressof(_M_unex),
978 std::move(__x)._M_unex);
981 template<typename _Gr = _Er>
982 requires is_constructible_v<_Er, const _Gr&>
983 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
984 expected(const unexpected<_Gr>& __u)
985 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
986 : _M_unex(__u.error()), _M_has_value(false)
989 template<typename _Gr = _Er>
990 requires is_constructible_v<_Er, _Gr>
991 constexpr explicit(!is_convertible_v<_Gr, _Er>)
992 expected(unexpected<_Gr>&& __u)
993 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
994 : _M_unex(std::move(__u).error()), _M_has_value(false)
998 expected(in_place_t) noexcept
1002 template<typename... _Args>
1003 requires is_constructible_v<_Er, _Args...>
1005 expected(unexpect_t, _Args&&... __args)
1006 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1007 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1010 template<typename _Up, typename... _Args>
1011 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1013 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1014 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1016 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1019 constexpr ~expected() = default;
1021 constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1024 std::destroy_at(__builtin_addressof(_M_unex));
1029 expected& operator=(const expected&) = delete;
1032 operator=(const expected& __x)
1033 noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1034 is_nothrow_copy_assignable<_Er>>)
1035 requires is_copy_constructible_v<_Er>
1036 && is_copy_assignable_v<_Er>
1038 if (__x._M_has_value)
1041 _M_assign_unex(__x._M_unex);
1046 operator=(expected&& __x)
1047 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1048 is_nothrow_move_assignable<_Er>>)
1049 requires is_move_constructible_v<_Er>
1050 && is_move_assignable_v<_Er>
1052 if (__x._M_has_value)
1055 _M_assign_unex(std::move(__x._M_unex));
1059 template<typename _Gr>
1060 requires is_constructible_v<_Er, const _Gr&>
1061 && is_assignable_v<_Er&, const _Gr&>
1063 operator=(const unexpected<_Gr>& __e)
1065 _M_assign_unex(__e.error());
1069 template<typename _Gr>
1070 requires is_constructible_v<_Er, _Gr>
1071 && is_assignable_v<_Er&, _Gr>
1073 operator=(unexpected<_Gr>&& __e)
1075 _M_assign_unex(std::move(__e.error()));
1086 std::destroy_at(__builtin_addressof(_M_unex));
1087 _M_has_value = true;
1094 noexcept(__and_v<is_nothrow_swappable<_Er&>,
1095 is_nothrow_move_constructible<_Er>>)
1096 requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1100 if (!__x._M_has_value)
1102 std::construct_at(__builtin_addressof(_M_unex),
1103 std::move(__x._M_unex)); // might throw
1104 std::destroy_at(__builtin_addressof(__x._M_unex));
1105 _M_has_value = false;
1106 __x._M_has_value = true;
1111 if (__x._M_has_value)
1113 std::construct_at(__builtin_addressof(__x._M_unex),
1114 std::move(_M_unex)); // might throw
1115 std::destroy_at(__builtin_addressof(_M_unex));
1116 _M_has_value = true;
1117 __x._M_has_value = false;
1122 swap(_M_unex, __x._M_unex);
1131 operator bool() const noexcept { return _M_has_value; }
1134 constexpr bool has_value() const noexcept { return _M_has_value; }
1137 operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1142 if (_M_has_value) [[likely]]
1144 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1150 if (_M_has_value) [[likely]]
1152 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1155 constexpr const _Er&
1156 error() const & noexcept
1158 __glibcxx_assert(!_M_has_value);
1165 __glibcxx_assert(!_M_has_value);
1169 constexpr const _Er&&
1170 error() const && noexcept
1172 __glibcxx_assert(!_M_has_value);
1173 return std::move(_M_unex);
1179 __glibcxx_assert(!_M_has_value);
1180 return std::move(_M_unex);
1183 // equality operators
1185 template<typename _Up, typename _Er2>
1186 requires is_void_v<_Up>
1187 friend constexpr bool
1188 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1189 // FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
1191 if (__x.has_value())
1192 return __y.has_value();
1194 return !__y.has_value() && bool(__x.error() == __y.error());
1197 template<typename _Er2>
1198 friend constexpr bool
1199 operator==(const expected& __x, const unexpected<_Er2>& __e)
1200 // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1201 { return !__x.has_value() && bool(__x.error() == __e.error()); }
1203 friend constexpr void
1204 swap(expected& __x, expected& __y)
1205 noexcept(noexcept(__x.swap(__y)))
1206 requires requires { __x.swap(__y); }
1210 template<typename, typename> friend class expected;
1212 template<typename _Vp>
1214 _M_assign_unex(_Vp&& __v)
1218 std::construct_at(__builtin_addressof(_M_unex),
1219 std::forward<_Vp>(__v));
1220 _M_has_value = false;
1223 _M_unex = std::forward<_Vp>(__v);
1236_GLIBCXX_END_NAMESPACE_VERSION
1240#endif // _GLIBCXX_EXPECTED