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