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