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