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