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