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