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