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