1 // unique_ptr implementation -*- C++ -*- 2 3 // Copyright (C) 2008-2022 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 bits/unique_ptr.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{memory} 28 */ 29 30 #ifndef _UNIQUE_PTR_H 31 #define _UNIQUE_PTR_H 1 32 33 #include <bits/c++config.h> 34 #include <debug/assertions.h> 35 #include <type_traits> 36 #include <tuple> 37 #include <bits/stl_function.h> 38 #include <bits/functional_hash.h> 39 #if __cplusplus > 201703L 40 # include <compare> 41 # include <ostream> 42 #endif 43 44 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc 45 # if __cpp_lib_constexpr_memory < 202202L 46 // Defined with older value in bits/ptr_traits.h for C++20 47 # undef __cpp_lib_constexpr_memory 48 # define __cpp_lib_constexpr_memory 202202L 49 # endif 50 #endif 51 52 namespace std _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 /** 57 * @addtogroup pointer_abstractions 58 * @{ 59 */ 60 61 #if _GLIBCXX_USE_DEPRECATED 62 #pragma GCC diagnostic push 63 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 64 template<typename> class auto_ptr; 65 #pragma GCC diagnostic pop 66 #endif 67 68 /** Primary template of default_delete, used by unique_ptr for single objects 69 * 70 * @headerfile memory 71 * @since C++11 72 */ 73 template<typename _Tp> 74 struct default_delete 75 { 76 /// Default constructor 77 constexpr default_delete() noexcept = default; 78 79 /** @brief Converting constructor. 80 * 81 * Allows conversion from a deleter for objects of another type, `_Up`, 82 * only if `_Up*` is convertible to `_Tp*`. 83 */ 84 template<typename _Up, 85 typename = _Require<is_convertible<_Up*, _Tp*>>> 86 _GLIBCXX23_CONSTEXPR 87 default_delete(const default_delete<_Up>&) noexcept { } 88 89 /// Calls `delete __ptr` 90 _GLIBCXX23_CONSTEXPR 91 void 92 operator()(_Tp* __ptr) const 93 { 94 static_assert(!is_void<_Tp>::value, 95 "can't delete pointer to incomplete type"); 96 static_assert(sizeof(_Tp)>0, 97 "can't delete pointer to incomplete type"); 98 delete __ptr; 99 } 100 }; 101 102 // _GLIBCXX_RESOLVE_LIB_DEFECTS 103 // DR 740 - omit specialization for array objects with a compile time length 104 105 /** Specialization of default_delete for arrays, used by `unique_ptr<T[]>` 106 * 107 * @headerfile memory 108 * @since C++11 109 */ 110 template<typename _Tp> 111 struct default_delete<_Tp[]> 112 { 113 public: 114 /// Default constructor 115 constexpr default_delete() noexcept = default; 116 117 /** @brief Converting constructor. 118 * 119 * Allows conversion from a deleter for arrays of another type, such as 120 * a const-qualified version of `_Tp`. 121 * 122 * Conversions from types derived from `_Tp` are not allowed because 123 * it is undefined to `delete[]` an array of derived types through a 124 * pointer to the base type. 125 */ 126 template<typename _Up, 127 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>> 128 _GLIBCXX23_CONSTEXPR 129 default_delete(const default_delete<_Up[]>&) noexcept { } 130 131 /// Calls `delete[] __ptr` 132 template<typename _Up> 133 _GLIBCXX23_CONSTEXPR 134 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type 135 operator()(_Up* __ptr) const 136 { 137 static_assert(sizeof(_Tp)>0, 138 "can't delete pointer to incomplete type"); 139 delete [] __ptr; 140 } 141 }; 142 143 /// @cond undocumented 144 145 // Manages the pointer and deleter of a unique_ptr 146 template <typename _Tp, typename _Dp> 147 class __uniq_ptr_impl 148 { 149 template <typename _Up, typename _Ep, typename = void> 150 struct _Ptr 151 { 152 using type = _Up*; 153 }; 154 155 template <typename _Up, typename _Ep> 156 struct 157 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> 158 { 159 using type = typename remove_reference<_Ep>::type::pointer; 160 }; 161 162 public: 163 using _DeleterConstraint = enable_if< 164 __and_<__not_<is_pointer<_Dp>>, 165 is_default_constructible<_Dp>>::value>; 166 167 using pointer = typename _Ptr<_Tp, _Dp>::type; 168 169 static_assert( !is_rvalue_reference<_Dp>::value, 170 "unique_ptr's deleter type must be a function object type" 171 " or an lvalue reference type" ); 172 173 __uniq_ptr_impl() = default; 174 _GLIBCXX23_CONSTEXPR 175 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; } 176 177 template<typename _Del> 178 _GLIBCXX23_CONSTEXPR 179 __uniq_ptr_impl(pointer __p, _Del&& __d) 180 : _M_t(__p, std::forward<_Del>(__d)) { } 181 182 _GLIBCXX23_CONSTEXPR 183 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept 184 : _M_t(std::move(__u._M_t)) 185 { __u._M_ptr() = nullptr; } 186 187 _GLIBCXX23_CONSTEXPR 188 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept 189 { 190 reset(__u.release()); 191 _M_deleter() = std::forward<_Dp>(__u._M_deleter()); 192 return *this; 193 } 194 195 _GLIBCXX23_CONSTEXPR 196 pointer& _M_ptr() noexcept { return std::get<0>(_M_t); } 197 _GLIBCXX23_CONSTEXPR 198 pointer _M_ptr() const noexcept { return std::get<0>(_M_t); } 199 _GLIBCXX23_CONSTEXPR 200 _Dp& _M_deleter() noexcept { return std::get<1>(_M_t); } 201 _GLIBCXX23_CONSTEXPR 202 const _Dp& _M_deleter() const noexcept { return std::get<1>(_M_t); } 203 204 _GLIBCXX23_CONSTEXPR 205 void reset(pointer __p) noexcept 206 { 207 const pointer __old_p = _M_ptr(); 208 _M_ptr() = __p; 209 if (__old_p) 210 _M_deleter()(__old_p); 211 } 212 213 _GLIBCXX23_CONSTEXPR 214 pointer release() noexcept 215 { 216 pointer __p = _M_ptr(); 217 _M_ptr() = nullptr; 218 return __p; 219 } 220 221 _GLIBCXX23_CONSTEXPR 222 void 223 swap(__uniq_ptr_impl& __rhs) noexcept 224 { 225 using std::swap; 226 swap(this->_M_ptr(), __rhs._M_ptr()); 227 swap(this->_M_deleter(), __rhs._M_deleter()); 228 } 229 230 private: 231 tuple<pointer, _Dp> _M_t; 232 }; 233 234 // Defines move construction + assignment as either defaulted or deleted. 235 template <typename _Tp, typename _Dp, 236 bool = is_move_constructible<_Dp>::value, 237 bool = is_move_assignable<_Dp>::value> 238 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp> 239 { 240 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; 241 __uniq_ptr_data(__uniq_ptr_data&&) = default; 242 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default; 243 }; 244 245 template <typename _Tp, typename _Dp> 246 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp> 247 { 248 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; 249 __uniq_ptr_data(__uniq_ptr_data&&) = default; 250 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete; 251 }; 252 253 template <typename _Tp, typename _Dp> 254 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp> 255 { 256 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; 257 __uniq_ptr_data(__uniq_ptr_data&&) = delete; 258 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default; 259 }; 260 261 template <typename _Tp, typename _Dp> 262 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp> 263 { 264 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; 265 __uniq_ptr_data(__uniq_ptr_data&&) = delete; 266 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete; 267 }; 268 /// @endcond 269 270 // 20.7.1.2 unique_ptr for single objects. 271 272 /// A move-only smart pointer that manages unique ownership of a resource. 273 /// @headerfile memory 274 /// @since C++11 275 template <typename _Tp, typename _Dp = default_delete<_Tp>> 276 class unique_ptr 277 { 278 template <typename _Up> 279 using _DeleterConstraint = 280 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 281 282 __uniq_ptr_data<_Tp, _Dp> _M_t; 283 284 public: 285 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 286 using element_type = _Tp; 287 using deleter_type = _Dp; 288 289 private: 290 // helper template for detecting a safe conversion from another 291 // unique_ptr 292 template<typename _Up, typename _Ep> 293 using __safe_conversion_up = __and_< 294 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 295 __not_<is_array<_Up>> 296 >; 297 298 public: 299 // Constructors. 300 301 /// Default constructor, creates a unique_ptr that owns nothing. 302 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 303 constexpr unique_ptr() noexcept 304 : _M_t() 305 { } 306 307 /** Takes ownership of a pointer. 308 * 309 * @param __p A pointer to an object of @c element_type 310 * 311 * The deleter will be value-initialized. 312 */ 313 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 314 _GLIBCXX23_CONSTEXPR 315 explicit 316 unique_ptr(pointer __p) noexcept 317 : _M_t(__p) 318 { } 319 320 /** Takes ownership of a pointer. 321 * 322 * @param __p A pointer to an object of @c element_type 323 * @param __d A reference to a deleter. 324 * 325 * The deleter will be initialized with @p __d 326 */ 327 template<typename _Del = deleter_type, 328 typename = _Require<is_copy_constructible<_Del>>> 329 _GLIBCXX23_CONSTEXPR 330 unique_ptr(pointer __p, const deleter_type& __d) noexcept 331 : _M_t(__p, __d) { } 332 333 /** Takes ownership of a pointer. 334 * 335 * @param __p A pointer to an object of @c element_type 336 * @param __d An rvalue reference to a (non-reference) deleter. 337 * 338 * The deleter will be initialized with @p std::move(__d) 339 */ 340 template<typename _Del = deleter_type, 341 typename = _Require<is_move_constructible<_Del>>> 342 _GLIBCXX23_CONSTEXPR 343 unique_ptr(pointer __p, 344 __enable_if_t<!is_lvalue_reference<_Del>::value, 345 _Del&&> __d) noexcept 346 : _M_t(__p, std::move(__d)) 347 { } 348 349 template<typename _Del = deleter_type, 350 typename _DelUnref = typename remove_reference<_Del>::type> 351 _GLIBCXX23_CONSTEXPR 352 unique_ptr(pointer, 353 __enable_if_t<is_lvalue_reference<_Del>::value, 354 _DelUnref&&>) = delete; 355 356 /// Creates a unique_ptr that owns nothing. 357 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 358 constexpr unique_ptr(nullptr_t) noexcept 359 : _M_t() 360 { } 361 362 // Move constructors. 363 364 /// Move constructor. 365 unique_ptr(unique_ptr&&) = default; 366 367 /** @brief Converting constructor from another type 368 * 369 * Requires that the pointer owned by @p __u is convertible to the 370 * type of pointer owned by this object, @p __u does not own an array, 371 * and @p __u has a compatible deleter type. 372 */ 373 template<typename _Up, typename _Ep, typename = _Require< 374 __safe_conversion_up<_Up, _Ep>, 375 __conditional_t<is_reference<_Dp>::value, 376 is_same<_Ep, _Dp>, 377 is_convertible<_Ep, _Dp>>>> 378 _GLIBCXX23_CONSTEXPR 379 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 380 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 381 { } 382 383 #if _GLIBCXX_USE_DEPRECATED 384 #pragma GCC diagnostic push 385 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 386 /// Converting constructor from @c auto_ptr 387 template<typename _Up, typename = _Require< 388 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 389 unique_ptr(auto_ptr<_Up>&& __u) noexcept; 390 #pragma GCC diagnostic pop 391 #endif 392 393 /// Destructor, invokes the deleter if the stored pointer is not null. 394 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc 395 constexpr 396 #endif 397 ~unique_ptr() noexcept 398 { 399 static_assert(__is_invocable<deleter_type&, pointer>::value, 400 "unique_ptr's deleter must be invocable with a pointer"); 401 auto& __ptr = _M_t._M_ptr(); 402 if (__ptr != nullptr) 403 get_deleter()(std::move(__ptr)); 404 __ptr = pointer(); 405 } 406 407 // Assignment. 408 409 /** @brief Move assignment operator. 410 * 411 * Invokes the deleter if this object owns a pointer. 412 */ 413 unique_ptr& operator=(unique_ptr&&) = default; 414 415 /** @brief Assignment from another type. 416 * 417 * @param __u The object to transfer ownership from, which owns a 418 * convertible pointer to a non-array object. 419 * 420 * Invokes the deleter if this object owns a pointer. 421 */ 422 template<typename _Up, typename _Ep> 423 _GLIBCXX23_CONSTEXPR 424 typename enable_if< __and_< 425 __safe_conversion_up<_Up, _Ep>, 426 is_assignable<deleter_type&, _Ep&&> 427 >::value, 428 unique_ptr&>::type 429 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 430 { 431 reset(__u.release()); 432 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 433 return *this; 434 } 435 436 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 437 _GLIBCXX23_CONSTEXPR 438 unique_ptr& 439 operator=(nullptr_t) noexcept 440 { 441 reset(); 442 return *this; 443 } 444 445 // Observers. 446 447 /// Dereference the stored pointer. 448 _GLIBCXX23_CONSTEXPR 449 typename add_lvalue_reference<element_type>::type 450 operator*() const noexcept(noexcept(*std::declval<pointer>())) 451 { 452 __glibcxx_assert(get() != pointer()); 453 return *get(); 454 } 455 456 /// Return the stored pointer. 457 _GLIBCXX23_CONSTEXPR 458 pointer 459 operator->() const noexcept 460 { 461 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); 462 return get(); 463 } 464 465 /// Return the stored pointer. 466 _GLIBCXX23_CONSTEXPR 467 pointer 468 get() const noexcept 469 { return _M_t._M_ptr(); } 470 471 /// Return a reference to the stored deleter. 472 _GLIBCXX23_CONSTEXPR 473 deleter_type& 474 get_deleter() noexcept 475 { return _M_t._M_deleter(); } 476 477 /// Return a reference to the stored deleter. 478 _GLIBCXX23_CONSTEXPR 479 const deleter_type& 480 get_deleter() const noexcept 481 { return _M_t._M_deleter(); } 482 483 /// Return @c true if the stored pointer is not null. 484 _GLIBCXX23_CONSTEXPR 485 explicit operator bool() const noexcept 486 { return get() == pointer() ? false : true; } 487 488 // Modifiers. 489 490 /// Release ownership of any stored pointer. 491 _GLIBCXX23_CONSTEXPR 492 pointer 493 release() noexcept 494 { return _M_t.release(); } 495 496 /** @brief Replace the stored pointer. 497 * 498 * @param __p The new pointer to store. 499 * 500 * The deleter will be invoked if a pointer is already owned. 501 */ 502 _GLIBCXX23_CONSTEXPR 503 void 504 reset(pointer __p = pointer()) noexcept 505 { 506 static_assert(__is_invocable<deleter_type&, pointer>::value, 507 "unique_ptr's deleter must be invocable with a pointer"); 508 _M_t.reset(std::move(__p)); 509 } 510 511 /// Exchange the pointer and deleter with another object. 512 _GLIBCXX23_CONSTEXPR 513 void 514 swap(unique_ptr& __u) noexcept 515 { 516 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); 517 _M_t.swap(__u._M_t); 518 } 519 520 // Disable copy from lvalue. 521 unique_ptr(const unique_ptr&) = delete; 522 unique_ptr& operator=(const unique_ptr&) = delete; 523 }; 524 525 // 20.7.1.3 unique_ptr for array objects with a runtime length 526 // [unique.ptr.runtime] 527 // _GLIBCXX_RESOLVE_LIB_DEFECTS 528 // DR 740 - omit specialization for array objects with a compile time length 529 530 /// A move-only smart pointer that manages unique ownership of an array. 531 /// @headerfile memory 532 /// @since C++11 533 template<typename _Tp, typename _Dp> 534 class unique_ptr<_Tp[], _Dp> 535 { 536 template <typename _Up> 537 using _DeleterConstraint = 538 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 539 540 __uniq_ptr_data<_Tp, _Dp> _M_t; 541 542 template<typename _Up> 543 using __remove_cv = typename remove_cv<_Up>::type; 544 545 // like is_base_of<_Tp, _Up> but false if unqualified types are the same 546 template<typename _Up> 547 using __is_derived_Tp 548 = __and_< is_base_of<_Tp, _Up>, 549 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 550 551 public: 552 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 553 using element_type = _Tp; 554 using deleter_type = _Dp; 555 556 // helper template for detecting a safe conversion from another 557 // unique_ptr 558 template<typename _Up, typename _Ep, 559 typename _UPtr = unique_ptr<_Up, _Ep>, 560 typename _UP_pointer = typename _UPtr::pointer, 561 typename _UP_element_type = typename _UPtr::element_type> 562 using __safe_conversion_up = __and_< 563 is_array<_Up>, 564 is_same<pointer, element_type*>, 565 is_same<_UP_pointer, _UP_element_type*>, 566 is_convertible<_UP_element_type(*)[], element_type(*)[]> 567 >; 568 569 // helper template for detecting a safe conversion from a raw pointer 570 template<typename _Up> 571 using __safe_conversion_raw = __and_< 572 __or_<__or_<is_same<_Up, pointer>, 573 is_same<_Up, nullptr_t>>, 574 __and_<is_pointer<_Up>, 575 is_same<pointer, element_type*>, 576 is_convertible< 577 typename remove_pointer<_Up>::type(*)[], 578 element_type(*)[]> 579 > 580 > 581 >; 582 583 // Constructors. 584 585 /// Default constructor, creates a unique_ptr that owns nothing. 586 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 587 constexpr unique_ptr() noexcept 588 : _M_t() 589 { } 590 591 /** Takes ownership of a pointer. 592 * 593 * @param __p A pointer to an array of a type safely convertible 594 * to an array of @c element_type 595 * 596 * The deleter will be value-initialized. 597 */ 598 template<typename _Up, 599 typename _Vp = _Dp, 600 typename = _DeleterConstraint<_Vp>, 601 typename = typename enable_if< 602 __safe_conversion_raw<_Up>::value, bool>::type> 603 _GLIBCXX23_CONSTEXPR 604 explicit 605 unique_ptr(_Up __p) noexcept 606 : _M_t(__p) 607 { } 608 609 /** Takes ownership of a pointer. 610 * 611 * @param __p A pointer to an array of a type safely convertible 612 * to an array of @c element_type 613 * @param __d A reference to a deleter. 614 * 615 * The deleter will be initialized with @p __d 616 */ 617 template<typename _Up, typename _Del = deleter_type, 618 typename = _Require<__safe_conversion_raw<_Up>, 619 is_copy_constructible<_Del>>> 620 _GLIBCXX23_CONSTEXPR 621 unique_ptr(_Up __p, const deleter_type& __d) noexcept 622 : _M_t(__p, __d) { } 623 624 /** Takes ownership of a pointer. 625 * 626 * @param __p A pointer to an array of a type safely convertible 627 * to an array of @c element_type 628 * @param __d A reference to a deleter. 629 * 630 * The deleter will be initialized with @p std::move(__d) 631 */ 632 template<typename _Up, typename _Del = deleter_type, 633 typename = _Require<__safe_conversion_raw<_Up>, 634 is_move_constructible<_Del>>> 635 _GLIBCXX23_CONSTEXPR 636 unique_ptr(_Up __p, 637 __enable_if_t<!is_lvalue_reference<_Del>::value, 638 _Del&&> __d) noexcept 639 : _M_t(std::move(__p), std::move(__d)) 640 { } 641 642 template<typename _Up, typename _Del = deleter_type, 643 typename _DelUnref = typename remove_reference<_Del>::type, 644 typename = _Require<__safe_conversion_raw<_Up>>> 645 unique_ptr(_Up, 646 __enable_if_t<is_lvalue_reference<_Del>::value, 647 _DelUnref&&>) = delete; 648 649 /// Move constructor. 650 unique_ptr(unique_ptr&&) = default; 651 652 /// Creates a unique_ptr that owns nothing. 653 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 654 constexpr unique_ptr(nullptr_t) noexcept 655 : _M_t() 656 { } 657 658 template<typename _Up, typename _Ep, typename = _Require< 659 __safe_conversion_up<_Up, _Ep>, 660 __conditional_t<is_reference<_Dp>::value, 661 is_same<_Ep, _Dp>, 662 is_convertible<_Ep, _Dp>>>> 663 _GLIBCXX23_CONSTEXPR 664 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 665 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 666 { } 667 668 /// Destructor, invokes the deleter if the stored pointer is not null. 669 #if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc 670 constexpr 671 #endif 672 ~unique_ptr() 673 { 674 auto& __ptr = _M_t._M_ptr(); 675 if (__ptr != nullptr) 676 get_deleter()(__ptr); 677 __ptr = pointer(); 678 } 679 680 // Assignment. 681 682 /** @brief Move assignment operator. 683 * 684 * Invokes the deleter if this object owns a pointer. 685 */ 686 unique_ptr& 687 operator=(unique_ptr&&) = default; 688 689 /** @brief Assignment from another type. 690 * 691 * @param __u The object to transfer ownership from, which owns a 692 * convertible pointer to an array object. 693 * 694 * Invokes the deleter if this object owns a pointer. 695 */ 696 template<typename _Up, typename _Ep> 697 _GLIBCXX23_CONSTEXPR 698 typename 699 enable_if<__and_<__safe_conversion_up<_Up, _Ep>, 700 is_assignable<deleter_type&, _Ep&&> 701 >::value, 702 unique_ptr&>::type 703 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 704 { 705 reset(__u.release()); 706 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 707 return *this; 708 } 709 710 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 711 _GLIBCXX23_CONSTEXPR 712 unique_ptr& 713 operator=(nullptr_t) noexcept 714 { 715 reset(); 716 return *this; 717 } 718 719 // Observers. 720 721 /// Access an element of owned array. 722 _GLIBCXX23_CONSTEXPR 723 typename std::add_lvalue_reference<element_type>::type 724 operator[](size_t __i) const 725 { 726 __glibcxx_assert(get() != pointer()); 727 return get()[__i]; 728 } 729 730 /// Return the stored pointer. 731 _GLIBCXX23_CONSTEXPR 732 pointer 733 get() const noexcept 734 { return _M_t._M_ptr(); } 735 736 /// Return a reference to the stored deleter. 737 _GLIBCXX23_CONSTEXPR 738 deleter_type& 739 get_deleter() noexcept 740 { return _M_t._M_deleter(); } 741 742 /// Return a reference to the stored deleter. 743 _GLIBCXX23_CONSTEXPR 744 const deleter_type& 745 get_deleter() const noexcept 746 { return _M_t._M_deleter(); } 747 748 /// Return @c true if the stored pointer is not null. 749 _GLIBCXX23_CONSTEXPR 750 explicit operator bool() const noexcept 751 { return get() == pointer() ? false : true; } 752 753 // Modifiers. 754 755 /// Release ownership of any stored pointer. 756 _GLIBCXX23_CONSTEXPR 757 pointer 758 release() noexcept 759 { return _M_t.release(); } 760 761 /** @brief Replace the stored pointer. 762 * 763 * @param __p The new pointer to store. 764 * 765 * The deleter will be invoked if a pointer is already owned. 766 */ 767 template <typename _Up, 768 typename = _Require< 769 __or_<is_same<_Up, pointer>, 770 __and_<is_same<pointer, element_type*>, 771 is_pointer<_Up>, 772 is_convertible< 773 typename remove_pointer<_Up>::type(*)[], 774 element_type(*)[] 775 > 776 > 777 > 778 >> 779 _GLIBCXX23_CONSTEXPR 780 void 781 reset(_Up __p) noexcept 782 { _M_t.reset(std::move(__p)); } 783 784 _GLIBCXX23_CONSTEXPR 785 void reset(nullptr_t = nullptr) noexcept 786 { reset(pointer()); } 787 788 /// Exchange the pointer and deleter with another object. 789 _GLIBCXX23_CONSTEXPR 790 void 791 swap(unique_ptr& __u) noexcept 792 { 793 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); 794 _M_t.swap(__u._M_t); 795 } 796 797 // Disable copy from lvalue. 798 unique_ptr(const unique_ptr&) = delete; 799 unique_ptr& operator=(const unique_ptr&) = delete; 800 }; 801 802 /// @{ 803 /// @relates unique_ptr 804 805 /// Swap overload for unique_ptr 806 template<typename _Tp, typename _Dp> 807 inline 808 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 809 // Constrained free swap overload, see p0185r1 810 _GLIBCXX23_CONSTEXPR 811 typename enable_if<__is_swappable<_Dp>::value>::type 812 #else 813 void 814 #endif 815 swap(unique_ptr<_Tp, _Dp>& __x, 816 unique_ptr<_Tp, _Dp>& __y) noexcept 817 { __x.swap(__y); } 818 819 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 820 template<typename _Tp, typename _Dp> 821 typename enable_if<!__is_swappable<_Dp>::value>::type 822 swap(unique_ptr<_Tp, _Dp>&, 823 unique_ptr<_Tp, _Dp>&) = delete; 824 #endif 825 826 /// Equality operator for unique_ptr objects, compares the owned pointers 827 template<typename _Tp, typename _Dp, 828 typename _Up, typename _Ep> 829 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 830 inline bool 831 operator==(const unique_ptr<_Tp, _Dp>& __x, 832 const unique_ptr<_Up, _Ep>& __y) 833 { return __x.get() == __y.get(); } 834 835 /// unique_ptr comparison with nullptr 836 template<typename _Tp, typename _Dp> 837 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 838 inline bool 839 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 840 { return !__x; } 841 842 #ifndef __cpp_lib_three_way_comparison 843 /// unique_ptr comparison with nullptr 844 template<typename _Tp, typename _Dp> 845 _GLIBCXX_NODISCARD 846 inline bool 847 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 848 { return !__x; } 849 850 /// Inequality operator for unique_ptr objects, compares the owned pointers 851 template<typename _Tp, typename _Dp, 852 typename _Up, typename _Ep> 853 _GLIBCXX_NODISCARD 854 inline bool 855 operator!=(const unique_ptr<_Tp, _Dp>& __x, 856 const unique_ptr<_Up, _Ep>& __y) 857 { return __x.get() != __y.get(); } 858 859 /// unique_ptr comparison with nullptr 860 template<typename _Tp, typename _Dp> 861 _GLIBCXX_NODISCARD 862 inline bool 863 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 864 { return (bool)__x; } 865 866 /// unique_ptr comparison with nullptr 867 template<typename _Tp, typename _Dp> 868 _GLIBCXX_NODISCARD 869 inline bool 870 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 871 { return (bool)__x; } 872 #endif // three way comparison 873 874 /// Relational operator for unique_ptr objects, compares the owned pointers 875 template<typename _Tp, typename _Dp, 876 typename _Up, typename _Ep> 877 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 878 inline bool 879 operator<(const unique_ptr<_Tp, _Dp>& __x, 880 const unique_ptr<_Up, _Ep>& __y) 881 { 882 typedef typename 883 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 884 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 885 return std::less<_CT>()(__x.get(), __y.get()); 886 } 887 888 /// unique_ptr comparison with nullptr 889 template<typename _Tp, typename _Dp> 890 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 891 inline bool 892 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 893 { 894 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 895 nullptr); 896 } 897 898 /// unique_ptr comparison with nullptr 899 template<typename _Tp, typename _Dp> 900 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 901 inline bool 902 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 903 { 904 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 905 __x.get()); 906 } 907 908 /// Relational operator for unique_ptr objects, compares the owned pointers 909 template<typename _Tp, typename _Dp, 910 typename _Up, typename _Ep> 911 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 912 inline bool 913 operator<=(const unique_ptr<_Tp, _Dp>& __x, 914 const unique_ptr<_Up, _Ep>& __y) 915 { return !(__y < __x); } 916 917 /// unique_ptr comparison with nullptr 918 template<typename _Tp, typename _Dp> 919 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 920 inline bool 921 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 922 { return !(nullptr < __x); } 923 924 /// unique_ptr comparison with nullptr 925 template<typename _Tp, typename _Dp> 926 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 927 inline bool 928 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 929 { return !(__x < nullptr); } 930 931 /// Relational operator for unique_ptr objects, compares the owned pointers 932 template<typename _Tp, typename _Dp, 933 typename _Up, typename _Ep> 934 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 935 inline bool 936 operator>(const unique_ptr<_Tp, _Dp>& __x, 937 const unique_ptr<_Up, _Ep>& __y) 938 { return (__y < __x); } 939 940 /// unique_ptr comparison with nullptr 941 template<typename _Tp, typename _Dp> 942 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 943 inline bool 944 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 945 { 946 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 947 __x.get()); 948 } 949 950 /// unique_ptr comparison with nullptr 951 template<typename _Tp, typename _Dp> 952 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 953 inline bool 954 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 955 { 956 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 957 nullptr); 958 } 959 960 /// Relational operator for unique_ptr objects, compares the owned pointers 961 template<typename _Tp, typename _Dp, 962 typename _Up, typename _Ep> 963 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 964 inline bool 965 operator>=(const unique_ptr<_Tp, _Dp>& __x, 966 const unique_ptr<_Up, _Ep>& __y) 967 { return !(__x < __y); } 968 969 /// unique_ptr comparison with nullptr 970 template<typename _Tp, typename _Dp> 971 _GLIBCXX_NODISCARD _GLIBCXX23_CONSTEXPR 972 inline bool 973 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 974 { return !(__x < nullptr); } 975 976 /// unique_ptr comparison with nullptr 977 template<typename _Tp, typename _Dp> 978 _GLIBCXX_NODISCARD inline bool 979 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 980 { return !(nullptr < __x); } 981 982 #ifdef __cpp_lib_three_way_comparison 983 template<typename _Tp, typename _Dp, typename _Up, typename _Ep> 984 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer, 985 typename unique_ptr<_Up, _Ep>::pointer> 986 _GLIBCXX23_CONSTEXPR 987 inline 988 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer, 989 typename unique_ptr<_Up, _Ep>::pointer> 990 operator<=>(const unique_ptr<_Tp, _Dp>& __x, 991 const unique_ptr<_Up, _Ep>& __y) 992 { return compare_three_way()(__x.get(), __y.get()); } 993 994 template<typename _Tp, typename _Dp> 995 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer> 996 _GLIBCXX23_CONSTEXPR 997 inline 998 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer> 999 operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 1000 { 1001 using pointer = typename unique_ptr<_Tp, _Dp>::pointer; 1002 return compare_three_way()(__x.get(), static_cast<pointer>(nullptr)); 1003 } 1004 #endif 1005 /// @} relates unique_ptr 1006 1007 /// @cond undocumented 1008 template<typename _Up, typename _Ptr = typename _Up::pointer, 1009 bool = __poison_hash<_Ptr>::__enable_hash_call> 1010 struct __uniq_ptr_hash 1011 #if ! _GLIBCXX_INLINE_VERSION 1012 : private __poison_hash<_Ptr> 1013 #endif 1014 { 1015 size_t 1016 operator()(const _Up& __u) const 1017 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>()))) 1018 { return hash<_Ptr>()(__u.get()); } 1019 }; 1020 1021 template<typename _Up, typename _Ptr> 1022 struct __uniq_ptr_hash<_Up, _Ptr, false> 1023 : private __poison_hash<_Ptr> 1024 { }; 1025 /// @endcond 1026 1027 /// std::hash specialization for unique_ptr. 1028 template<typename _Tp, typename _Dp> 1029 struct hash<unique_ptr<_Tp, _Dp>> 1030 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, 1031 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>> 1032 { }; 1033 1034 #if __cplusplus >= 201402L 1035 #define __cpp_lib_make_unique 201304L 1036 1037 /// @cond undocumented 1038 namespace __detail 1039 { 1040 template<typename _Tp> 1041 struct _MakeUniq 1042 { typedef unique_ptr<_Tp> __single_object; }; 1043 1044 template<typename _Tp> 1045 struct _MakeUniq<_Tp[]> 1046 { typedef unique_ptr<_Tp[]> __array; }; 1047 1048 template<typename _Tp, size_t _Bound> 1049 struct _MakeUniq<_Tp[_Bound]> 1050 { struct __invalid_type { }; }; 1051 1052 template<typename _Tp> 1053 using __unique_ptr_t = typename _MakeUniq<_Tp>::__single_object; 1054 template<typename _Tp> 1055 using __unique_ptr_array_t = typename _MakeUniq<_Tp>::__array; 1056 template<typename _Tp> 1057 using __invalid_make_unique_t = typename _MakeUniq<_Tp>::__invalid_type; 1058 } 1059 /// @endcond 1060 1061 /** Create an object owned by a `unique_ptr`. 1062 * @tparam _Tp A non-array object type. 1063 * @param __args Constructor arguments for the new object. 1064 * @returns A `unique_ptr<_Tp>` that owns the new object. 1065 * @since C++14 1066 * @relates unique_ptr 1067 */ 1068 template<typename _Tp, typename... _Args> 1069 _GLIBCXX23_CONSTEXPR 1070 inline __detail::__unique_ptr_t<_Tp> 1071 make_unique(_Args&&... __args) 1072 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } 1073 1074 /** Create an array owned by a `unique_ptr`. 1075 * @tparam _Tp An array type of unknown bound, such as `U[]`. 1076 * @param __num The number of elements of type `U` in the new array. 1077 * @returns A `unique_ptr<U[]>` that owns the new array. 1078 * @since C++14 1079 * @relates unique_ptr 1080 * 1081 * The array elements are value-initialized. 1082 */ 1083 template<typename _Tp> 1084 _GLIBCXX23_CONSTEXPR 1085 inline __detail::__unique_ptr_array_t<_Tp> 1086 make_unique(size_t __num) 1087 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } 1088 1089 /** Disable std::make_unique for arrays of known bound. 1090 * @tparam _Tp An array type of known bound, such as `U[N]`. 1091 * @since C++14 1092 * @relates unique_ptr 1093 */ 1094 template<typename _Tp, typename... _Args> 1095 __detail::__invalid_make_unique_t<_Tp> 1096 make_unique(_Args&&...) = delete; 1097 1098 #if __cplusplus > 201703L 1099 /** Create a default-initialied object owned by a `unique_ptr`. 1100 * @tparam _Tp A non-array object type. 1101 * @returns A `unique_ptr<_Tp>` that owns the new object. 1102 * @since C++20 1103 * @relates unique_ptr 1104 */ 1105 template<typename _Tp> 1106 _GLIBCXX23_CONSTEXPR 1107 inline __detail::__unique_ptr_t<_Tp> 1108 make_unique_for_overwrite() 1109 { return unique_ptr<_Tp>(new _Tp); } 1110 1111 /** Create a default-initialized array owned by a `unique_ptr`. 1112 * @tparam _Tp An array type of unknown bound, such as `U[]`. 1113 * @param __num The number of elements of type `U` in the new array. 1114 * @returns A `unique_ptr<U[]>` that owns the new array. 1115 * @since C++20 1116 * @relates unique_ptr 1117 */ 1118 template<typename _Tp> 1119 _GLIBCXX23_CONSTEXPR 1120 inline __detail::__unique_ptr_array_t<_Tp> 1121 make_unique_for_overwrite(size_t __num) 1122 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]); } 1123 1124 /** Disable std::make_unique_for_overwrite for arrays of known bound. 1125 * @tparam _Tp An array type of known bound, such as `U[N]`. 1126 * @since C++20 1127 * @relates unique_ptr 1128 */ 1129 template<typename _Tp, typename... _Args> 1130 __detail::__invalid_make_unique_t<_Tp> 1131 make_unique_for_overwrite(_Args&&...) = delete; 1132 #endif // C++20 1133 1134 #endif // C++14 1135 1136 #if __cplusplus > 201703L && __cpp_concepts 1137 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1138 // 2948. unique_ptr does not define operator<< for stream output 1139 /// Stream output operator for unique_ptr 1140 /// @relates unique_ptr 1141 /// @since C++20 1142 template<typename _CharT, typename _Traits, typename _Tp, typename _Dp> 1143 inline basic_ostream<_CharT, _Traits>& 1144 operator<<(basic_ostream<_CharT, _Traits>& __os, 1145 const unique_ptr<_Tp, _Dp>& __p) 1146 requires requires { __os << __p.get(); } 1147 { 1148 __os << __p.get(); 1149 return __os; 1150 } 1151 #endif // C++20 1152 1153 /// @} group pointer_abstractions 1154 1155 #if __cplusplus >= 201703L 1156 namespace __detail::__variant 1157 { 1158 template<typename> struct _Never_valueless_alt; // see <variant> 1159 1160 // Provide the strong exception-safety guarantee when emplacing a 1161 // unique_ptr into a variant. 1162 template<typename _Tp, typename _Del> 1163 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>> 1164 : std::true_type 1165 { }; 1166 } // namespace __detail::__variant 1167 #endif // C++17 1168 1169 _GLIBCXX_END_NAMESPACE_VERSION 1170 } // namespace 1171 1172 #endif /* _UNIQUE_PTR_H */ 1173