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/invoke.h> // __invoke
39#include <bits/stl_construct.h> // construct_at
40#include <bits/utility.h> // in_place_t
42namespace std _GLIBCXX_VISIBILITY(default)
44_GLIBCXX_BEGIN_NAMESPACE_VERSION
47 * @defgroup expected_values Expected values
48 * @addtogroup utilities
53#define __cpp_lib_expected 202211L
55 /// Discriminated union that holds an expected value or an error value.
59 template<typename _Tp, typename _Er>
62 /// Wrapper type used to pass an error value to a `std::expected`.
66 template<typename _Er>
69 /// Exception thrown by std::expected when the value() is not present.
73 template<typename _Er>
74 class bad_expected_access;
77 class bad_expected_access<void> : public exception
80 bad_expected_access() noexcept { }
81 bad_expected_access(const bad_expected_access&) = default;
82 bad_expected_access(bad_expected_access&&) = default;
83 bad_expected_access& operator=(const bad_expected_access&) = default;
84 bad_expected_access& operator=(bad_expected_access&&) = default;
85 ~bad_expected_access() = default;
91 what() const noexcept override
92 { return "bad access to std::expected without expected value"; }
95 template<typename _Er>
96 class bad_expected_access : public bad_expected_access<void> {
99 bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
101 // XXX const char* what() const noexcept override;
110 error() const & noexcept
116 { return std::move(_M_unex); }
120 error() const && noexcept
121 { return std::move(_M_unex); }
127 /// Tag type for constructing unexpected values in a std::expected
133 explicit unexpect_t() = default;
136 /// Tag for constructing unexpected values in a std::expected
140 inline constexpr unexpect_t unexpect{};
142/// @cond undocumented
145 template<typename _Tp>
146 constexpr bool __is_expected = false;
147 template<typename _Tp, typename _Er>
148 constexpr bool __is_expected<expected<_Tp, _Er>> = true;
150 template<typename _Tp>
151 constexpr bool __is_unexpected = false;
152 template<typename _Tp>
153 constexpr bool __is_unexpected<unexpected<_Tp>> = true;
155 template<typename _Fn, typename _Tp>
156 using __result = remove_cvref_t<invoke_result_t<_Fn&&, _Tp&&>>;
157 template<typename _Fn, typename _Tp>
158 using __result_xform = remove_cv_t<invoke_result_t<_Fn&&, _Tp&&>>;
159 template<typename _Fn>
160 using __result0 = remove_cvref_t<invoke_result_t<_Fn&&>>;
161 template<typename _Fn>
162 using __result0_xform = remove_cv_t<invoke_result_t<_Fn&&>>;
164 template<typename _Er>
165 concept __can_be_unexpected
166 = is_object_v<_Er> && (!is_array_v<_Er>)
167 && (!__expected::__is_unexpected<_Er>)
168 && (!is_const_v<_Er>) && (!is_volatile_v<_Er>);
170 // Tag types for in-place construction from an invocation result.
171 struct __in_place_inv { };
172 struct __unexpect_inv { };
176 template<typename _Er>
179 static_assert( __expected::__can_be_unexpected<_Er> );
182 constexpr unexpected(const unexpected&) = default;
183 constexpr unexpected(unexpected&&) = default;
185 template<typename _Err = _Er>
186 requires (!is_same_v<remove_cvref_t<_Err>, unexpected>)
187 && (!is_same_v<remove_cvref_t<_Err>, in_place_t>)
188 && is_constructible_v<_Er, _Err>
190 unexpected(_Err&& __e)
191 noexcept(is_nothrow_constructible_v<_Er, _Err>)
192 : _M_unex(std::forward<_Err>(__e))
195 template<typename... _Args>
196 requires is_constructible_v<_Er, _Args...>
198 unexpected(in_place_t, _Args&&... __args)
199 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
200 : _M_unex(std::forward<_Args>(__args)...)
203 template<typename _Up, typename... _Args>
204 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
206 unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
207 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
209 : _M_unex(__il, std::forward<_Args>(__args)...)
212 constexpr unexpected& operator=(const unexpected&) = default;
213 constexpr unexpected& operator=(unexpected&&) = default;
218 error() const & noexcept { return _M_unex; }
222 error() & noexcept { return _M_unex; }
225 constexpr const _Er&&
226 error() const && noexcept { return std::move(_M_unex); }
230 error() && noexcept { return std::move(_M_unex); }
233 swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
234 requires is_swappable_v<_Er>
237 swap(_M_unex, __other._M_unex);
240 template<typename _Err>
242 friend constexpr bool
243 operator==(const unexpected& __x, const unexpected<_Err>& __y)
244 { return __x._M_unex == __y.error(); }
246 friend constexpr void
247 swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
248 requires is_swappable_v<_Er>
255 template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
257/// @cond undocumented
260 template<typename _Tp>
263 static_assert( is_nothrow_move_constructible_v<_Tp> );
267 : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
268 { std::destroy_at(_M_guarded); }
273 if (_M_guarded) [[unlikely]]
274 std::construct_at(_M_guarded, std::move(_M_tmp));
277 _Guard(const _Guard&) = delete;
278 _Guard& operator=(const _Guard&) = delete;
283 _M_guarded = nullptr;
284 return std::move(_M_tmp);
292 // reinit-expected helper from [expected.object.assign]
293 template<typename _Tp, typename _Up, typename _Vp>
295 __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
296 noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
298 if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
300 std::destroy_at(__oldval);
301 std::construct_at(__newval, std::forward<_Vp>(__arg));
303 else if constexpr (is_nothrow_move_constructible_v<_Tp>)
305 _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
306 std::destroy_at(__oldval);
307 std::construct_at(__newval, std::move(__tmp));
311 _Guard<_Up> __guard(*__oldval);
312 std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
319 template<typename _Tp, typename _Er>
322 static_assert( ! is_reference_v<_Tp> );
323 static_assert( ! is_function_v<_Tp> );
324 static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
325 static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
326 static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
327 static_assert( __expected::__can_be_unexpected<_Er> );
329 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
330 static constexpr bool __cons_from_expected
331 = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
332 is_constructible<_Tp, expected<_Up, _Err>>,
333 is_constructible<_Tp, const expected<_Up, _Err>&>,
334 is_constructible<_Tp, const expected<_Up, _Err>>,
335 is_convertible<expected<_Up, _Err>&, _Tp>,
336 is_convertible<expected<_Up, _Err>, _Tp>,
337 is_convertible<const expected<_Up, _Err>&, _Tp>,
338 is_convertible<const expected<_Up, _Err>, _Tp>,
339 is_constructible<_Unex, expected<_Up, _Err>&>,
340 is_constructible<_Unex, expected<_Up, _Err>>,
341 is_constructible<_Unex, const expected<_Up, _Err>&>,
342 is_constructible<_Unex, const expected<_Up, _Err>>
345 template<typename _Up, typename _Err>
346 constexpr static bool __explicit_conv
347 = __or_v<__not_<is_convertible<_Up, _Tp>>,
348 __not_<is_convertible<_Err, _Er>>
351 template<typename _Up>
352 static constexpr bool __same_val
353 = is_same_v<typename _Up::value_type, _Tp>;
355 template<typename _Up>
356 static constexpr bool __same_err
357 = is_same_v<typename _Up::error_type, _Er>;
360 using value_type = _Tp;
361 using error_type = _Er;
362 using unexpected_type = unexpected<_Er>;
364 template<typename _Up>
365 using rebind = expected<_Up, error_type>;
369 noexcept(is_nothrow_default_constructible_v<_Tp>)
370 requires is_default_constructible_v<_Tp>
371 : _M_val(), _M_has_value(true)
374 expected(const expected&) = default;
377 expected(const expected& __x)
378 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
379 is_nothrow_copy_constructible<_Er>>)
380 requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
381 && (!is_trivially_copy_constructible_v<_Tp>
382 || !is_trivially_copy_constructible_v<_Er>)
383 : _M_has_value(__x._M_has_value)
386 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
388 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
391 expected(expected&&) = default;
394 expected(expected&& __x)
395 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
396 is_nothrow_move_constructible<_Er>>)
397 requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
398 && (!is_trivially_move_constructible_v<_Tp>
399 || !is_trivially_move_constructible_v<_Er>)
400 : _M_has_value(__x._M_has_value)
403 std::construct_at(__builtin_addressof(_M_val),
404 std::move(__x)._M_val);
406 std::construct_at(__builtin_addressof(_M_unex),
407 std::move(__x)._M_unex);
410 template<typename _Up, typename _Gr>
411 requires is_constructible_v<_Tp, const _Up&>
412 && is_constructible_v<_Er, const _Gr&>
413 && (!__cons_from_expected<_Up, _Gr>)
414 constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
415 expected(const expected<_Up, _Gr>& __x)
416 noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
417 is_nothrow_constructible<_Er, const _Gr&>>)
418 : _M_has_value(__x._M_has_value)
421 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
423 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
426 template<typename _Up, typename _Gr>
427 requires is_constructible_v<_Tp, _Up>
428 && is_constructible_v<_Er, _Gr>
429 && (!__cons_from_expected<_Up, _Gr>)
430 constexpr explicit(__explicit_conv<_Up, _Gr>)
431 expected(expected<_Up, _Gr>&& __x)
432 noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
433 is_nothrow_constructible<_Er, _Gr>>)
434 : _M_has_value(__x._M_has_value)
437 std::construct_at(__builtin_addressof(_M_val),
438 std::move(__x)._M_val);
440 std::construct_at(__builtin_addressof(_M_unex),
441 std::move(__x)._M_unex);
444 template<typename _Up = _Tp>
445 requires (!is_same_v<remove_cvref_t<_Up>, expected>)
446 && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
447 && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
448 && is_constructible_v<_Tp, _Up>
449 constexpr explicit(!is_convertible_v<_Up, _Tp>)
451 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
452 : _M_val(std::forward<_Up>(__v)), _M_has_value(true)
455 template<typename _Gr = _Er>
456 requires is_constructible_v<_Er, const _Gr&>
457 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
458 expected(const unexpected<_Gr>& __u)
459 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
460 : _M_unex(__u.error()), _M_has_value(false)
463 template<typename _Gr = _Er>
464 requires is_constructible_v<_Er, _Gr>
465 constexpr explicit(!is_convertible_v<_Gr, _Er>)
466 expected(unexpected<_Gr>&& __u)
467 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
468 : _M_unex(std::move(__u).error()), _M_has_value(false)
471 template<typename... _Args>
472 requires is_constructible_v<_Tp, _Args...>
474 expected(in_place_t, _Args&&... __args)
475 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
476 : _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
479 template<typename _Up, typename... _Args>
480 requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
482 expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
483 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
485 : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
488 template<typename... _Args>
489 requires is_constructible_v<_Er, _Args...>
491 expected(unexpect_t, _Args&&... __args)
492 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
493 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
496 template<typename _Up, typename... _Args>
497 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
499 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
500 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
502 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
505 constexpr ~expected() = default;
507 constexpr ~expected()
508 requires (!is_trivially_destructible_v<_Tp>)
509 || (!is_trivially_destructible_v<_Er>)
512 std::destroy_at(__builtin_addressof(_M_val));
514 std::destroy_at(__builtin_addressof(_M_unex));
519 expected& operator=(const expected&) = delete;
522 operator=(const expected& __x)
523 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
524 is_nothrow_copy_constructible<_Er>,
525 is_nothrow_copy_assignable<_Tp>,
526 is_nothrow_copy_assignable<_Er>>)
527 requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
528 && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
529 && (is_nothrow_move_constructible_v<_Tp>
530 || is_nothrow_move_constructible_v<_Er>)
532 if (__x._M_has_value)
533 this->_M_assign_val(__x._M_val);
535 this->_M_assign_unex(__x._M_unex);
540 operator=(expected&& __x)
541 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
542 is_nothrow_move_constructible<_Er>,
543 is_nothrow_move_assignable<_Tp>,
544 is_nothrow_move_assignable<_Er>>)
545 requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
546 && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
547 && (is_nothrow_move_constructible_v<_Tp>
548 || is_nothrow_move_constructible_v<_Er>)
550 if (__x._M_has_value)
551 _M_assign_val(std::move(__x._M_val));
553 _M_assign_unex(std::move(__x._M_unex));
557 template<typename _Up = _Tp>
558 requires (!is_same_v<expected, remove_cvref_t<_Up>>)
559 && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
560 && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
561 && (is_nothrow_constructible_v<_Tp, _Up>
562 || is_nothrow_move_constructible_v<_Tp>
563 || is_nothrow_move_constructible_v<_Er>)
567 _M_assign_val(std::forward<_Up>(__v));
571 template<typename _Gr>
572 requires is_constructible_v<_Er, const _Gr&>
573 && is_assignable_v<_Er&, const _Gr&>
574 && (is_nothrow_constructible_v<_Er, const _Gr&>
575 || is_nothrow_move_constructible_v<_Tp>
576 || is_nothrow_move_constructible_v<_Er>)
578 operator=(const unexpected<_Gr>& __e)
580 _M_assign_unex(__e.error());
584 template<typename _Gr>
585 requires is_constructible_v<_Er, _Gr>
586 && is_assignable_v<_Er&, _Gr>
587 && (is_nothrow_constructible_v<_Er, _Gr>
588 || is_nothrow_move_constructible_v<_Tp>
589 || is_nothrow_move_constructible_v<_Er>)
591 operator=(unexpected<_Gr>&& __e)
593 _M_assign_unex(std::move(__e).error());
599 template<typename... _Args>
600 requires is_nothrow_constructible_v<_Tp, _Args...>
602 emplace(_Args&&... __args) noexcept
605 std::destroy_at(__builtin_addressof(_M_val));
608 std::destroy_at(__builtin_addressof(_M_unex));
611 std::construct_at(__builtin_addressof(_M_val),
612 std::forward<_Args>(__args)...);
616 template<typename _Up, typename... _Args>
617 requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
620 emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
623 std::destroy_at(__builtin_addressof(_M_val));
626 std::destroy_at(__builtin_addressof(_M_unex));
629 std::construct_at(__builtin_addressof(_M_val),
630 __il, std::forward<_Args>(__args)...);
637 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
638 is_nothrow_move_constructible<_Er>,
639 is_nothrow_swappable<_Tp&>,
640 is_nothrow_swappable<_Er&>>)
641 requires is_swappable_v<_Tp> && is_swappable_v<_Er>
642 && is_move_constructible_v<_Tp>
643 && is_move_constructible_v<_Er>
644 && (is_nothrow_move_constructible_v<_Tp>
645 || is_nothrow_move_constructible_v<_Er>)
649 if (__x._M_has_value)
652 swap(_M_val, __x._M_val);
655 this->_M_swap_val_unex(__x);
659 if (__x._M_has_value)
660 __x._M_swap_val_unex(*this);
664 swap(_M_unex, __x._M_unex);
673 operator->() const noexcept
675 __glibcxx_assert(_M_has_value);
676 return __builtin_addressof(_M_val);
681 operator->() noexcept
683 __glibcxx_assert(_M_has_value);
684 return __builtin_addressof(_M_val);
689 operator*() const & noexcept
691 __glibcxx_assert(_M_has_value);
697 operator*() & noexcept
699 __glibcxx_assert(_M_has_value);
704 constexpr const _Tp&&
705 operator*() const && noexcept
707 __glibcxx_assert(_M_has_value);
708 return std::move(_M_val);
713 operator*() && noexcept
715 __glibcxx_assert(_M_has_value);
716 return std::move(_M_val);
721 operator bool() const noexcept { return _M_has_value; }
724 constexpr bool has_value() const noexcept { return _M_has_value; }
729 if (_M_has_value) [[likely]]
731 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
737 if (_M_has_value) [[likely]]
739 const auto& __unex = _M_unex;
740 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
743 constexpr const _Tp&&
746 if (_M_has_value) [[likely]]
747 return std::move(_M_val);
748 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
754 if (_M_has_value) [[likely]]
755 return std::move(_M_val);
756 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
760 error() const & noexcept
762 __glibcxx_assert(!_M_has_value);
769 __glibcxx_assert(!_M_has_value);
773 constexpr const _Er&&
774 error() const && noexcept
776 __glibcxx_assert(!_M_has_value);
777 return std::move(_M_unex);
783 __glibcxx_assert(!_M_has_value);
784 return std::move(_M_unex);
787 template<typename _Up>
789 value_or(_Up&& __v) const &
790 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
791 is_nothrow_convertible<_Up, _Tp>>)
793 static_assert( is_copy_constructible_v<_Tp> );
794 static_assert( is_convertible_v<_Up, _Tp> );
798 return static_cast<_Tp>(std::forward<_Up>(__v));
801 template<typename _Up>
803 value_or(_Up&& __v) &&
804 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
805 is_nothrow_convertible<_Up, _Tp>>)
807 static_assert( is_move_constructible_v<_Tp> );
808 static_assert( is_convertible_v<_Up, _Tp> );
811 return std::move(_M_val);
812 return static_cast<_Tp>(std::forward<_Up>(__v));
815 template<typename _Gr = _Er>
817 error_or(_Gr&& __e) const&
819 static_assert( is_copy_constructible_v<_Er> );
820 static_assert( is_convertible_v<_Gr, _Er> );
823 return std::forward<_Gr>(__e);
827 template<typename _Gr = _Er>
829 error_or(_Gr&& __e) &&
831 static_assert( is_move_constructible_v<_Er> );
832 static_assert( is_convertible_v<_Gr, _Er> );
835 return std::forward<_Gr>(__e);
836 return std::move(_M_unex);
839 // monadic operations
841 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
843 and_then(_Fn&& __f) &
845 using _Up = __expected::__result<_Fn, _Tp&>;
846 static_assert(__expected::__is_expected<_Up>);
847 static_assert(is_same_v<typename _Up::error_type, _Er>);
850 return std::__invoke(std::forward<_Fn>(__f), _M_val);
852 return _Up(unexpect, _M_unex);
855 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
857 and_then(_Fn&& __f) const &
859 using _Up = __expected::__result<_Fn, const _Tp&>;
860 static_assert(__expected::__is_expected<_Up>);
861 static_assert(is_same_v<typename _Up::error_type, _Er>);
864 return std::__invoke(std::forward<_Fn>(__f), _M_val);
866 return _Up(unexpect, _M_unex);
869 template<typename _Fn> requires is_constructible_v<_Er, _Er>
871 and_then(_Fn&& __f) &&
873 using _Up = __expected::__result<_Fn, _Tp&&>;
874 static_assert(__expected::__is_expected<_Up>);
875 static_assert(is_same_v<typename _Up::error_type, _Er>);
878 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
880 return _Up(unexpect, std::move(_M_unex));
884 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
886 and_then(_Fn&& __f) const &&
888 using _Up = __expected::__result<_Fn, const _Tp&&>;
889 static_assert(__expected::__is_expected<_Up>);
890 static_assert(is_same_v<typename _Up::error_type, _Er>);
893 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
895 return _Up(unexpect, std::move(_M_unex));
898 template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
902 using _Gr = __expected::__result<_Fn, _Er&>;
903 static_assert(__expected::__is_expected<_Gr>);
904 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
907 return _Gr(in_place, _M_val);
909 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
912 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
914 or_else(_Fn&& __f) const &
916 using _Gr = __expected::__result<_Fn, const _Er&>;
917 static_assert(__expected::__is_expected<_Gr>);
918 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
921 return _Gr(in_place, _M_val);
923 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
927 template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
929 or_else(_Fn&& __f) &&
931 using _Gr = __expected::__result<_Fn, _Er&&>;
932 static_assert(__expected::__is_expected<_Gr>);
933 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
936 return _Gr(in_place, std::move(_M_val));
938 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
941 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
943 or_else(_Fn&& __f) const &&
945 using _Gr = __expected::__result<_Fn, const _Er&&>;
946 static_assert(__expected::__is_expected<_Gr>);
947 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
950 return _Gr(in_place, std::move(_M_val));
952 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
955 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
957 transform(_Fn&& __f) &
959 using _Up = __expected::__result_xform<_Fn, _Tp&>;
960 using _Res = expected<_Up, _Er>;
963 return _Res(__in_place_inv{}, [&]() {
964 return std::__invoke(std::forward<_Fn>(__f),
968 return _Res(unexpect, _M_unex);
971 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
973 transform(_Fn&& __f) const &
975 using _Up = __expected::__result_xform<_Fn, const _Tp&>;
976 using _Res = expected<_Up, _Er>;
979 return _Res(__in_place_inv{}, [&]() {
980 return std::__invoke(std::forward<_Fn>(__f),
984 return _Res(unexpect, _M_unex);
987 template<typename _Fn> requires is_constructible_v<_Er, _Er>
989 transform(_Fn&& __f) &&
991 using _Up = __expected::__result_xform<_Fn, _Tp>;
992 using _Res = expected<_Up, _Er>;
995 return _Res(__in_place_inv{}, [&]() {
996 return std::__invoke(std::forward<_Fn>(__f),
1000 return _Res(unexpect, std::move(_M_unex));
1003 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1005 transform(_Fn&& __f) const &&
1007 using _Up = __expected::__result_xform<_Fn, const _Tp>;
1008 using _Res = expected<_Up, _Er>;
1011 return _Res(__in_place_inv{}, [&]() {
1012 return std::__invoke(std::forward<_Fn>(__f),
1016 return _Res(unexpect, std::move(_M_unex));
1019 template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
1021 transform_error(_Fn&& __f) &
1023 using _Gr = __expected::__result_xform<_Fn, _Er&>;
1024 using _Res = expected<_Tp, _Gr>;
1027 return _Res(in_place, _M_val);
1029 return _Res(__unexpect_inv{}, [&]() {
1030 return std::__invoke(std::forward<_Fn>(__f),
1035 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
1037 transform_error(_Fn&& __f) const &
1039 using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1040 using _Res = expected<_Tp, _Gr>;
1043 return _Res(in_place, _M_val);
1045 return _Res(__unexpect_inv{}, [&]() {
1046 return std::__invoke(std::forward<_Fn>(__f),
1051 template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
1053 transform_error(_Fn&& __f) &&
1055 using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1056 using _Res = expected<_Tp, _Gr>;
1059 return _Res(in_place, std::move(_M_val));
1061 return _Res(__unexpect_inv{}, [&]() {
1062 return std::__invoke(std::forward<_Fn>(__f),
1063 std::move(_M_unex));
1067 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
1069 transform_error(_Fn&& __f) const &&
1071 using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1072 using _Res = expected<_Tp, _Gr>;
1075 return _Res(in_place, std::move(_M_val));
1077 return _Res(__unexpect_inv{}, [&]() {
1078 return std::__invoke(std::forward<_Fn>(__f),
1079 std::move(_M_unex));
1083 // equality operators
1085 template<typename _Up, typename _Er2>
1086 requires (!is_void_v<_Up>)
1087 friend constexpr bool
1088 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1089 // FIXME: noexcept(noexcept(bool(*__x == *__y))
1090 // && noexcept(bool(__x.error() == __y.error())))
1092 if (__x.has_value())
1093 return __y.has_value() && bool(*__x == *__y);
1095 return !__y.has_value() && bool(__x.error() == __y.error());
1098 template<typename _Up>
1099 friend constexpr bool
1100 operator==(const expected& __x, const _Up& __v)
1101 // FIXME: noexcept(noexcept(bool(*__x == __v)))
1102 { return __x.has_value() && bool(*__x == __v); }
1104 template<typename _Er2>
1105 friend constexpr bool
1106 operator==(const expected& __x, const unexpected<_Er2>& __e)
1107 // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1108 { return !__x.has_value() && bool(__x.error() == __e.error()); }
1110 friend constexpr void
1111 swap(expected& __x, expected& __y)
1112 noexcept(noexcept(__x.swap(__y)))
1113 requires requires {__x.swap(__y);}
1117 template<typename, typename> friend class expected;
1119 template<typename _Vp>
1121 _M_assign_val(_Vp&& __v)
1124 _M_val = std::forward<_Vp>(__v);
1127 __expected::__reinit(__builtin_addressof(_M_val),
1128 __builtin_addressof(_M_unex),
1129 std::forward<_Vp>(__v));
1130 _M_has_value = true;
1134 template<typename _Vp>
1136 _M_assign_unex(_Vp&& __v)
1140 __expected::__reinit(__builtin_addressof(_M_unex),
1141 __builtin_addressof(_M_val),
1142 std::forward<_Vp>(__v));
1143 _M_has_value = false;
1146 _M_unex = std::forward<_Vp>(__v);
1149 // Swap two expected objects when only one has a value.
1150 // Precondition: this->_M_has_value && !__rhs._M_has_value
1152 _M_swap_val_unex(expected& __rhs)
1153 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1154 is_nothrow_move_constructible<_Tp>>)
1156 if constexpr (is_nothrow_move_constructible_v<_Er>)
1158 __expected::_Guard<_Er> __guard(__rhs._M_unex);
1159 std::construct_at(__builtin_addressof(__rhs._M_val),
1160 std::move(_M_val)); // might throw
1161 __rhs._M_has_value = true;
1162 std::destroy_at(__builtin_addressof(_M_val));
1163 std::construct_at(__builtin_addressof(_M_unex),
1165 _M_has_value = false;
1169 __expected::_Guard<_Tp> __guard(_M_val);
1170 std::construct_at(__builtin_addressof(_M_unex),
1171 std::move(__rhs._M_unex)); // might throw
1172 _M_has_value = false;
1173 std::destroy_at(__builtin_addressof(__rhs._M_unex));
1174 std::construct_at(__builtin_addressof(__rhs._M_val),
1176 __rhs._M_has_value = true;
1180 using __in_place_inv = __expected::__in_place_inv;
1181 using __unexpect_inv = __expected::__unexpect_inv;
1183 template<typename _Fn>
1185 expected(__in_place_inv, _Fn&& __fn)
1186 : _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
1189 template<typename _Fn>
1191 expected(__unexpect_inv, _Fn&& __fn)
1192 : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1203 // Partial specialization for std::expected<cv void, E>
1204 template<typename _Tp, typename _Er> requires is_void_v<_Tp>
1205 class expected<_Tp, _Er>
1207 static_assert( __expected::__can_be_unexpected<_Er> );
1209 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
1210 static constexpr bool __cons_from_expected
1211 = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
1212 is_constructible<_Unex, expected<_Up, _Err>>,
1213 is_constructible<_Unex, const expected<_Up, _Err>&>,
1214 is_constructible<_Unex, const expected<_Up, _Err>>
1217 template<typename _Up>
1218 static constexpr bool __same_val
1219 = is_same_v<typename _Up::value_type, _Tp>;
1221 template<typename _Up>
1222 static constexpr bool __same_err
1223 = is_same_v<typename _Up::error_type, _Er>;
1226 using value_type = _Tp;
1227 using error_type = _Er;
1228 using unexpected_type = unexpected<_Er>;
1230 template<typename _Up>
1231 using rebind = expected<_Up, error_type>;
1235 : _M_void(), _M_has_value(true)
1238 expected(const expected&) = default;
1241 expected(const expected& __x)
1242 noexcept(is_nothrow_copy_constructible_v<_Er>)
1243 requires is_copy_constructible_v<_Er>
1244 && (!is_trivially_copy_constructible_v<_Er>)
1245 : _M_void(), _M_has_value(__x._M_has_value)
1248 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1251 expected(expected&&) = default;
1254 expected(expected&& __x)
1255 noexcept(is_nothrow_move_constructible_v<_Er>)
1256 requires is_move_constructible_v<_Er>
1257 && (!is_trivially_move_constructible_v<_Er>)
1258 : _M_void(), _M_has_value(__x._M_has_value)
1261 std::construct_at(__builtin_addressof(_M_unex),
1262 std::move(__x)._M_unex);
1265 template<typename _Up, typename _Gr>
1266 requires is_void_v<_Up>
1267 && is_constructible_v<_Er, const _Gr&>
1268 && (!__cons_from_expected<_Up, _Gr>)
1269 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1270 expected(const expected<_Up, _Gr>& __x)
1271 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1272 : _M_void(), _M_has_value(__x._M_has_value)
1275 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1278 template<typename _Up, typename _Gr>
1279 requires is_void_v<_Up>
1280 && is_constructible_v<_Er, _Gr>
1281 && (!__cons_from_expected<_Up, _Gr>)
1282 constexpr explicit(!is_convertible_v<_Gr, _Er>)
1283 expected(expected<_Up, _Gr>&& __x)
1284 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1285 : _M_void(), _M_has_value(__x._M_has_value)
1288 std::construct_at(__builtin_addressof(_M_unex),
1289 std::move(__x)._M_unex);
1292 template<typename _Gr = _Er>
1293 requires is_constructible_v<_Er, const _Gr&>
1294 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1295 expected(const unexpected<_Gr>& __u)
1296 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1297 : _M_unex(__u.error()), _M_has_value(false)
1300 template<typename _Gr = _Er>
1301 requires is_constructible_v<_Er, _Gr>
1302 constexpr explicit(!is_convertible_v<_Gr, _Er>)
1303 expected(unexpected<_Gr>&& __u)
1304 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1305 : _M_unex(std::move(__u).error()), _M_has_value(false)
1309 expected(in_place_t) noexcept
1313 template<typename... _Args>
1314 requires is_constructible_v<_Er, _Args...>
1316 expected(unexpect_t, _Args&&... __args)
1317 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1318 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1321 template<typename _Up, typename... _Args>
1322 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1324 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1325 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1327 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1330 constexpr ~expected() = default;
1332 constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1335 std::destroy_at(__builtin_addressof(_M_unex));
1340 expected& operator=(const expected&) = delete;
1343 operator=(const expected& __x)
1344 noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1345 is_nothrow_copy_assignable<_Er>>)
1346 requires is_copy_constructible_v<_Er>
1347 && is_copy_assignable_v<_Er>
1349 if (__x._M_has_value)
1352 _M_assign_unex(__x._M_unex);
1357 operator=(expected&& __x)
1358 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1359 is_nothrow_move_assignable<_Er>>)
1360 requires is_move_constructible_v<_Er>
1361 && is_move_assignable_v<_Er>
1363 if (__x._M_has_value)
1366 _M_assign_unex(std::move(__x._M_unex));
1370 template<typename _Gr>
1371 requires is_constructible_v<_Er, const _Gr&>
1372 && is_assignable_v<_Er&, const _Gr&>
1374 operator=(const unexpected<_Gr>& __e)
1376 _M_assign_unex(__e.error());
1380 template<typename _Gr>
1381 requires is_constructible_v<_Er, _Gr>
1382 && is_assignable_v<_Er&, _Gr>
1384 operator=(unexpected<_Gr>&& __e)
1386 _M_assign_unex(std::move(__e.error()));
1397 std::destroy_at(__builtin_addressof(_M_unex));
1398 _M_has_value = true;
1405 noexcept(__and_v<is_nothrow_swappable<_Er&>,
1406 is_nothrow_move_constructible<_Er>>)
1407 requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1411 if (!__x._M_has_value)
1413 std::construct_at(__builtin_addressof(_M_unex),
1414 std::move(__x._M_unex)); // might throw
1415 std::destroy_at(__builtin_addressof(__x._M_unex));
1416 _M_has_value = false;
1417 __x._M_has_value = true;
1422 if (__x._M_has_value)
1424 std::construct_at(__builtin_addressof(__x._M_unex),
1425 std::move(_M_unex)); // might throw
1426 std::destroy_at(__builtin_addressof(_M_unex));
1427 _M_has_value = true;
1428 __x._M_has_value = false;
1433 swap(_M_unex, __x._M_unex);
1442 operator bool() const noexcept { return _M_has_value; }
1445 constexpr bool has_value() const noexcept { return _M_has_value; }
1448 operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1453 if (_M_has_value) [[likely]]
1455 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1461 if (_M_has_value) [[likely]]
1463 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1466 constexpr const _Er&
1467 error() const & noexcept
1469 __glibcxx_assert(!_M_has_value);
1476 __glibcxx_assert(!_M_has_value);
1480 constexpr const _Er&&
1481 error() const && noexcept
1483 __glibcxx_assert(!_M_has_value);
1484 return std::move(_M_unex);
1490 __glibcxx_assert(!_M_has_value);
1491 return std::move(_M_unex);
1494 template<typename _Gr = _Er>
1496 error_or(_Gr&& __e) const&
1498 static_assert( is_copy_constructible_v<_Er> );
1499 static_assert( is_convertible_v<_Gr, _Er> );
1502 return std::forward<_Gr>(__e);
1506 template<typename _Gr = _Er>
1508 error_or(_Gr&& __e) &&
1510 static_assert( is_move_constructible_v<_Er> );
1511 static_assert( is_convertible_v<_Gr, _Er> );
1514 return std::forward<_Gr>(__e);
1515 return std::move(_M_unex);
1518 // monadic operations
1520 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1522 and_then(_Fn&& __f) &
1524 using _Up = __expected::__result0<_Fn>;
1525 static_assert(__expected::__is_expected<_Up>);
1526 static_assert(is_same_v<typename _Up::error_type, _Er>);
1529 return std::__invoke(std::forward<_Fn>(__f));
1531 return _Up(unexpect, _M_unex);
1534 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1536 and_then(_Fn&& __f) const &
1538 using _Up = __expected::__result0<_Fn>;
1539 static_assert(__expected::__is_expected<_Up>);
1540 static_assert(is_same_v<typename _Up::error_type, _Er>);
1543 return std::__invoke(std::forward<_Fn>(__f));
1545 return _Up(unexpect, _M_unex);
1548 template<typename _Fn> requires is_constructible_v<_Er, _Er>
1550 and_then(_Fn&& __f) &&
1552 using _Up = __expected::__result0<_Fn>;
1553 static_assert(__expected::__is_expected<_Up>);
1554 static_assert(is_same_v<typename _Up::error_type, _Er>);
1557 return std::__invoke(std::forward<_Fn>(__f));
1559 return _Up(unexpect, std::move(_M_unex));
1562 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1564 and_then(_Fn&& __f) const &&
1566 using _Up = __expected::__result0<_Fn>;
1567 static_assert(__expected::__is_expected<_Up>);
1568 static_assert(is_same_v<typename _Up::error_type, _Er>);
1571 return std::__invoke(std::forward<_Fn>(__f));
1573 return _Up(unexpect, std::move(_M_unex));
1576 template<typename _Fn>
1578 or_else(_Fn&& __f) &
1580 using _Gr = __expected::__result<_Fn, _Er&>;
1581 static_assert(__expected::__is_expected<_Gr>);
1582 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1587 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
1590 template<typename _Fn>
1592 or_else(_Fn&& __f) const &
1594 using _Gr = __expected::__result<_Fn, const _Er&>;
1595 static_assert(__expected::__is_expected<_Gr>);
1596 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1601 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
1604 template<typename _Fn>
1606 or_else(_Fn&& __f) &&
1608 using _Gr = __expected::__result<_Fn, _Er&&>;
1609 static_assert(__expected::__is_expected<_Gr>);
1610 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1615 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1618 template<typename _Fn>
1620 or_else(_Fn&& __f) const &&
1622 using _Gr = __expected::__result<_Fn, const _Er&&>;
1623 static_assert(__expected::__is_expected<_Gr>);
1624 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1629 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1632 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1634 transform(_Fn&& __f) &
1636 using _Up = __expected::__result0_xform<_Fn>;
1637 using _Res = expected<_Up, _Er>;
1640 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1642 return _Res(unexpect, _M_unex);
1645 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1647 transform(_Fn&& __f) const &
1649 using _Up = __expected::__result0_xform<_Fn>;
1650 using _Res = expected<_Up, _Er>;
1653 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1655 return _Res(unexpect, _M_unex);
1658 template<typename _Fn> requires is_constructible_v<_Er, _Er>
1660 transform(_Fn&& __f) &&
1662 using _Up = __expected::__result0_xform<_Fn>;
1663 using _Res = expected<_Up, _Er>;
1666 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1668 return _Res(unexpect, std::move(_M_unex));
1671 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1673 transform(_Fn&& __f) const &&
1675 using _Up = __expected::__result0_xform<_Fn>;
1676 using _Res = expected<_Up, _Er>;
1679 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1681 return _Res(unexpect, std::move(_M_unex));
1684 template<typename _Fn>
1686 transform_error(_Fn&& __f) &
1688 using _Gr = __expected::__result_xform<_Fn, _Er&>;
1689 using _Res = expected<_Tp, _Gr>;
1694 return _Res(__unexpect_inv{}, [&]() {
1695 return std::__invoke(std::forward<_Fn>(__f),
1700 template<typename _Fn>
1702 transform_error(_Fn&& __f) const &
1704 using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1705 using _Res = expected<_Tp, _Gr>;
1710 return _Res(__unexpect_inv{}, [&]() {
1711 return std::__invoke(std::forward<_Fn>(__f),
1716 template<typename _Fn>
1718 transform_error(_Fn&& __f) &&
1720 using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1721 using _Res = expected<_Tp, _Gr>;
1726 return _Res(__unexpect_inv{}, [&]() {
1727 return std::__invoke(std::forward<_Fn>(__f),
1728 std::move(_M_unex));
1732 template<typename _Fn>
1734 transform_error(_Fn&& __f) const &&
1736 using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1737 using _Res = expected<_Tp, _Gr>;
1742 return _Res(__unexpect_inv{}, [&]() {
1743 return std::__invoke(std::forward<_Fn>(__f),
1744 std::move(_M_unex));
1748 // equality operators
1750 template<typename _Up, typename _Er2>
1751 requires is_void_v<_Up>
1752 friend constexpr bool
1753 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1754 // FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
1756 if (__x.has_value())
1757 return __y.has_value();
1759 return !__y.has_value() && bool(__x.error() == __y.error());
1762 template<typename _Er2>
1763 friend constexpr bool
1764 operator==(const expected& __x, const unexpected<_Er2>& __e)
1765 // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1766 { return !__x.has_value() && bool(__x.error() == __e.error()); }
1768 friend constexpr void
1769 swap(expected& __x, expected& __y)
1770 noexcept(noexcept(__x.swap(__y)))
1771 requires requires { __x.swap(__y); }
1775 template<typename, typename> friend class expected;
1777 template<typename _Vp>
1779 _M_assign_unex(_Vp&& __v)
1783 std::construct_at(__builtin_addressof(_M_unex),
1784 std::forward<_Vp>(__v));
1785 _M_has_value = false;
1788 _M_unex = std::forward<_Vp>(__v);
1791 using __in_place_inv = __expected::__in_place_inv;
1792 using __unexpect_inv = __expected::__unexpect_inv;
1794 template<typename _Fn>
1796 expected(__in_place_inv, _Fn&& __fn)
1797 : _M_void(), _M_has_value(true)
1798 { std::forward<_Fn>(__fn)(); }
1800 template<typename _Fn>
1802 expected(__unexpect_inv, _Fn&& __fn)
1803 : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1815_GLIBCXX_END_NAMESPACE_VERSION
1819#endif // _GLIBCXX_EXPECTED