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