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