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