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