1// <optional> -*- C++ -*- 2 3// Copyright (C) 2013-2019 Free Software Foundation, Inc. 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/optional 26 * This is a Standard C++ Library header. 27 */ 28 29#ifndef _GLIBCXX_OPTIONAL 30#define _GLIBCXX_OPTIONAL 1 31 32#pragma GCC system_header 33 34#if __cplusplus >= 201703L 35 36#include <utility> 37#include <type_traits> 38#include <stdexcept> 39#include <new> 40#include <initializer_list> 41#include <bits/functexcept.h> 42#include <bits/functional_hash.h> 43#include <bits/enable_special_members.h> 44 45namespace std _GLIBCXX_VISIBILITY(default) 46{ 47_GLIBCXX_BEGIN_NAMESPACE_VERSION 48 49 /** 50 * @addtogroup utilities 51 * @{ 52 */ 53 54#define __cpp_lib_optional 201606L 55 56 template<typename _Tp> 57 class optional; 58 59 /// Tag type to disengage optional objects. 60 struct nullopt_t 61 { 62 // Do not user-declare default constructor at all for 63 // optional_value = {} syntax to work. 64 // nullopt_t() = delete; 65 66 // Used for constructing nullopt. 67 enum class _Construct { _Token }; 68 69 // Must be constexpr for nullopt_t to be literal. 70 explicit constexpr nullopt_t(_Construct) { } 71 }; 72 73 /// Tag to disengage optional objects. 74 inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; 75 76 /** 77 * @brief Exception class thrown when a disengaged optional object is 78 * dereferenced. 79 * @ingroup exceptions 80 */ 81 class bad_optional_access : public exception 82 { 83 public: 84 bad_optional_access() { } 85 86 virtual const char* what() const noexcept override 87 { return "bad optional access"; } 88 89 virtual ~bad_optional_access() noexcept = default; 90 }; 91 92 void 93 __throw_bad_optional_access() 94 __attribute__((__noreturn__)); 95 96 // XXX Does not belong here. 97 inline void 98 __throw_bad_optional_access() 99 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); } 100 101 // This class template manages construction/destruction of 102 // the contained value for a std::optional. 103 template <typename _Tp> 104 struct _Optional_payload_base 105 { 106 using _Stored_type = remove_const_t<_Tp>; 107 108 _Optional_payload_base() = default; 109 ~_Optional_payload_base() = default; 110 111 template<typename... _Args> 112 constexpr 113 _Optional_payload_base(in_place_t __tag, _Args&&... __args) 114 : _M_payload(__tag, std::forward<_Args>(__args)...), 115 _M_engaged(true) 116 { } 117 118 template<typename _Up, typename... _Args> 119 constexpr 120 _Optional_payload_base(std::initializer_list<_Up> __il, 121 _Args&&... __args) 122 : _M_payload(__il, std::forward<_Args>(__args)...), 123 _M_engaged(true) 124 { } 125 126 // Constructor used by _Optional_base copy constructor when the 127 // contained value is not trivially copy constructible. 128 constexpr 129 _Optional_payload_base(bool __engaged, 130 const _Optional_payload_base& __other) 131 { 132 if (__other._M_engaged) 133 this->_M_construct(__other._M_get()); 134 } 135 136 // Constructor used by _Optional_base move constructor when the 137 // contained value is not trivially move constructible. 138 constexpr 139 _Optional_payload_base(bool __engaged, 140 _Optional_payload_base&& __other) 141 { 142 if (__other._M_engaged) 143 this->_M_construct(std::move(__other._M_get())); 144 } 145 146 // Copy constructor is only used to when the contained value is 147 // trivially copy constructible. 148 _Optional_payload_base(const _Optional_payload_base&) = default; 149 150 // Move constructor is only used to when the contained value is 151 // trivially copy constructible. 152 _Optional_payload_base(_Optional_payload_base&&) = default; 153 154 _Optional_payload_base& 155 operator=(const _Optional_payload_base&) = default; 156 157 _Optional_payload_base& 158 operator=(_Optional_payload_base&&) = default; 159 160 // used to perform non-trivial copy assignment. 161 constexpr void 162 _M_copy_assign(const _Optional_payload_base& __other) 163 { 164 if (this->_M_engaged && __other._M_engaged) 165 this->_M_get() = __other._M_get(); 166 else 167 { 168 if (__other._M_engaged) 169 this->_M_construct(__other._M_get()); 170 else 171 this->_M_reset(); 172 } 173 } 174 175 // used to perform non-trivial move assignment. 176 constexpr void 177 _M_move_assign(_Optional_payload_base&& __other) 178 noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 179 is_nothrow_move_assignable<_Tp>>) 180 { 181 if (this->_M_engaged && __other._M_engaged) 182 this->_M_get() = std::move(__other._M_get()); 183 else 184 { 185 if (__other._M_engaged) 186 this->_M_construct(std::move(__other._M_get())); 187 else 188 this->_M_reset(); 189 } 190 } 191 192 struct _Empty_byte { }; 193 194 template<typename _Up, bool = is_trivially_destructible_v<_Up>> 195 union _Storage 196 { 197 constexpr _Storage() noexcept : _M_empty() { } 198 199 template<typename... _Args> 200 constexpr 201 _Storage(in_place_t, _Args&&... __args) 202 : _M_value(std::forward<_Args>(__args)...) 203 { } 204 205 template<typename _Vp, typename... _Args> 206 constexpr 207 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args) 208 : _M_value(__il, std::forward<_Args>(__args)...) 209 { } 210 211 _Empty_byte _M_empty; 212 _Up _M_value; 213 }; 214 215 template<typename _Up> 216 union _Storage<_Up, false> 217 { 218 constexpr _Storage() noexcept : _M_empty() { } 219 220 template<typename... _Args> 221 constexpr 222 _Storage(in_place_t, _Args&&... __args) 223 : _M_value(std::forward<_Args>(__args)...) 224 { } 225 226 template<typename _Vp, typename... _Args> 227 constexpr 228 _Storage(std::initializer_list<_Vp> __il, _Args&&... __args) 229 : _M_value(__il, std::forward<_Args>(__args)...) 230 { } 231 232 // User-provided destructor is needed when _Up has non-trivial dtor. 233 ~_Storage() { } 234 235 _Empty_byte _M_empty; 236 _Up _M_value; 237 }; 238 239 _Storage<_Stored_type> _M_payload; 240 241 bool _M_engaged = false; 242 243 template<typename... _Args> 244 void 245 _M_construct(_Args&&... __args) 246 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>) 247 { 248 ::new ((void *) std::__addressof(this->_M_payload)) 249 _Stored_type(std::forward<_Args>(__args)...); 250 this->_M_engaged = true; 251 } 252 253 constexpr void 254 _M_destroy() noexcept 255 { 256 _M_engaged = false; 257 _M_payload._M_value.~_Stored_type(); 258 } 259 260 // The _M_get() operations have _M_engaged as a precondition. 261 // They exist to access the contained value with the appropriate 262 // const-qualification, because _M_payload has had the const removed. 263 264 constexpr _Tp& 265 _M_get() noexcept 266 { return this->_M_payload._M_value; } 267 268 constexpr const _Tp& 269 _M_get() const noexcept 270 { return this->_M_payload._M_value; } 271 272 // _M_reset is a 'safe' operation with no precondition. 273 constexpr void 274 _M_reset() noexcept 275 { 276 if (this->_M_engaged) 277 _M_destroy(); 278 } 279 }; 280 281 // Class template that manages the payload for optionals. 282 template <typename _Tp, 283 bool /*_HasTrivialDestructor*/ = 284 is_trivially_destructible_v<_Tp>, 285 bool /*_HasTrivialCopy */ = 286 is_trivially_copy_assignable_v<_Tp> 287 && is_trivially_copy_constructible_v<_Tp>, 288 bool /*_HasTrivialMove */ = 289 is_trivially_move_assignable_v<_Tp> 290 && is_trivially_move_constructible_v<_Tp>> 291 struct _Optional_payload; 292 293 // Payload for potentially-constexpr optionals (trivial copy/move/destroy). 294 template <typename _Tp> 295 struct _Optional_payload<_Tp, true, true, true> 296 : _Optional_payload_base<_Tp> 297 { 298 using _Optional_payload_base<_Tp>::_Optional_payload_base; 299 300 _Optional_payload() = default; 301 }; 302 303 // Payload for optionals with non-trivial copy construction/assignment. 304 template <typename _Tp> 305 struct _Optional_payload<_Tp, true, false, true> 306 : _Optional_payload_base<_Tp> 307 { 308 using _Optional_payload_base<_Tp>::_Optional_payload_base; 309 310 _Optional_payload() = default; 311 ~_Optional_payload() = default; 312 _Optional_payload(const _Optional_payload&) = default; 313 _Optional_payload(_Optional_payload&&) = default; 314 _Optional_payload& operator=(_Optional_payload&&) = default; 315 316 // Non-trivial copy assignment. 317 constexpr 318 _Optional_payload& 319 operator=(const _Optional_payload& __other) 320 { 321 this->_M_copy_assign(__other); 322 return *this; 323 } 324 }; 325 326 // Payload for optionals with non-trivial move construction/assignment. 327 template <typename _Tp> 328 struct _Optional_payload<_Tp, true, true, false> 329 : _Optional_payload_base<_Tp> 330 { 331 using _Optional_payload_base<_Tp>::_Optional_payload_base; 332 333 _Optional_payload() = default; 334 ~_Optional_payload() = default; 335 _Optional_payload(const _Optional_payload&) = default; 336 _Optional_payload(_Optional_payload&&) = default; 337 _Optional_payload& operator=(const _Optional_payload&) = default; 338 339 // Non-trivial move assignment. 340 constexpr 341 _Optional_payload& 342 operator=(_Optional_payload&& __other) 343 noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 344 is_nothrow_move_assignable<_Tp>>) 345 { 346 this->_M_move_assign(std::move(__other)); 347 return *this; 348 } 349 }; 350 351 // Payload for optionals with non-trivial copy and move assignment. 352 template <typename _Tp> 353 struct _Optional_payload<_Tp, true, false, false> 354 : _Optional_payload_base<_Tp> 355 { 356 using _Optional_payload_base<_Tp>::_Optional_payload_base; 357 358 _Optional_payload() = default; 359 ~_Optional_payload() = default; 360 _Optional_payload(const _Optional_payload&) = default; 361 _Optional_payload(_Optional_payload&&) = default; 362 363 // Non-trivial copy assignment. 364 constexpr 365 _Optional_payload& 366 operator=(const _Optional_payload& __other) 367 { 368 this->_M_copy_assign(__other); 369 return *this; 370 } 371 372 // Non-trivial move assignment. 373 constexpr 374 _Optional_payload& 375 operator=(_Optional_payload&& __other) 376 noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 377 is_nothrow_move_assignable<_Tp>>) 378 { 379 this->_M_move_assign(std::move(__other)); 380 return *this; 381 } 382 }; 383 384 // Payload for optionals with non-trivial destructors. 385 template <typename _Tp, bool _Copy, bool _Move> 386 struct _Optional_payload<_Tp, false, _Copy, _Move> 387 : _Optional_payload<_Tp, true, false, false> 388 { 389 // Base class implements all the constructors and assignment operators: 390 using _Optional_payload<_Tp, true, false, false>::_Optional_payload; 391 _Optional_payload() = default; 392 _Optional_payload(const _Optional_payload&) = default; 393 _Optional_payload(_Optional_payload&&) = default; 394 _Optional_payload& operator=(const _Optional_payload&) = default; 395 _Optional_payload& operator=(_Optional_payload&&) = default; 396 397 // Destructor needs to destroy the contained value: 398 ~_Optional_payload() { this->_M_reset(); } 399 }; 400 401 // Common base class for _Optional_base<T> to avoid repeating these 402 // member functions in each specialization. 403 template<typename _Tp, typename _Dp> 404 class _Optional_base_impl 405 { 406 protected: 407 using _Stored_type = remove_const_t<_Tp>; 408 409 // The _M_construct operation has !_M_engaged as a precondition 410 // while _M_destruct has _M_engaged as a precondition. 411 template<typename... _Args> 412 void 413 _M_construct(_Args&&... __args) 414 noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>) 415 { 416 ::new 417 (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload)) 418 _Stored_type(std::forward<_Args>(__args)...); 419 static_cast<_Dp*>(this)->_M_payload._M_engaged = true; 420 } 421 422 void 423 _M_destruct() noexcept 424 { static_cast<_Dp*>(this)->_M_payload._M_destroy(); } 425 426 // _M_reset is a 'safe' operation with no precondition. 427 constexpr void 428 _M_reset() noexcept 429 { static_cast<_Dp*>(this)->_M_payload._M_reset(); } 430 431 constexpr bool _M_is_engaged() const noexcept 432 { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; } 433 434 // The _M_get operations have _M_engaged as a precondition. 435 constexpr _Tp& 436 _M_get() noexcept 437 { 438 __glibcxx_assert(this->_M_is_engaged()); 439 return static_cast<_Dp*>(this)->_M_payload._M_get(); 440 } 441 442 constexpr const _Tp& 443 _M_get() const noexcept 444 { 445 __glibcxx_assert(this->_M_is_engaged()); 446 return static_cast<const _Dp*>(this)->_M_payload._M_get(); 447 } 448 }; 449 450 /** 451 * @brief Class template that provides copy/move constructors of optional. 452 * 453 * Such a separate base class template is necessary in order to 454 * conditionally make copy/move constructors trivial. 455 * 456 * When the contained value is trivally copy/move constructible, 457 * the copy/move constructors of _Optional_base will invoke the 458 * trivial copy/move constructor of _Optional_payload. Otherwise, 459 * they will invoke _Optional_payload(bool, const _Optional_payload&) 460 * or _Optional_payload(bool, _Optional_payload&&) to initialize 461 * the contained value, if copying/moving an engaged optional. 462 * 463 * Whether the other special members are trivial is determined by the 464 * _Optional_payload<_Tp> specialization used for the _M_payload member. 465 * 466 * @see optional, _Enable_special_members 467 */ 468 template<typename _Tp, 469 bool = is_trivially_copy_constructible_v<_Tp>, 470 bool = is_trivially_move_constructible_v<_Tp>> 471 struct _Optional_base 472 : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 473 { 474 // Constructors for disengaged optionals. 475 constexpr _Optional_base() = default; 476 477 // Constructors for engaged optionals. 478 template<typename... _Args, 479 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> 480 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 481 : _M_payload(in_place, 482 std::forward<_Args>(__args)...) { } 483 484 template<typename _Up, typename... _Args, 485 enable_if_t<is_constructible_v<_Tp, 486 initializer_list<_Up>&, 487 _Args&&...>, bool> = false> 488 constexpr explicit _Optional_base(in_place_t, 489 initializer_list<_Up> __il, 490 _Args&&... __args) 491 : _M_payload(in_place, 492 __il, std::forward<_Args>(__args)...) 493 { } 494 495 // Copy and move constructors. 496 constexpr _Optional_base(const _Optional_base& __other) 497 : _M_payload(__other._M_payload._M_engaged, 498 __other._M_payload) 499 { } 500 501 constexpr _Optional_base(_Optional_base&& __other) 502 noexcept(is_nothrow_move_constructible_v<_Tp>) 503 : _M_payload(__other._M_payload._M_engaged, 504 std::move(__other._M_payload)) 505 { } 506 507 // Assignment operators. 508 _Optional_base& operator=(const _Optional_base&) = default; 509 _Optional_base& operator=(_Optional_base&&) = default; 510 511 _Optional_payload<_Tp> _M_payload; 512 }; 513 514 template<typename _Tp> 515 struct _Optional_base<_Tp, false, true> 516 : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 517 { 518 // Constructors for disengaged optionals. 519 constexpr _Optional_base() = default; 520 521 // Constructors for engaged optionals. 522 template<typename... _Args, 523 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> 524 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 525 : _M_payload(in_place, 526 std::forward<_Args>(__args)...) { } 527 528 template<typename _Up, typename... _Args, 529 enable_if_t<is_constructible_v<_Tp, 530 initializer_list<_Up>&, 531 _Args&&...>, bool> = false> 532 constexpr explicit _Optional_base(in_place_t, 533 initializer_list<_Up> __il, 534 _Args&&... __args) 535 : _M_payload(in_place, 536 __il, std::forward<_Args>(__args)...) 537 { } 538 539 // Copy and move constructors. 540 constexpr _Optional_base(const _Optional_base& __other) 541 : _M_payload(__other._M_payload._M_engaged, 542 __other._M_payload) 543 { } 544 545 constexpr _Optional_base(_Optional_base&& __other) = default; 546 547 // Assignment operators. 548 _Optional_base& operator=(const _Optional_base&) = default; 549 _Optional_base& operator=(_Optional_base&&) = default; 550 551 _Optional_payload<_Tp> _M_payload; 552 }; 553 554 template<typename _Tp> 555 struct _Optional_base<_Tp, true, false> 556 : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 557 { 558 // Constructors for disengaged optionals. 559 constexpr _Optional_base() = default; 560 561 // Constructors for engaged optionals. 562 template<typename... _Args, 563 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> 564 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 565 : _M_payload(in_place, 566 std::forward<_Args>(__args)...) { } 567 568 template<typename _Up, typename... _Args, 569 enable_if_t<is_constructible_v<_Tp, 570 initializer_list<_Up>&, 571 _Args&&...>, bool> = false> 572 constexpr explicit _Optional_base(in_place_t, 573 initializer_list<_Up> __il, 574 _Args&&... __args) 575 : _M_payload(in_place, 576 __il, std::forward<_Args>(__args)...) 577 { } 578 579 // Copy and move constructors. 580 constexpr _Optional_base(const _Optional_base& __other) = default; 581 582 constexpr _Optional_base(_Optional_base&& __other) 583 noexcept(is_nothrow_move_constructible_v<_Tp>) 584 : _M_payload(__other._M_payload._M_engaged, 585 std::move(__other._M_payload)) 586 { } 587 588 // Assignment operators. 589 _Optional_base& operator=(const _Optional_base&) = default; 590 _Optional_base& operator=(_Optional_base&&) = default; 591 592 _Optional_payload<_Tp> _M_payload; 593 }; 594 595 template<typename _Tp> 596 struct _Optional_base<_Tp, true, true> 597 : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 598 { 599 // Constructors for disengaged optionals. 600 constexpr _Optional_base() = default; 601 602 // Constructors for engaged optionals. 603 template<typename... _Args, 604 enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false> 605 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 606 : _M_payload(in_place, 607 std::forward<_Args>(__args)...) { } 608 609 template<typename _Up, typename... _Args, 610 enable_if_t<is_constructible_v<_Tp, 611 initializer_list<_Up>&, 612 _Args&&...>, bool> = false> 613 constexpr explicit _Optional_base(in_place_t, 614 initializer_list<_Up> __il, 615 _Args&&... __args) 616 : _M_payload(in_place, 617 __il, std::forward<_Args>(__args)...) 618 { } 619 620 // Copy and move constructors. 621 constexpr _Optional_base(const _Optional_base& __other) = default; 622 constexpr _Optional_base(_Optional_base&& __other) = default; 623 624 // Assignment operators. 625 _Optional_base& operator=(const _Optional_base&) = default; 626 _Optional_base& operator=(_Optional_base&&) = default; 627 628 _Optional_payload<_Tp> _M_payload; 629 }; 630 631 template<typename _Tp> 632 class optional; 633 634 template<typename _Tp, typename _Up> 635 using __converts_from_optional = 636 __or_<is_constructible<_Tp, const optional<_Up>&>, 637 is_constructible<_Tp, optional<_Up>&>, 638 is_constructible<_Tp, const optional<_Up>&&>, 639 is_constructible<_Tp, optional<_Up>&&>, 640 is_convertible<const optional<_Up>&, _Tp>, 641 is_convertible<optional<_Up>&, _Tp>, 642 is_convertible<const optional<_Up>&&, _Tp>, 643 is_convertible<optional<_Up>&&, _Tp>>; 644 645 template<typename _Tp, typename _Up> 646 using __assigns_from_optional = 647 __or_<is_assignable<_Tp&, const optional<_Up>&>, 648 is_assignable<_Tp&, optional<_Up>&>, 649 is_assignable<_Tp&, const optional<_Up>&&>, 650 is_assignable<_Tp&, optional<_Up>&&>>; 651 652 /** 653 * @brief Class template for optional values. 654 */ 655 template<typename _Tp> 656 class optional 657 : private _Optional_base<_Tp>, 658 private _Enable_copy_move< 659 // Copy constructor. 660 is_copy_constructible_v<_Tp>, 661 // Copy assignment. 662 __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>, 663 // Move constructor. 664 is_move_constructible_v<_Tp>, 665 // Move assignment. 666 __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>, 667 // Unique tag type. 668 optional<_Tp>> 669 { 670 static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>); 671 static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>); 672 static_assert(!is_reference_v<_Tp>); 673 674 private: 675 using _Base = _Optional_base<_Tp>; 676 677 // SFINAE helpers 678 template<typename _Up> 679 using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>; 680 template<typename _Up> 681 using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>; 682 template<typename... _Cond> 683 using _Requires = enable_if_t<__and_v<_Cond...>, bool>; 684 685 public: 686 using value_type = _Tp; 687 688 constexpr optional() = default; 689 690 constexpr optional(nullopt_t) noexcept { } 691 692 // Converting constructors for engaged optionals. 693 template<typename _Up = _Tp, 694 _Requires<__not_self<_Up>, __not_tag<_Up>, 695 is_constructible<_Tp, _Up&&>, 696 is_convertible<_Up&&, _Tp>> = true> 697 constexpr 698 optional(_Up&& __t) 699 : _Base(std::in_place, std::forward<_Up>(__t)) { } 700 701 template<typename _Up = _Tp, 702 _Requires<__not_self<_Up>, __not_tag<_Up>, 703 is_constructible<_Tp, _Up&&>, 704 __not_<is_convertible<_Up&&, _Tp>>> = false> 705 explicit constexpr 706 optional(_Up&& __t) 707 : _Base(std::in_place, std::forward<_Up>(__t)) { } 708 709 template<typename _Up, 710 _Requires<__not_<is_same<_Tp, _Up>>, 711 is_constructible<_Tp, const _Up&>, 712 is_convertible<const _Up&, _Tp>, 713 __not_<__converts_from_optional<_Tp, _Up>>> = true> 714 constexpr 715 optional(const optional<_Up>& __t) 716 { 717 if (__t) 718 emplace(*__t); 719 } 720 721 template<typename _Up, 722 _Requires<__not_<is_same<_Tp, _Up>>, 723 is_constructible<_Tp, const _Up&>, 724 __not_<is_convertible<const _Up&, _Tp>>, 725 __not_<__converts_from_optional<_Tp, _Up>>> = false> 726 explicit constexpr 727 optional(const optional<_Up>& __t) 728 { 729 if (__t) 730 emplace(*__t); 731 } 732 733 template <typename _Up, 734 _Requires<__not_<is_same<_Tp, _Up>>, 735 is_constructible<_Tp, _Up&&>, 736 is_convertible<_Up&&, _Tp>, 737 __not_<__converts_from_optional<_Tp, _Up>>> = true> 738 constexpr 739 optional(optional<_Up>&& __t) 740 { 741 if (__t) 742 emplace(std::move(*__t)); 743 } 744 745 template <typename _Up, 746 _Requires<__not_<is_same<_Tp, _Up>>, 747 is_constructible<_Tp, _Up&&>, 748 __not_<is_convertible<_Up&&, _Tp>>, 749 __not_<__converts_from_optional<_Tp, _Up>>> = false> 750 explicit constexpr 751 optional(optional<_Up>&& __t) 752 { 753 if (__t) 754 emplace(std::move(*__t)); 755 } 756 757 template<typename... _Args, 758 _Requires<is_constructible<_Tp, _Args&&...>> = false> 759 explicit constexpr 760 optional(in_place_t, _Args&&... __args) 761 : _Base(std::in_place, std::forward<_Args>(__args)...) { } 762 763 template<typename _Up, typename... _Args, 764 _Requires<is_constructible<_Tp, 765 initializer_list<_Up>&, 766 _Args&&...>> = false> 767 explicit constexpr 768 optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 769 : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { } 770 771 // Assignment operators. 772 optional& 773 operator=(nullopt_t) noexcept 774 { 775 this->_M_reset(); 776 return *this; 777 } 778 779 template<typename _Up = _Tp> 780 enable_if_t<__and_v<__not_self<_Up>, 781 __not_<__and_<is_scalar<_Tp>, 782 is_same<_Tp, decay_t<_Up>>>>, 783 is_constructible<_Tp, _Up>, 784 is_assignable<_Tp&, _Up>>, 785 optional&> 786 operator=(_Up&& __u) 787 { 788 if (this->_M_is_engaged()) 789 this->_M_get() = std::forward<_Up>(__u); 790 else 791 this->_M_construct(std::forward<_Up>(__u)); 792 793 return *this; 794 } 795 796 template<typename _Up> 797 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>, 798 is_constructible<_Tp, const _Up&>, 799 is_assignable<_Tp&, const _Up&>, 800 __not_<__converts_from_optional<_Tp, _Up>>, 801 __not_<__assigns_from_optional<_Tp, _Up>>>, 802 optional&> 803 operator=(const optional<_Up>& __u) 804 { 805 if (__u) 806 { 807 if (this->_M_is_engaged()) 808 this->_M_get() = *__u; 809 else 810 this->_M_construct(*__u); 811 } 812 else 813 { 814 this->_M_reset(); 815 } 816 return *this; 817 } 818 819 template<typename _Up> 820 enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>, 821 is_constructible<_Tp, _Up>, 822 is_assignable<_Tp&, _Up>, 823 __not_<__converts_from_optional<_Tp, _Up>>, 824 __not_<__assigns_from_optional<_Tp, _Up>>>, 825 optional&> 826 operator=(optional<_Up>&& __u) 827 { 828 if (__u) 829 { 830 if (this->_M_is_engaged()) 831 this->_M_get() = std::move(*__u); 832 else 833 this->_M_construct(std::move(*__u)); 834 } 835 else 836 { 837 this->_M_reset(); 838 } 839 840 return *this; 841 } 842 843 template<typename... _Args> 844 enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&> 845 emplace(_Args&&... __args) 846 { 847 this->_M_reset(); 848 this->_M_construct(std::forward<_Args>(__args)...); 849 return this->_M_get(); 850 } 851 852 template<typename _Up, typename... _Args> 853 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, 854 _Args&&...>, _Tp&> 855 emplace(initializer_list<_Up> __il, _Args&&... __args) 856 { 857 this->_M_reset(); 858 this->_M_construct(__il, std::forward<_Args>(__args)...); 859 return this->_M_get(); 860 } 861 862 // Destructor is implicit, implemented in _Optional_base. 863 864 // Swap. 865 void 866 swap(optional& __other) 867 noexcept(is_nothrow_move_constructible_v<_Tp> 868 && is_nothrow_swappable_v<_Tp>) 869 { 870 using std::swap; 871 872 if (this->_M_is_engaged() && __other._M_is_engaged()) 873 swap(this->_M_get(), __other._M_get()); 874 else if (this->_M_is_engaged()) 875 { 876 __other._M_construct(std::move(this->_M_get())); 877 this->_M_destruct(); 878 } 879 else if (__other._M_is_engaged()) 880 { 881 this->_M_construct(std::move(__other._M_get())); 882 __other._M_destruct(); 883 } 884 } 885 886 // Observers. 887 constexpr const _Tp* 888 operator->() const 889 { return std::__addressof(this->_M_get()); } 890 891 constexpr 892 _Tp* 893 operator->() 894 { return std::__addressof(this->_M_get()); } 895 896 constexpr const _Tp& 897 operator*() const& 898 { return this->_M_get(); } 899 900 constexpr _Tp& 901 operator*()& 902 { return this->_M_get(); } 903 904 constexpr _Tp&& 905 operator*()&& 906 { return std::move(this->_M_get()); } 907 908 constexpr const _Tp&& 909 operator*() const&& 910 { return std::move(this->_M_get()); } 911 912 constexpr explicit operator bool() const noexcept 913 { return this->_M_is_engaged(); } 914 915 constexpr bool has_value() const noexcept 916 { return this->_M_is_engaged(); } 917 918 constexpr const _Tp& 919 value() const& 920 { 921 return this->_M_is_engaged() 922 ? this->_M_get() 923 : (__throw_bad_optional_access(), this->_M_get()); 924 } 925 926 constexpr _Tp& 927 value()& 928 { 929 return this->_M_is_engaged() 930 ? this->_M_get() 931 : (__throw_bad_optional_access(), this->_M_get()); 932 } 933 934 constexpr _Tp&& 935 value()&& 936 { 937 return this->_M_is_engaged() 938 ? std::move(this->_M_get()) 939 : (__throw_bad_optional_access(), std::move(this->_M_get())); 940 } 941 942 constexpr const _Tp&& 943 value() const&& 944 { 945 return this->_M_is_engaged() 946 ? std::move(this->_M_get()) 947 : (__throw_bad_optional_access(), std::move(this->_M_get())); 948 } 949 950 template<typename _Up> 951 constexpr _Tp 952 value_or(_Up&& __u) const& 953 { 954 static_assert(is_copy_constructible_v<_Tp>); 955 static_assert(is_convertible_v<_Up&&, _Tp>); 956 957 return this->_M_is_engaged() 958 ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u)); 959 } 960 961 template<typename _Up> 962 constexpr _Tp 963 value_or(_Up&& __u) && 964 { 965 static_assert(is_move_constructible_v<_Tp>); 966 static_assert(is_convertible_v<_Up&&, _Tp>); 967 968 return this->_M_is_engaged() 969 ? std::move(this->_M_get()) 970 : static_cast<_Tp>(std::forward<_Up>(__u)); 971 } 972 973 void reset() noexcept { this->_M_reset(); } 974 }; 975 976 template<typename _Tp> 977 using __optional_relop_t = 978 enable_if_t<is_convertible<_Tp, bool>::value, bool>; 979 980 // Comparisons between optional values. 981 template<typename _Tp, typename _Up> 982 constexpr auto 983 operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 984 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())> 985 { 986 return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) 987 && (!__lhs || *__lhs == *__rhs); 988 } 989 990 template<typename _Tp, typename _Up> 991 constexpr auto 992 operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 993 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())> 994 { 995 return static_cast<bool>(__lhs) != static_cast<bool>(__rhs) 996 || (static_cast<bool>(__lhs) && *__lhs != *__rhs); 997 } 998 999 template<typename _Tp, typename _Up> 1000 constexpr auto 1001 operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1002 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())> 1003 { 1004 return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs); 1005 } 1006 1007 template<typename _Tp, typename _Up> 1008 constexpr auto 1009 operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1010 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())> 1011 { 1012 return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs); 1013 } 1014 1015 template<typename _Tp, typename _Up> 1016 constexpr auto 1017 operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1018 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())> 1019 { 1020 return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs); 1021 } 1022 1023 template<typename _Tp, typename _Up> 1024 constexpr auto 1025 operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1026 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())> 1027 { 1028 return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs); 1029 } 1030 1031 // Comparisons with nullopt. 1032 template<typename _Tp> 1033 constexpr bool 1034 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept 1035 { return !__lhs; } 1036 1037 template<typename _Tp> 1038 constexpr bool 1039 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept 1040 { return !__rhs; } 1041 1042 template<typename _Tp> 1043 constexpr bool 1044 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept 1045 { return static_cast<bool>(__lhs); } 1046 1047 template<typename _Tp> 1048 constexpr bool 1049 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept 1050 { return static_cast<bool>(__rhs); } 1051 1052 template<typename _Tp> 1053 constexpr bool 1054 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 1055 { return false; } 1056 1057 template<typename _Tp> 1058 constexpr bool 1059 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept 1060 { return static_cast<bool>(__rhs); } 1061 1062 template<typename _Tp> 1063 constexpr bool 1064 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept 1065 { return static_cast<bool>(__lhs); } 1066 1067 template<typename _Tp> 1068 constexpr bool 1069 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 1070 { return false; } 1071 1072 template<typename _Tp> 1073 constexpr bool 1074 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept 1075 { return !__lhs; } 1076 1077 template<typename _Tp> 1078 constexpr bool 1079 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 1080 { return true; } 1081 1082 template<typename _Tp> 1083 constexpr bool 1084 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 1085 { return true; } 1086 1087 template<typename _Tp> 1088 constexpr bool 1089 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept 1090 { return !__rhs; } 1091 1092 // Comparisons with value type. 1093 template<typename _Tp, typename _Up> 1094 constexpr auto 1095 operator==(const optional<_Tp>& __lhs, const _Up& __rhs) 1096 -> __optional_relop_t<decltype(declval<_Tp>() == declval<_Up>())> 1097 { return __lhs && *__lhs == __rhs; } 1098 1099 template<typename _Tp, typename _Up> 1100 constexpr auto 1101 operator==(const _Up& __lhs, const optional<_Tp>& __rhs) 1102 -> __optional_relop_t<decltype(declval<_Up>() == declval<_Tp>())> 1103 { return __rhs && __lhs == *__rhs; } 1104 1105 template<typename _Tp, typename _Up> 1106 constexpr auto 1107 operator!=(const optional<_Tp>& __lhs, const _Up& __rhs) 1108 -> __optional_relop_t<decltype(declval<_Tp>() != declval<_Up>())> 1109 { return !__lhs || *__lhs != __rhs; } 1110 1111 template<typename _Tp, typename _Up> 1112 constexpr auto 1113 operator!=(const _Up& __lhs, const optional<_Tp>& __rhs) 1114 -> __optional_relop_t<decltype(declval<_Up>() != declval<_Tp>())> 1115 { return !__rhs || __lhs != *__rhs; } 1116 1117 template<typename _Tp, typename _Up> 1118 constexpr auto 1119 operator<(const optional<_Tp>& __lhs, const _Up& __rhs) 1120 -> __optional_relop_t<decltype(declval<_Tp>() < declval<_Up>())> 1121 { return !__lhs || *__lhs < __rhs; } 1122 1123 template<typename _Tp, typename _Up> 1124 constexpr auto 1125 operator<(const _Up& __lhs, const optional<_Tp>& __rhs) 1126 -> __optional_relop_t<decltype(declval<_Up>() < declval<_Tp>())> 1127 { return __rhs && __lhs < *__rhs; } 1128 1129 template<typename _Tp, typename _Up> 1130 constexpr auto 1131 operator>(const optional<_Tp>& __lhs, const _Up& __rhs) 1132 -> __optional_relop_t<decltype(declval<_Tp>() > declval<_Up>())> 1133 { return __lhs && *__lhs > __rhs; } 1134 1135 template<typename _Tp, typename _Up> 1136 constexpr auto 1137 operator>(const _Up& __lhs, const optional<_Tp>& __rhs) 1138 -> __optional_relop_t<decltype(declval<_Up>() > declval<_Tp>())> 1139 { return !__rhs || __lhs > *__rhs; } 1140 1141 template<typename _Tp, typename _Up> 1142 constexpr auto 1143 operator<=(const optional<_Tp>& __lhs, const _Up& __rhs) 1144 -> __optional_relop_t<decltype(declval<_Tp>() <= declval<_Up>())> 1145 { return !__lhs || *__lhs <= __rhs; } 1146 1147 template<typename _Tp, typename _Up> 1148 constexpr auto 1149 operator<=(const _Up& __lhs, const optional<_Tp>& __rhs) 1150 -> __optional_relop_t<decltype(declval<_Up>() <= declval<_Tp>())> 1151 { return __rhs && __lhs <= *__rhs; } 1152 1153 template<typename _Tp, typename _Up> 1154 constexpr auto 1155 operator>=(const optional<_Tp>& __lhs, const _Up& __rhs) 1156 -> __optional_relop_t<decltype(declval<_Tp>() >= declval<_Up>())> 1157 { return __lhs && *__lhs >= __rhs; } 1158 1159 template<typename _Tp, typename _Up> 1160 constexpr auto 1161 operator>=(const _Up& __lhs, const optional<_Tp>& __rhs) 1162 -> __optional_relop_t<decltype(declval<_Up>() >= declval<_Tp>())> 1163 { return !__rhs || __lhs >= *__rhs; } 1164 1165 // Swap and creation functions. 1166 1167 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1168 // 2748. swappable traits for optionals 1169 template<typename _Tp> 1170 inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>> 1171 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) 1172 noexcept(noexcept(__lhs.swap(__rhs))) 1173 { __lhs.swap(__rhs); } 1174 1175 template<typename _Tp> 1176 enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)> 1177 swap(optional<_Tp>&, optional<_Tp>&) = delete; 1178 1179 template<typename _Tp> 1180 constexpr optional<decay_t<_Tp>> 1181 make_optional(_Tp&& __t) 1182 { return optional<decay_t<_Tp>> { std::forward<_Tp>(__t) }; } 1183 1184 template<typename _Tp, typename ..._Args> 1185 constexpr optional<_Tp> 1186 make_optional(_Args&&... __args) 1187 { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; } 1188 1189 template<typename _Tp, typename _Up, typename ..._Args> 1190 constexpr optional<_Tp> 1191 make_optional(initializer_list<_Up> __il, _Args&&... __args) 1192 { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; } 1193 1194 // Hash. 1195 1196 template<typename _Tp, typename _Up = remove_const_t<_Tp>, 1197 bool = __poison_hash<_Up>::__enable_hash_call> 1198 struct __optional_hash_call_base 1199 { 1200 size_t 1201 operator()(const optional<_Tp>& __t) const 1202 noexcept(noexcept(hash<_Up>{}(*__t))) 1203 { 1204 // We pick an arbitrary hash for disengaged optionals which hopefully 1205 // usual values of _Tp won't typically hash to. 1206 constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333); 1207 return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash; 1208 } 1209 }; 1210 1211 template<typename _Tp, typename _Up> 1212 struct __optional_hash_call_base<_Tp, _Up, false> {}; 1213 1214 template<typename _Tp> 1215 struct hash<optional<_Tp>> 1216 : private __poison_hash<remove_const_t<_Tp>>, 1217 public __optional_hash_call_base<_Tp> 1218 { 1219 using result_type [[__deprecated__]] = size_t; 1220 using argument_type [[__deprecated__]] = optional<_Tp>; 1221 }; 1222 1223 template<typename _Tp> 1224 struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>> 1225 { }; 1226 1227 /// @} 1228 1229#if __cpp_deduction_guides >= 201606 1230 template <typename _Tp> optional(_Tp) -> optional<_Tp>; 1231#endif 1232 1233_GLIBCXX_END_NAMESPACE_VERSION 1234} // namespace std 1235 1236#endif // C++17 1237 1238#endif // _GLIBCXX_OPTIONAL 1239