libstdc++
expected
Go to the documentation of this file.
1// <expected> -*- C++ -*-
2
3// Copyright The GNU Toolchain Authors.
4//
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)
9// any later version.
10
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.
15
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.
19
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/>.
24
25/** @file include/expected
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_EXPECTED
30#define _GLIBCXX_EXPECTED
31
32#pragma GCC system_header
33
34#if __cplusplus > 202002L && __cpp_concepts >= 202002L
35
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
41
42namespace std _GLIBCXX_VISIBILITY(default)
43{
44_GLIBCXX_BEGIN_NAMESPACE_VERSION
45
46 /**
47 * @defgroup expected_values Expected values
48 * @addtogroup utilities
49 * @since C++23
50 * @{
51 */
52
53#define __cpp_lib_expected 202211L
54
55 /// Discriminated union that holds an expected value or an error value.
56 /**
57 * @since C++23
58 */
59 template<typename _Tp, typename _Er>
60 class expected;
61
62 /// Wrapper type used to pass an error value to a `std::expected`.
63 /**
64 * @since C++23
65 */
66 template<typename _Er>
67 class unexpected;
68
69 /// Exception thrown by std::expected when the value() is not present.
70 /**
71 * @since C++23
72 */
73 template<typename _Er>
74 class bad_expected_access;
75
76 template<>
77 class bad_expected_access<void> : public exception
78 {
79 protected:
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;
86
87 public:
88
89 [[nodiscard]]
90 const char*
91 what() const noexcept override
92 { return "bad access to std::expected without expected value"; }
93 };
94
95 template<typename _Er>
96 class bad_expected_access : public bad_expected_access<void> {
97 public:
98 explicit
99 bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
100
101 // XXX const char* what() const noexcept override;
102
103 [[nodiscard]]
104 _Er&
105 error() & noexcept
106 { return _M_unex; }
107
108 [[nodiscard]]
109 const _Er&
110 error() const & noexcept
111 { return _M_unex; }
112
113 [[nodiscard]]
114 _Er&&
115 error() && noexcept
116 { return std::move(_M_unex); }
117
118 [[nodiscard]]
119 const _Er&&
120 error() const && noexcept
121 { return std::move(_M_unex); }
122
123 private:
124 _Er _M_unex;
125 };
126
127 /// Tag type for constructing unexpected values in a std::expected
128 /**
129 * @since C++23
130 */
131 struct unexpect_t
132 {
133 explicit unexpect_t() = default;
134 };
135
136 /// Tag for constructing unexpected values in a std::expected
137 /**
138 * @since C++23
139 */
140 inline constexpr unexpect_t unexpect{};
141
142/// @cond undocumented
143namespace __expected
144{
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;
149
150 template<typename _Tp>
151 constexpr bool __is_unexpected = false;
152 template<typename _Tp>
153 constexpr bool __is_unexpected<unexpected<_Tp>> = true;
154
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&&>>;
163
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>);
169
170 // Tag types for in-place construction from an invocation result.
171 struct __in_place_inv { };
172 struct __unexpect_inv { };
173}
174/// @endcond
175
176 template<typename _Er>
177 class unexpected
178 {
179 static_assert( __expected::__can_be_unexpected<_Er> );
180
181 public:
182 constexpr unexpected(const unexpected&) = default;
183 constexpr unexpected(unexpected&&) = default;
184
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>
189 constexpr explicit
190 unexpected(_Err&& __e)
191 noexcept(is_nothrow_constructible_v<_Er, _Err>)
192 : _M_unex(std::forward<_Err>(__e))
193 { }
194
195 template<typename... _Args>
196 requires is_constructible_v<_Er, _Args...>
197 constexpr explicit
198 unexpected(in_place_t, _Args&&... __args)
199 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
200 : _M_unex(std::forward<_Args>(__args)...)
201 { }
202
203 template<typename _Up, typename... _Args>
204 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
205 constexpr explicit
206 unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
207 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
208 _Args...>)
209 : _M_unex(__il, std::forward<_Args>(__args)...)
210 { }
211
212 constexpr unexpected& operator=(const unexpected&) = default;
213 constexpr unexpected& operator=(unexpected&&) = default;
214
215
216 [[nodiscard]]
217 constexpr const _Er&
218 error() const & noexcept { return _M_unex; }
219
220 [[nodiscard]]
221 constexpr _Er&
222 error() & noexcept { return _M_unex; }
223
224 [[nodiscard]]
225 constexpr const _Er&&
226 error() const && noexcept { return std::move(_M_unex); }
227
228 [[nodiscard]]
229 constexpr _Er&&
230 error() && noexcept { return std::move(_M_unex); }
231
232 constexpr void
233 swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
234 requires is_swappable_v<_Er>
235 {
236 using std::swap;
237 swap(_M_unex, __other._M_unex);
238 }
239
240 template<typename _Err>
241 [[nodiscard]]
242 friend constexpr bool
243 operator==(const unexpected& __x, const unexpected<_Err>& __y)
244 { return __x._M_unex == __y.error(); }
245
246 friend constexpr void
247 swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
248 requires is_swappable_v<_Er>
249 { __x.swap(__y); }
250
251 private:
252 _Er _M_unex;
253 };
254
255 template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
256
257/// @cond undocumented
258namespace __expected
259{
260 template<typename _Tp>
261 struct _Guard
262 {
263 static_assert( is_nothrow_move_constructible_v<_Tp> );
264
265 constexpr explicit
266 _Guard(_Tp& __x)
267 : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
268 { std::destroy_at(_M_guarded); }
269
270 constexpr
271 ~_Guard()
272 {
273 if (_M_guarded) [[unlikely]]
274 std::construct_at(_M_guarded, std::move(_M_tmp));
275 }
276
277 _Guard(const _Guard&) = delete;
278 _Guard& operator=(const _Guard&) = delete;
279
280 constexpr _Tp&&
281 release() noexcept
282 {
283 _M_guarded = nullptr;
284 return std::move(_M_tmp);
285 }
286
287 private:
288 _Tp* _M_guarded;
289 _Tp _M_tmp;
290 };
291
292 // reinit-expected helper from [expected.object.assign]
293 template<typename _Tp, typename _Up, typename _Vp>
294 constexpr void
295 __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
296 noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
297 {
298 if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
299 {
300 std::destroy_at(__oldval);
301 std::construct_at(__newval, std::forward<_Vp>(__arg));
302 }
303 else if constexpr (is_nothrow_move_constructible_v<_Tp>)
304 {
305 _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
306 std::destroy_at(__oldval);
307 std::construct_at(__newval, std::move(__tmp));
308 }
309 else
310 {
311 _Guard<_Up> __guard(*__oldval);
312 std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
313 __guard.release();
314 }
315 }
316}
317/// @endcond
318
319 template<typename _Tp, typename _Er>
320 class expected
321 {
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> );
328
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>>
343 >;
344
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>>
349 >;
350
351 template<typename _Up>
352 static constexpr bool __same_val
353 = is_same_v<typename _Up::value_type, _Tp>;
354
355 template<typename _Up>
356 static constexpr bool __same_err
357 = is_same_v<typename _Up::error_type, _Er>;
358
359 public:
360 using value_type = _Tp;
361 using error_type = _Er;
362 using unexpected_type = unexpected<_Er>;
363
364 template<typename _Up>
365 using rebind = expected<_Up, error_type>;
366
367 constexpr
368 expected()
369 noexcept(is_nothrow_default_constructible_v<_Tp>)
370 requires is_default_constructible_v<_Tp>
371 : _M_val(), _M_has_value(true)
372 { }
373
374 expected(const expected&) = default;
375
376 constexpr
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)
384 {
385 if (_M_has_value)
386 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
387 else
388 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
389 }
390
391 expected(expected&&) = default;
392
393 constexpr
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)
401 {
402 if (_M_has_value)
403 std::construct_at(__builtin_addressof(_M_val),
404 std::move(__x)._M_val);
405 else
406 std::construct_at(__builtin_addressof(_M_unex),
407 std::move(__x)._M_unex);
408 }
409
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)
419 {
420 if (_M_has_value)
421 std::construct_at(__builtin_addressof(_M_val), __x._M_val);
422 else
423 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
424 }
425
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)
435 {
436 if (_M_has_value)
437 std::construct_at(__builtin_addressof(_M_val),
438 std::move(__x)._M_val);
439 else
440 std::construct_at(__builtin_addressof(_M_unex),
441 std::move(__x)._M_unex);
442 }
443
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>)
450 expected(_Up&& __v)
451 noexcept(is_nothrow_constructible_v<_Tp, _Up>)
452 : _M_val(std::forward<_Up>(__v)), _M_has_value(true)
453 { }
454
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)
461 { }
462
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)
469 { }
470
471 template<typename... _Args>
472 requires is_constructible_v<_Tp, _Args...>
473 constexpr explicit
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)
477 { }
478
479 template<typename _Up, typename... _Args>
480 requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
481 constexpr explicit
482 expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
483 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
484 _Args...>)
485 : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
486 { }
487
488 template<typename... _Args>
489 requires is_constructible_v<_Er, _Args...>
490 constexpr explicit
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)
494 { }
495
496 template<typename _Up, typename... _Args>
497 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
498 constexpr explicit
499 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
500 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
501 _Args...>)
502 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
503 { }
504
505 constexpr ~expected() = default;
506
507 constexpr ~expected()
508 requires (!is_trivially_destructible_v<_Tp>)
509 || (!is_trivially_destructible_v<_Er>)
510 {
511 if (_M_has_value)
512 std::destroy_at(__builtin_addressof(_M_val));
513 else
514 std::destroy_at(__builtin_addressof(_M_unex));
515 }
516
517 // assignment
518
519 expected& operator=(const expected&) = delete;
520
521 constexpr expected&
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>)
531 {
532 if (__x._M_has_value)
533 this->_M_assign_val(__x._M_val);
534 else
535 this->_M_assign_unex(__x._M_unex);
536 return *this;
537 }
538
539 constexpr expected&
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>)
549 {
550 if (__x._M_has_value)
551 _M_assign_val(std::move(__x._M_val));
552 else
553 _M_assign_unex(std::move(__x._M_unex));
554 return *this;
555 }
556
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>)
564 constexpr expected&
565 operator=(_Up&& __v)
566 {
567 _M_assign_val(std::forward<_Up>(__v));
568 return *this;
569 }
570
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>)
577 constexpr expected&
578 operator=(const unexpected<_Gr>& __e)
579 {
580 _M_assign_unex(__e.error());
581 return *this;
582 }
583
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>)
590 constexpr expected&
591 operator=(unexpected<_Gr>&& __e)
592 {
593 _M_assign_unex(std::move(__e).error());
594 return *this;
595 }
596
597 // modifiers
598
599 template<typename... _Args>
600 requires is_nothrow_constructible_v<_Tp, _Args...>
601 constexpr _Tp&
602 emplace(_Args&&... __args) noexcept
603 {
604 if (_M_has_value)
605 std::destroy_at(__builtin_addressof(_M_val));
606 else
607 {
608 std::destroy_at(__builtin_addressof(_M_unex));
609 _M_has_value = true;
610 }
611 std::construct_at(__builtin_addressof(_M_val),
612 std::forward<_Args>(__args)...);
613 return _M_val;
614 }
615
616 template<typename _Up, typename... _Args>
617 requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
618 _Args...>
619 constexpr _Tp&
620 emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
621 {
622 if (_M_has_value)
623 std::destroy_at(__builtin_addressof(_M_val));
624 else
625 {
626 std::destroy_at(__builtin_addressof(_M_unex));
627 _M_has_value = true;
628 }
629 std::construct_at(__builtin_addressof(_M_val),
630 __il, std::forward<_Args>(__args)...);
631 return _M_val;
632 }
633
634 // swap
635 constexpr void
636 swap(expected& __x)
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>)
646 {
647 if (_M_has_value)
648 {
649 if (__x._M_has_value)
650 {
651 using std::swap;
652 swap(_M_val, __x._M_val);
653 }
654 else
655 this->_M_swap_val_unex(__x);
656 }
657 else
658 {
659 if (__x._M_has_value)
660 __x._M_swap_val_unex(*this);
661 else
662 {
663 using std::swap;
664 swap(_M_unex, __x._M_unex);
665 }
666 }
667 }
668
669 // observers
670
671 [[nodiscard]]
672 constexpr const _Tp*
673 operator->() const noexcept
674 {
675 __glibcxx_assert(_M_has_value);
676 return __builtin_addressof(_M_val);
677 }
678
679 [[nodiscard]]
680 constexpr _Tp*
681 operator->() noexcept
682 {
683 __glibcxx_assert(_M_has_value);
684 return __builtin_addressof(_M_val);
685 }
686
687 [[nodiscard]]
688 constexpr const _Tp&
689 operator*() const & noexcept
690 {
691 __glibcxx_assert(_M_has_value);
692 return _M_val;
693 }
694
695 [[nodiscard]]
696 constexpr _Tp&
697 operator*() & noexcept
698 {
699 __glibcxx_assert(_M_has_value);
700 return _M_val;
701 }
702
703 [[nodiscard]]
704 constexpr const _Tp&&
705 operator*() const && noexcept
706 {
707 __glibcxx_assert(_M_has_value);
708 return std::move(_M_val);
709 }
710
711 [[nodiscard]]
712 constexpr _Tp&&
713 operator*() && noexcept
714 {
715 __glibcxx_assert(_M_has_value);
716 return std::move(_M_val);
717 }
718
719 [[nodiscard]]
720 constexpr explicit
721 operator bool() const noexcept { return _M_has_value; }
722
723 [[nodiscard]]
724 constexpr bool has_value() const noexcept { return _M_has_value; }
725
726 constexpr const _Tp&
727 value() const &
728 {
729 if (_M_has_value) [[likely]]
730 return _M_val;
731 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
732 }
733
734 constexpr _Tp&
735 value() &
736 {
737 if (_M_has_value) [[likely]]
738 return _M_val;
739 const auto& __unex = _M_unex;
740 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
741 }
742
743 constexpr const _Tp&&
744 value() const &&
745 {
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)));
749 }
750
751 constexpr _Tp&&
752 value() &&
753 {
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)));
757 }
758
759 constexpr const _Er&
760 error() const & noexcept
761 {
762 __glibcxx_assert(!_M_has_value);
763 return _M_unex;
764 }
765
766 constexpr _Er&
767 error() & noexcept
768 {
769 __glibcxx_assert(!_M_has_value);
770 return _M_unex;
771 }
772
773 constexpr const _Er&&
774 error() const && noexcept
775 {
776 __glibcxx_assert(!_M_has_value);
777 return std::move(_M_unex);
778 }
779
780 constexpr _Er&&
781 error() && noexcept
782 {
783 __glibcxx_assert(!_M_has_value);
784 return std::move(_M_unex);
785 }
786
787 template<typename _Up>
788 constexpr _Tp
789 value_or(_Up&& __v) const &
790 noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
791 is_nothrow_convertible<_Up, _Tp>>)
792 {
793 static_assert( is_copy_constructible_v<_Tp> );
794 static_assert( is_convertible_v<_Up, _Tp> );
795
796 if (_M_has_value)
797 return _M_val;
798 return static_cast<_Tp>(std::forward<_Up>(__v));
799 }
800
801 template<typename _Up>
802 constexpr _Tp
803 value_or(_Up&& __v) &&
804 noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
805 is_nothrow_convertible<_Up, _Tp>>)
806 {
807 static_assert( is_move_constructible_v<_Tp> );
808 static_assert( is_convertible_v<_Up, _Tp> );
809
810 if (_M_has_value)
811 return std::move(_M_val);
812 return static_cast<_Tp>(std::forward<_Up>(__v));
813 }
814
815 template<typename _Gr = _Er>
816 constexpr _Er
817 error_or(_Gr&& __e) const&
818 {
819 static_assert( is_copy_constructible_v<_Er> );
820 static_assert( is_convertible_v<_Gr, _Er> );
821
822 if (_M_has_value)
823 return std::forward<_Gr>(__e);
824 return _M_unex;
825 }
826
827 template<typename _Gr = _Er>
828 constexpr _Er
829 error_or(_Gr&& __e) &&
830 {
831 static_assert( is_move_constructible_v<_Er> );
832 static_assert( is_convertible_v<_Gr, _Er> );
833
834 if (_M_has_value)
835 return std::forward<_Gr>(__e);
836 return std::move(_M_unex);
837 }
838
839 // monadic operations
840
841 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
842 constexpr auto
843 and_then(_Fn&& __f) &
844 {
845 using _Up = __expected::__result<_Fn, _Tp&>;
846 static_assert(__expected::__is_expected<_Up>,
847 "the function passed to std::expected<T, E>::and_then "
848 "must return a std::expected");
849 static_assert(is_same_v<typename _Up::error_type, _Er>,
850 "the function passed to std::expected<T, E>::and_then "
851 "must return a std::expected with the same error_type");
852
853 if (has_value())
854 return std::__invoke(std::forward<_Fn>(__f), _M_val);
855 else
856 return _Up(unexpect, _M_unex);
857 }
858
859 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
860 constexpr auto
861 and_then(_Fn&& __f) const &
862 {
863 using _Up = __expected::__result<_Fn, const _Tp&>;
864 static_assert(__expected::__is_expected<_Up>,
865 "the function passed to std::expected<T, E>::and_then "
866 "must return a std::expected");
867 static_assert(is_same_v<typename _Up::error_type, _Er>,
868 "the function passed to std::expected<T, E>::and_then "
869 "must return a std::expected with the same error_type");
870
871 if (has_value())
872 return std::__invoke(std::forward<_Fn>(__f), _M_val);
873 else
874 return _Up(unexpect, _M_unex);
875 }
876
877 template<typename _Fn> requires is_constructible_v<_Er, _Er>
878 constexpr auto
879 and_then(_Fn&& __f) &&
880 {
881 using _Up = __expected::__result<_Fn, _Tp&&>;
882 static_assert(__expected::__is_expected<_Up>,
883 "the function passed to std::expected<T, E>::and_then "
884 "must return a std::expected");
885 static_assert(is_same_v<typename _Up::error_type, _Er>,
886 "the function passed to std::expected<T, E>::and_then "
887 "must return a std::expected with the same error_type");
888
889 if (has_value())
890 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
891 else
892 return _Up(unexpect, std::move(_M_unex));
893 }
894
895
896 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
897 constexpr auto
898 and_then(_Fn&& __f) const &&
899 {
900 using _Up = __expected::__result<_Fn, const _Tp&&>;
901 static_assert(__expected::__is_expected<_Up>,
902 "the function passed to std::expected<T, E>::and_then "
903 "must return a std::expected");
904 static_assert(is_same_v<typename _Up::error_type, _Er>,
905 "the function passed to std::expected<T, E>::and_then "
906 "must return a std::expected with the same error_type");
907
908 if (has_value())
909 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
910 else
911 return _Up(unexpect, std::move(_M_unex));
912 }
913
914 template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
915 constexpr auto
916 or_else(_Fn&& __f) &
917 {
918 using _Gr = __expected::__result<_Fn, _Er&>;
919 static_assert(__expected::__is_expected<_Gr>,
920 "the function passed to std::expected<T, E>::or_else "
921 "must return a std::expected");
922 static_assert(is_same_v<typename _Gr::value_type, _Tp>,
923 "the function passed to std::expected<T, E>::or_else "
924 "must return a std::expected with the same value_type");
925
926 if (has_value())
927 return _Gr(in_place, _M_val);
928 else
929 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
930 }
931
932 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
933 constexpr auto
934 or_else(_Fn&& __f) const &
935 {
936 using _Gr = __expected::__result<_Fn, const _Er&>;
937 static_assert(__expected::__is_expected<_Gr>,
938 "the function passed to std::expected<T, E>::or_else "
939 "must return a std::expected");
940 static_assert(is_same_v<typename _Gr::value_type, _Tp>,
941 "the function passed to std::expected<T, E>::or_else "
942 "must return a std::expected with the same value_type");
943
944 if (has_value())
945 return _Gr(in_place, _M_val);
946 else
947 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
948 }
949
950
951 template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
952 constexpr auto
953 or_else(_Fn&& __f) &&
954 {
955 using _Gr = __expected::__result<_Fn, _Er&&>;
956 static_assert(__expected::__is_expected<_Gr>,
957 "the function passed to std::expected<T, E>::or_else "
958 "must return a std::expected");
959 static_assert(is_same_v<typename _Gr::value_type, _Tp>,
960 "the function passed to std::expected<T, E>::or_else "
961 "must return a std::expected with the same value_type");
962
963 if (has_value())
964 return _Gr(in_place, std::move(_M_val));
965 else
966 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
967 }
968
969 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
970 constexpr auto
971 or_else(_Fn&& __f) const &&
972 {
973 using _Gr = __expected::__result<_Fn, const _Er&&>;
974 static_assert(__expected::__is_expected<_Gr>,
975 "the function passed to std::expected<T, E>::or_else "
976 "must return a std::expected");
977 static_assert(is_same_v<typename _Gr::value_type, _Tp>,
978 "the function passed to std::expected<T, E>::or_else "
979 "must return a std::expected with the same value_type");
980
981 if (has_value())
982 return _Gr(in_place, std::move(_M_val));
983 else
984 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
985 }
986
987 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
988 constexpr auto
989 transform(_Fn&& __f) &
990 {
991 using _Up = __expected::__result_xform<_Fn, _Tp&>;
992 using _Res = expected<_Up, _Er>;
993
994 if (has_value())
995 return _Res(__in_place_inv{}, [&]() {
996 return std::__invoke(std::forward<_Fn>(__f),
997 _M_val);
998 });
999 else
1000 return _Res(unexpect, _M_unex);
1001 }
1002
1003 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1004 constexpr auto
1005 transform(_Fn&& __f) const &
1006 {
1007 using _Up = __expected::__result_xform<_Fn, const _Tp&>;
1008 using _Res = expected<_Up, _Er>;
1009
1010 if (has_value())
1011 return _Res(__in_place_inv{}, [&]() {
1012 return std::__invoke(std::forward<_Fn>(__f),
1013 _M_val);
1014 });
1015 else
1016 return _Res(unexpect, _M_unex);
1017 }
1018
1019 template<typename _Fn> requires is_constructible_v<_Er, _Er>
1020 constexpr auto
1021 transform(_Fn&& __f) &&
1022 {
1023 using _Up = __expected::__result_xform<_Fn, _Tp>;
1024 using _Res = expected<_Up, _Er>;
1025
1026 if (has_value())
1027 return _Res(__in_place_inv{}, [&]() {
1028 return std::__invoke(std::forward<_Fn>(__f),
1029 std::move(_M_val));
1030 });
1031 else
1032 return _Res(unexpect, std::move(_M_unex));
1033 }
1034
1035 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1036 constexpr auto
1037 transform(_Fn&& __f) const &&
1038 {
1039 using _Up = __expected::__result_xform<_Fn, const _Tp>;
1040 using _Res = expected<_Up, _Er>;
1041
1042 if (has_value())
1043 return _Res(__in_place_inv{}, [&]() {
1044 return std::__invoke(std::forward<_Fn>(__f),
1045 std::move(_M_val));
1046 });
1047 else
1048 return _Res(unexpect, std::move(_M_unex));
1049 }
1050
1051 template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
1052 constexpr auto
1053 transform_error(_Fn&& __f) &
1054 {
1055 using _Gr = __expected::__result_xform<_Fn, _Er&>;
1056 using _Res = expected<_Tp, _Gr>;
1057
1058 if (has_value())
1059 return _Res(in_place, _M_val);
1060 else
1061 return _Res(__unexpect_inv{}, [&]() {
1062 return std::__invoke(std::forward<_Fn>(__f),
1063 _M_unex);
1064 });
1065 }
1066
1067 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
1068 constexpr auto
1069 transform_error(_Fn&& __f) const &
1070 {
1071 using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1072 using _Res = expected<_Tp, _Gr>;
1073
1074 if (has_value())
1075 return _Res(in_place, _M_val);
1076 else
1077 return _Res(__unexpect_inv{}, [&]() {
1078 return std::__invoke(std::forward<_Fn>(__f),
1079 _M_unex);
1080 });
1081 }
1082
1083 template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
1084 constexpr auto
1085 transform_error(_Fn&& __f) &&
1086 {
1087 using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1088 using _Res = expected<_Tp, _Gr>;
1089
1090 if (has_value())
1091 return _Res(in_place, std::move(_M_val));
1092 else
1093 return _Res(__unexpect_inv{}, [&]() {
1094 return std::__invoke(std::forward<_Fn>(__f),
1095 std::move(_M_unex));
1096 });
1097 }
1098
1099 template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
1100 constexpr auto
1101 transform_error(_Fn&& __f) const &&
1102 {
1103 using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1104 using _Res = expected<_Tp, _Gr>;
1105
1106 if (has_value())
1107 return _Res(in_place, std::move(_M_val));
1108 else
1109 return _Res(__unexpect_inv{}, [&]() {
1110 return std::__invoke(std::forward<_Fn>(__f),
1111 std::move(_M_unex));
1112 });
1113 }
1114
1115 // equality operators
1116
1117 template<typename _Up, typename _Er2>
1118 requires (!is_void_v<_Up>)
1119 friend constexpr bool
1120 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1121 // FIXME: noexcept(noexcept(bool(*__x == *__y))
1122 // && noexcept(bool(__x.error() == __y.error())))
1123 {
1124 if (__x.has_value())
1125 return __y.has_value() && bool(*__x == *__y);
1126 else
1127 return !__y.has_value() && bool(__x.error() == __y.error());
1128 }
1129
1130 template<typename _Up>
1131 friend constexpr bool
1132 operator==(const expected& __x, const _Up& __v)
1133 // FIXME: noexcept(noexcept(bool(*__x == __v)))
1134 { return __x.has_value() && bool(*__x == __v); }
1135
1136 template<typename _Er2>
1137 friend constexpr bool
1138 operator==(const expected& __x, const unexpected<_Er2>& __e)
1139 // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1140 { return !__x.has_value() && bool(__x.error() == __e.error()); }
1141
1142 friend constexpr void
1143 swap(expected& __x, expected& __y)
1144 noexcept(noexcept(__x.swap(__y)))
1145 requires requires {__x.swap(__y);}
1146 { __x.swap(__y); }
1147
1148 private:
1149 template<typename, typename> friend class expected;
1150
1151 template<typename _Vp>
1152 constexpr void
1153 _M_assign_val(_Vp&& __v)
1154 {
1155 if (_M_has_value)
1156 _M_val = std::forward<_Vp>(__v);
1157 else
1158 {
1159 __expected::__reinit(__builtin_addressof(_M_val),
1160 __builtin_addressof(_M_unex),
1161 std::forward<_Vp>(__v));
1162 _M_has_value = true;
1163 }
1164 }
1165
1166 template<typename _Vp>
1167 constexpr void
1168 _M_assign_unex(_Vp&& __v)
1169 {
1170 if (_M_has_value)
1171 {
1172 __expected::__reinit(__builtin_addressof(_M_unex),
1173 __builtin_addressof(_M_val),
1174 std::forward<_Vp>(__v));
1175 _M_has_value = false;
1176 }
1177 else
1178 _M_unex = std::forward<_Vp>(__v);
1179 }
1180
1181 // Swap two expected objects when only one has a value.
1182 // Precondition: this->_M_has_value && !__rhs._M_has_value
1183 constexpr void
1184 _M_swap_val_unex(expected& __rhs)
1185 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1186 is_nothrow_move_constructible<_Tp>>)
1187 {
1188 if constexpr (is_nothrow_move_constructible_v<_Er>)
1189 {
1190 __expected::_Guard<_Er> __guard(__rhs._M_unex);
1191 std::construct_at(__builtin_addressof(__rhs._M_val),
1192 std::move(_M_val)); // might throw
1193 __rhs._M_has_value = true;
1194 std::destroy_at(__builtin_addressof(_M_val));
1195 std::construct_at(__builtin_addressof(_M_unex),
1196 __guard.release());
1197 _M_has_value = false;
1198 }
1199 else
1200 {
1201 __expected::_Guard<_Tp> __guard(_M_val);
1202 std::construct_at(__builtin_addressof(_M_unex),
1203 std::move(__rhs._M_unex)); // might throw
1204 _M_has_value = false;
1205 std::destroy_at(__builtin_addressof(__rhs._M_unex));
1206 std::construct_at(__builtin_addressof(__rhs._M_val),
1207 __guard.release());
1208 __rhs._M_has_value = true;
1209 }
1210 }
1211
1212 using __in_place_inv = __expected::__in_place_inv;
1213 using __unexpect_inv = __expected::__unexpect_inv;
1214
1215 template<typename _Fn>
1216 explicit constexpr
1217 expected(__in_place_inv, _Fn&& __fn)
1218 : _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
1219 { }
1220
1221 template<typename _Fn>
1222 explicit constexpr
1223 expected(__unexpect_inv, _Fn&& __fn)
1224 : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1225 { }
1226
1227 union {
1228 _Tp _M_val;
1229 _Er _M_unex;
1230 };
1231
1232 bool _M_has_value;
1233 };
1234
1235 // Partial specialization for std::expected<cv void, E>
1236 template<typename _Tp, typename _Er> requires is_void_v<_Tp>
1237 class expected<_Tp, _Er>
1238 {
1239 static_assert( __expected::__can_be_unexpected<_Er> );
1240
1241 template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
1242 static constexpr bool __cons_from_expected
1243 = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
1244 is_constructible<_Unex, expected<_Up, _Err>>,
1245 is_constructible<_Unex, const expected<_Up, _Err>&>,
1246 is_constructible<_Unex, const expected<_Up, _Err>>
1247 >;
1248
1249 template<typename _Up>
1250 static constexpr bool __same_val
1251 = is_same_v<typename _Up::value_type, _Tp>;
1252
1253 template<typename _Up>
1254 static constexpr bool __same_err
1255 = is_same_v<typename _Up::error_type, _Er>;
1256
1257 public:
1258 using value_type = _Tp;
1259 using error_type = _Er;
1260 using unexpected_type = unexpected<_Er>;
1261
1262 template<typename _Up>
1263 using rebind = expected<_Up, error_type>;
1264
1265 constexpr
1266 expected() noexcept
1267 : _M_void(), _M_has_value(true)
1268 { }
1269
1270 expected(const expected&) = default;
1271
1272 constexpr
1273 expected(const expected& __x)
1274 noexcept(is_nothrow_copy_constructible_v<_Er>)
1275 requires is_copy_constructible_v<_Er>
1276 && (!is_trivially_copy_constructible_v<_Er>)
1277 : _M_void(), _M_has_value(__x._M_has_value)
1278 {
1279 if (!_M_has_value)
1280 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1281 }
1282
1283 expected(expected&&) = default;
1284
1285 constexpr
1286 expected(expected&& __x)
1287 noexcept(is_nothrow_move_constructible_v<_Er>)
1288 requires is_move_constructible_v<_Er>
1289 && (!is_trivially_move_constructible_v<_Er>)
1290 : _M_void(), _M_has_value(__x._M_has_value)
1291 {
1292 if (!_M_has_value)
1293 std::construct_at(__builtin_addressof(_M_unex),
1294 std::move(__x)._M_unex);
1295 }
1296
1297 template<typename _Up, typename _Gr>
1298 requires is_void_v<_Up>
1299 && is_constructible_v<_Er, const _Gr&>
1300 && (!__cons_from_expected<_Up, _Gr>)
1301 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1302 expected(const expected<_Up, _Gr>& __x)
1303 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1304 : _M_void(), _M_has_value(__x._M_has_value)
1305 {
1306 if (!_M_has_value)
1307 std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
1308 }
1309
1310 template<typename _Up, typename _Gr>
1311 requires is_void_v<_Up>
1312 && is_constructible_v<_Er, _Gr>
1313 && (!__cons_from_expected<_Up, _Gr>)
1314 constexpr explicit(!is_convertible_v<_Gr, _Er>)
1315 expected(expected<_Up, _Gr>&& __x)
1316 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1317 : _M_void(), _M_has_value(__x._M_has_value)
1318 {
1319 if (!_M_has_value)
1320 std::construct_at(__builtin_addressof(_M_unex),
1321 std::move(__x)._M_unex);
1322 }
1323
1324 template<typename _Gr = _Er>
1325 requires is_constructible_v<_Er, const _Gr&>
1326 constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
1327 expected(const unexpected<_Gr>& __u)
1328 noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
1329 : _M_unex(__u.error()), _M_has_value(false)
1330 { }
1331
1332 template<typename _Gr = _Er>
1333 requires is_constructible_v<_Er, _Gr>
1334 constexpr explicit(!is_convertible_v<_Gr, _Er>)
1335 expected(unexpected<_Gr>&& __u)
1336 noexcept(is_nothrow_constructible_v<_Er, _Gr>)
1337 : _M_unex(std::move(__u).error()), _M_has_value(false)
1338 { }
1339
1340 constexpr explicit
1341 expected(in_place_t) noexcept
1342 : expected()
1343 { }
1344
1345 template<typename... _Args>
1346 requires is_constructible_v<_Er, _Args...>
1347 constexpr explicit
1348 expected(unexpect_t, _Args&&... __args)
1349 noexcept(is_nothrow_constructible_v<_Er, _Args...>)
1350 : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
1351 { }
1352
1353 template<typename _Up, typename... _Args>
1354 requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
1355 constexpr explicit
1356 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1357 noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
1358 _Args...>)
1359 : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
1360 { }
1361
1362 constexpr ~expected() = default;
1363
1364 constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
1365 {
1366 if (!_M_has_value)
1367 std::destroy_at(__builtin_addressof(_M_unex));
1368 }
1369
1370 // assignment
1371
1372 expected& operator=(const expected&) = delete;
1373
1374 constexpr expected&
1375 operator=(const expected& __x)
1376 noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
1377 is_nothrow_copy_assignable<_Er>>)
1378 requires is_copy_constructible_v<_Er>
1379 && is_copy_assignable_v<_Er>
1380 {
1381 if (__x._M_has_value)
1382 emplace();
1383 else
1384 _M_assign_unex(__x._M_unex);
1385 return *this;
1386 }
1387
1388 constexpr expected&
1389 operator=(expected&& __x)
1390 noexcept(__and_v<is_nothrow_move_constructible<_Er>,
1391 is_nothrow_move_assignable<_Er>>)
1392 requires is_move_constructible_v<_Er>
1393 && is_move_assignable_v<_Er>
1394 {
1395 if (__x._M_has_value)
1396 emplace();
1397 else
1398 _M_assign_unex(std::move(__x._M_unex));
1399 return *this;
1400 }
1401
1402 template<typename _Gr>
1403 requires is_constructible_v<_Er, const _Gr&>
1404 && is_assignable_v<_Er&, const _Gr&>
1405 constexpr expected&
1406 operator=(const unexpected<_Gr>& __e)
1407 {
1408 _M_assign_unex(__e.error());
1409 return *this;
1410 }
1411
1412 template<typename _Gr>
1413 requires is_constructible_v<_Er, _Gr>
1414 && is_assignable_v<_Er&, _Gr>
1415 constexpr expected&
1416 operator=(unexpected<_Gr>&& __e)
1417 {
1418 _M_assign_unex(std::move(__e.error()));
1419 return *this;
1420 }
1421
1422 // modifiers
1423
1424 constexpr void
1425 emplace() noexcept
1426 {
1427 if (!_M_has_value)
1428 {
1429 std::destroy_at(__builtin_addressof(_M_unex));
1430 _M_has_value = true;
1431 }
1432 }
1433
1434 // swap
1435 constexpr void
1436 swap(expected& __x)
1437 noexcept(__and_v<is_nothrow_swappable<_Er&>,
1438 is_nothrow_move_constructible<_Er>>)
1439 requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
1440 {
1441 if (_M_has_value)
1442 {
1443 if (!__x._M_has_value)
1444 {
1445 std::construct_at(__builtin_addressof(_M_unex),
1446 std::move(__x._M_unex)); // might throw
1447 std::destroy_at(__builtin_addressof(__x._M_unex));
1448 _M_has_value = false;
1449 __x._M_has_value = true;
1450 }
1451 }
1452 else
1453 {
1454 if (__x._M_has_value)
1455 {
1456 std::construct_at(__builtin_addressof(__x._M_unex),
1457 std::move(_M_unex)); // might throw
1458 std::destroy_at(__builtin_addressof(_M_unex));
1459 _M_has_value = true;
1460 __x._M_has_value = false;
1461 }
1462 else
1463 {
1464 using std::swap;
1465 swap(_M_unex, __x._M_unex);
1466 }
1467 }
1468 }
1469
1470 // observers
1471
1472 [[nodiscard]]
1473 constexpr explicit
1474 operator bool() const noexcept { return _M_has_value; }
1475
1476 [[nodiscard]]
1477 constexpr bool has_value() const noexcept { return _M_has_value; }
1478
1479 constexpr void
1480 operator*() const noexcept { __glibcxx_assert(_M_has_value); }
1481
1482 constexpr void
1483 value() const&
1484 {
1485 if (_M_has_value) [[likely]]
1486 return;
1487 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
1488 }
1489
1490 constexpr void
1491 value() &&
1492 {
1493 if (_M_has_value) [[likely]]
1494 return;
1495 _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
1496 }
1497
1498 constexpr const _Er&
1499 error() const & noexcept
1500 {
1501 __glibcxx_assert(!_M_has_value);
1502 return _M_unex;
1503 }
1504
1505 constexpr _Er&
1506 error() & noexcept
1507 {
1508 __glibcxx_assert(!_M_has_value);
1509 return _M_unex;
1510 }
1511
1512 constexpr const _Er&&
1513 error() const && noexcept
1514 {
1515 __glibcxx_assert(!_M_has_value);
1516 return std::move(_M_unex);
1517 }
1518
1519 constexpr _Er&&
1520 error() && noexcept
1521 {
1522 __glibcxx_assert(!_M_has_value);
1523 return std::move(_M_unex);
1524 }
1525
1526 template<typename _Gr = _Er>
1527 constexpr _Er
1528 error_or(_Gr&& __e) const&
1529 {
1530 static_assert( is_copy_constructible_v<_Er> );
1531 static_assert( is_convertible_v<_Gr, _Er> );
1532
1533 if (_M_has_value)
1534 return std::forward<_Gr>(__e);
1535 return _M_unex;
1536 }
1537
1538 template<typename _Gr = _Er>
1539 constexpr _Er
1540 error_or(_Gr&& __e) &&
1541 {
1542 static_assert( is_move_constructible_v<_Er> );
1543 static_assert( is_convertible_v<_Gr, _Er> );
1544
1545 if (_M_has_value)
1546 return std::forward<_Gr>(__e);
1547 return std::move(_M_unex);
1548 }
1549
1550 // monadic operations
1551
1552 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1553 constexpr auto
1554 and_then(_Fn&& __f) &
1555 {
1556 using _Up = __expected::__result0<_Fn>;
1557 static_assert(__expected::__is_expected<_Up>);
1558 static_assert(is_same_v<typename _Up::error_type, _Er>);
1559
1560 if (has_value())
1561 return std::__invoke(std::forward<_Fn>(__f));
1562 else
1563 return _Up(unexpect, _M_unex);
1564 }
1565
1566 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1567 constexpr auto
1568 and_then(_Fn&& __f) const &
1569 {
1570 using _Up = __expected::__result0<_Fn>;
1571 static_assert(__expected::__is_expected<_Up>);
1572 static_assert(is_same_v<typename _Up::error_type, _Er>);
1573
1574 if (has_value())
1575 return std::__invoke(std::forward<_Fn>(__f));
1576 else
1577 return _Up(unexpect, _M_unex);
1578 }
1579
1580 template<typename _Fn> requires is_constructible_v<_Er, _Er>
1581 constexpr auto
1582 and_then(_Fn&& __f) &&
1583 {
1584 using _Up = __expected::__result0<_Fn>;
1585 static_assert(__expected::__is_expected<_Up>);
1586 static_assert(is_same_v<typename _Up::error_type, _Er>);
1587
1588 if (has_value())
1589 return std::__invoke(std::forward<_Fn>(__f));
1590 else
1591 return _Up(unexpect, std::move(_M_unex));
1592 }
1593
1594 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1595 constexpr auto
1596 and_then(_Fn&& __f) const &&
1597 {
1598 using _Up = __expected::__result0<_Fn>;
1599 static_assert(__expected::__is_expected<_Up>);
1600 static_assert(is_same_v<typename _Up::error_type, _Er>);
1601
1602 if (has_value())
1603 return std::__invoke(std::forward<_Fn>(__f));
1604 else
1605 return _Up(unexpect, std::move(_M_unex));
1606 }
1607
1608 template<typename _Fn>
1609 constexpr auto
1610 or_else(_Fn&& __f) &
1611 {
1612 using _Gr = __expected::__result<_Fn, _Er&>;
1613 static_assert(__expected::__is_expected<_Gr>);
1614 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1615
1616 if (has_value())
1617 return _Gr();
1618 else
1619 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
1620 }
1621
1622 template<typename _Fn>
1623 constexpr auto
1624 or_else(_Fn&& __f) const &
1625 {
1626 using _Gr = __expected::__result<_Fn, const _Er&>;
1627 static_assert(__expected::__is_expected<_Gr>);
1628 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1629
1630 if (has_value())
1631 return _Gr();
1632 else
1633 return std::__invoke(std::forward<_Fn>(__f), _M_unex);
1634 }
1635
1636 template<typename _Fn>
1637 constexpr auto
1638 or_else(_Fn&& __f) &&
1639 {
1640 using _Gr = __expected::__result<_Fn, _Er&&>;
1641 static_assert(__expected::__is_expected<_Gr>);
1642 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1643
1644 if (has_value())
1645 return _Gr();
1646 else
1647 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1648 }
1649
1650 template<typename _Fn>
1651 constexpr auto
1652 or_else(_Fn&& __f) const &&
1653 {
1654 using _Gr = __expected::__result<_Fn, const _Er&&>;
1655 static_assert(__expected::__is_expected<_Gr>);
1656 static_assert(is_same_v<typename _Gr::value_type, _Tp>);
1657
1658 if (has_value())
1659 return _Gr();
1660 else
1661 return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
1662 }
1663
1664 template<typename _Fn> requires is_constructible_v<_Er, _Er&>
1665 constexpr auto
1666 transform(_Fn&& __f) &
1667 {
1668 using _Up = __expected::__result0_xform<_Fn>;
1669 using _Res = expected<_Up, _Er>;
1670
1671 if (has_value())
1672 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1673 else
1674 return _Res(unexpect, _M_unex);
1675 }
1676
1677 template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
1678 constexpr auto
1679 transform(_Fn&& __f) const &
1680 {
1681 using _Up = __expected::__result0_xform<_Fn>;
1682 using _Res = expected<_Up, _Er>;
1683
1684 if (has_value())
1685 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1686 else
1687 return _Res(unexpect, _M_unex);
1688 }
1689
1690 template<typename _Fn> requires is_constructible_v<_Er, _Er>
1691 constexpr auto
1692 transform(_Fn&& __f) &&
1693 {
1694 using _Up = __expected::__result0_xform<_Fn>;
1695 using _Res = expected<_Up, _Er>;
1696
1697 if (has_value())
1698 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1699 else
1700 return _Res(unexpect, std::move(_M_unex));
1701 }
1702
1703 template<typename _Fn> requires is_constructible_v<_Er, const _Er>
1704 constexpr auto
1705 transform(_Fn&& __f) const &&
1706 {
1707 using _Up = __expected::__result0_xform<_Fn>;
1708 using _Res = expected<_Up, _Er>;
1709
1710 if (has_value())
1711 return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
1712 else
1713 return _Res(unexpect, std::move(_M_unex));
1714 }
1715
1716 template<typename _Fn>
1717 constexpr auto
1718 transform_error(_Fn&& __f) &
1719 {
1720 using _Gr = __expected::__result_xform<_Fn, _Er&>;
1721 using _Res = expected<_Tp, _Gr>;
1722
1723 if (has_value())
1724 return _Res();
1725 else
1726 return _Res(__unexpect_inv{}, [&]() {
1727 return std::__invoke(std::forward<_Fn>(__f),
1728 _M_unex);
1729 });
1730 }
1731
1732 template<typename _Fn>
1733 constexpr auto
1734 transform_error(_Fn&& __f) const &
1735 {
1736 using _Gr = __expected::__result_xform<_Fn, const _Er&>;
1737 using _Res = expected<_Tp, _Gr>;
1738
1739 if (has_value())
1740 return _Res();
1741 else
1742 return _Res(__unexpect_inv{}, [&]() {
1743 return std::__invoke(std::forward<_Fn>(__f),
1744 _M_unex);
1745 });
1746 }
1747
1748 template<typename _Fn>
1749 constexpr auto
1750 transform_error(_Fn&& __f) &&
1751 {
1752 using _Gr = __expected::__result_xform<_Fn, _Er&&>;
1753 using _Res = expected<_Tp, _Gr>;
1754
1755 if (has_value())
1756 return _Res();
1757 else
1758 return _Res(__unexpect_inv{}, [&]() {
1759 return std::__invoke(std::forward<_Fn>(__f),
1760 std::move(_M_unex));
1761 });
1762 }
1763
1764 template<typename _Fn>
1765 constexpr auto
1766 transform_error(_Fn&& __f) const &&
1767 {
1768 using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
1769 using _Res = expected<_Tp, _Gr>;
1770
1771 if (has_value())
1772 return _Res();
1773 else
1774 return _Res(__unexpect_inv{}, [&]() {
1775 return std::__invoke(std::forward<_Fn>(__f),
1776 std::move(_M_unex));
1777 });
1778 }
1779
1780 // equality operators
1781
1782 template<typename _Up, typename _Er2>
1783 requires is_void_v<_Up>
1784 friend constexpr bool
1785 operator==(const expected& __x, const expected<_Up, _Er2>& __y)
1786 // FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
1787 {
1788 if (__x.has_value())
1789 return __y.has_value();
1790 else
1791 return !__y.has_value() && bool(__x.error() == __y.error());
1792 }
1793
1794 template<typename _Er2>
1795 friend constexpr bool
1796 operator==(const expected& __x, const unexpected<_Er2>& __e)
1797 // FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
1798 { return !__x.has_value() && bool(__x.error() == __e.error()); }
1799
1800 friend constexpr void
1801 swap(expected& __x, expected& __y)
1802 noexcept(noexcept(__x.swap(__y)))
1803 requires requires { __x.swap(__y); }
1804 { __x.swap(__y); }
1805
1806 private:
1807 template<typename, typename> friend class expected;
1808
1809 template<typename _Vp>
1810 constexpr void
1811 _M_assign_unex(_Vp&& __v)
1812 {
1813 if (_M_has_value)
1814 {
1815 std::construct_at(__builtin_addressof(_M_unex),
1816 std::forward<_Vp>(__v));
1817 _M_has_value = false;
1818 }
1819 else
1820 _M_unex = std::forward<_Vp>(__v);
1821 }
1822
1823 using __in_place_inv = __expected::__in_place_inv;
1824 using __unexpect_inv = __expected::__unexpect_inv;
1825
1826 template<typename _Fn>
1827 explicit constexpr
1828 expected(__in_place_inv, _Fn&& __fn)
1829 : _M_void(), _M_has_value(true)
1830 { std::forward<_Fn>(__fn)(); }
1831
1832 template<typename _Fn>
1833 explicit constexpr
1834 expected(__unexpect_inv, _Fn&& __fn)
1835 : _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
1836 { }
1837
1838 union {
1839 struct { } _M_void;
1840 _Er _M_unex;
1841 };
1842
1843 bool _M_has_value;
1844 };
1845 /// @}
1846
1847_GLIBCXX_END_NAMESPACE_VERSION
1848} // namespace std
1849
1850#endif // C++23
1851#endif // _GLIBCXX_EXPECTED