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