1 // unique_ptr implementation -*- C++ -*- 2 3 // Copyright (C) 2008-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 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 <utility> 37 #include <tuple> 38 #include <bits/stl_function.h> 39 #include <bits/functional_hash.h> 40 41 namespace std _GLIBCXX_VISIBILITY(default) 42 { 43 _GLIBCXX_BEGIN_NAMESPACE_VERSION 44 45 /** 46 * @addtogroup pointer_abstractions 47 * @{ 48 */ 49 50 #if _GLIBCXX_USE_DEPRECATED 51 #pragma GCC diagnostic push 52 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 53 template<typename> class auto_ptr; 54 #pragma GCC diagnostic pop 55 #endif 56 57 /// Primary template of default_delete, used by unique_ptr 58 template<typename _Tp> 59 struct default_delete 60 { 61 /// Default constructor 62 constexpr default_delete() noexcept = default; 63 64 /** @brief Converting constructor. 65 * 66 * Allows conversion from a deleter for arrays of another type, @p _Up, 67 * only if @p _Up* is convertible to @p _Tp*. 68 */ 69 template<typename _Up, typename = typename 70 enable_if<is_convertible<_Up*, _Tp*>::value>::type> 71 default_delete(const default_delete<_Up>&) noexcept { } 72 73 /// Calls @c delete @p __ptr 74 void 75 operator()(_Tp* __ptr) const 76 { 77 static_assert(!is_void<_Tp>::value, 78 "can't delete pointer to incomplete type"); 79 static_assert(sizeof(_Tp)>0, 80 "can't delete pointer to incomplete type"); 81 delete __ptr; 82 } 83 }; 84 85 // _GLIBCXX_RESOLVE_LIB_DEFECTS 86 // DR 740 - omit specialization for array objects with a compile time length 87 /// Specialization for arrays, default_delete. 88 template<typename _Tp> 89 struct default_delete<_Tp[]> 90 { 91 public: 92 /// Default constructor 93 constexpr default_delete() noexcept = default; 94 95 /** @brief Converting constructor. 96 * 97 * Allows conversion from a deleter for arrays of another type, such as 98 * a const-qualified version of @p _Tp. 99 * 100 * Conversions from types derived from @c _Tp are not allowed because 101 * it is unsafe to @c delete[] an array of derived types through a 102 * pointer to the base type. 103 */ 104 template<typename _Up, typename = typename 105 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type> 106 default_delete(const default_delete<_Up[]>&) noexcept { } 107 108 /// Calls @c delete[] @p __ptr 109 template<typename _Up> 110 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type 111 operator()(_Up* __ptr) const 112 { 113 static_assert(sizeof(_Tp)>0, 114 "can't delete pointer to incomplete type"); 115 delete [] __ptr; 116 } 117 }; 118 119 template <typename _Tp, typename _Dp> 120 class __uniq_ptr_impl 121 { 122 template <typename _Up, typename _Ep, typename = void> 123 struct _Ptr 124 { 125 using type = _Up*; 126 }; 127 128 template <typename _Up, typename _Ep> 129 struct 130 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> 131 { 132 using type = typename remove_reference<_Ep>::type::pointer; 133 }; 134 135 public: 136 using _DeleterConstraint = enable_if< 137 __and_<__not_<is_pointer<_Dp>>, 138 is_default_constructible<_Dp>>::value>; 139 140 using pointer = typename _Ptr<_Tp, _Dp>::type; 141 142 static_assert( !is_rvalue_reference<_Dp>::value, 143 "unique_ptr's deleter type must be a function object type" 144 " or an lvalue reference type" ); 145 146 __uniq_ptr_impl() = default; 147 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; } 148 149 template<typename _Del> 150 __uniq_ptr_impl(pointer __p, _Del&& __d) 151 : _M_t(__p, std::forward<_Del>(__d)) { } 152 153 pointer& _M_ptr() { return std::get<0>(_M_t); } 154 pointer _M_ptr() const { return std::get<0>(_M_t); } 155 _Dp& _M_deleter() { return std::get<1>(_M_t); } 156 const _Dp& _M_deleter() const { return std::get<1>(_M_t); } 157 158 void 159 swap(__uniq_ptr_impl& __rhs) noexcept 160 { 161 using std::swap; 162 swap(this->_M_ptr(), __rhs._M_ptr()); 163 swap(this->_M_deleter(), __rhs._M_deleter()); 164 } 165 166 private: 167 tuple<pointer, _Dp> _M_t; 168 }; 169 170 /// 20.7.1.2 unique_ptr for single objects. 171 template <typename _Tp, typename _Dp = default_delete<_Tp>> 172 class unique_ptr 173 { 174 template <typename _Up> 175 using _DeleterConstraint = 176 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 177 178 __uniq_ptr_impl<_Tp, _Dp> _M_t; 179 180 public: 181 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 182 using element_type = _Tp; 183 using deleter_type = _Dp; 184 185 private: 186 // helper template for detecting a safe conversion from another 187 // unique_ptr 188 template<typename _Up, typename _Ep> 189 using __safe_conversion_up = __and_< 190 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 191 __not_<is_array<_Up>> 192 >; 193 194 public: 195 // Constructors. 196 197 /// Default constructor, creates a unique_ptr that owns nothing. 198 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 199 constexpr unique_ptr() noexcept 200 : _M_t() 201 { } 202 203 /** Takes ownership of a pointer. 204 * 205 * @param __p A pointer to an object of @c element_type 206 * 207 * The deleter will be value-initialized. 208 */ 209 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 210 explicit 211 unique_ptr(pointer __p) noexcept 212 : _M_t(__p) 213 { } 214 215 /** Takes ownership of a pointer. 216 * 217 * @param __p A pointer to an object of @c element_type 218 * @param __d A reference to a deleter. 219 * 220 * The deleter will be initialized with @p __d 221 */ 222 template<typename _Del = deleter_type, 223 typename = _Require<is_copy_constructible<_Del>>> 224 unique_ptr(pointer __p, const deleter_type& __d) noexcept 225 : _M_t(__p, __d) { } 226 227 /** Takes ownership of a pointer. 228 * 229 * @param __p A pointer to an object of @c element_type 230 * @param __d An rvalue reference to a (non-reference) deleter. 231 * 232 * The deleter will be initialized with @p std::move(__d) 233 */ 234 template<typename _Del = deleter_type, 235 typename = _Require<is_move_constructible<_Del>>> 236 unique_ptr(pointer __p, 237 __enable_if_t<!is_lvalue_reference<_Del>::value, 238 _Del&&> __d) noexcept 239 : _M_t(__p, std::move(__d)) 240 { } 241 242 template<typename _Del = deleter_type, 243 typename _DelUnref = typename remove_reference<_Del>::type> 244 unique_ptr(pointer, 245 __enable_if_t<is_lvalue_reference<_Del>::value, 246 _DelUnref&&>) = delete; 247 248 /// Creates a unique_ptr that owns nothing. 249 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 250 constexpr unique_ptr(nullptr_t) noexcept 251 : _M_t() 252 { } 253 254 // Move constructors. 255 256 /// Move constructor. 257 unique_ptr(unique_ptr&& __u) noexcept 258 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 259 260 /** @brief Converting constructor from another type 261 * 262 * Requires that the pointer owned by @p __u is convertible to the 263 * type of pointer owned by this object, @p __u does not own an array, 264 * and @p __u has a compatible deleter type. 265 */ 266 template<typename _Up, typename _Ep, typename = _Require< 267 __safe_conversion_up<_Up, _Ep>, 268 typename conditional<is_reference<_Dp>::value, 269 is_same<_Ep, _Dp>, 270 is_convertible<_Ep, _Dp>>::type>> 271 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 272 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 273 { } 274 275 #if _GLIBCXX_USE_DEPRECATED 276 #pragma GCC diagnostic push 277 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 278 /// Converting constructor from @c auto_ptr 279 template<typename _Up, typename = _Require< 280 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 281 unique_ptr(auto_ptr<_Up>&& __u) noexcept; 282 #pragma GCC diagnostic pop 283 #endif 284 285 /// Destructor, invokes the deleter if the stored pointer is not null. 286 ~unique_ptr() noexcept 287 { 288 static_assert(__is_invocable<deleter_type&, pointer>::value, 289 "unique_ptr's deleter must be invocable with a pointer"); 290 auto& __ptr = _M_t._M_ptr(); 291 if (__ptr != nullptr) 292 get_deleter()(std::move(__ptr)); 293 __ptr = pointer(); 294 } 295 296 // Assignment. 297 298 /** @brief Move assignment operator. 299 * 300 * @param __u The object to transfer ownership from. 301 * 302 * Invokes the deleter first if this object owns a pointer. 303 */ 304 unique_ptr& 305 operator=(unique_ptr&& __u) noexcept 306 { 307 reset(__u.release()); 308 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 309 return *this; 310 } 311 312 /** @brief Assignment from another type. 313 * 314 * @param __u The object to transfer ownership from, which owns a 315 * convertible pointer to a non-array object. 316 * 317 * Invokes the deleter first if this object owns a pointer. 318 */ 319 template<typename _Up, typename _Ep> 320 typename enable_if< __and_< 321 __safe_conversion_up<_Up, _Ep>, 322 is_assignable<deleter_type&, _Ep&&> 323 >::value, 324 unique_ptr&>::type 325 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 326 { 327 reset(__u.release()); 328 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 329 return *this; 330 } 331 332 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 333 unique_ptr& 334 operator=(nullptr_t) noexcept 335 { 336 reset(); 337 return *this; 338 } 339 340 // Observers. 341 342 /// Dereference the stored pointer. 343 typename add_lvalue_reference<element_type>::type 344 operator*() const 345 { 346 __glibcxx_assert(get() != pointer()); 347 return *get(); 348 } 349 350 /// Return the stored pointer. 351 pointer 352 operator->() const noexcept 353 { 354 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); 355 return get(); 356 } 357 358 /// Return the stored pointer. 359 pointer 360 get() const noexcept 361 { return _M_t._M_ptr(); } 362 363 /// Return a reference to the stored deleter. 364 deleter_type& 365 get_deleter() noexcept 366 { return _M_t._M_deleter(); } 367 368 /// Return a reference to the stored deleter. 369 const deleter_type& 370 get_deleter() const noexcept 371 { return _M_t._M_deleter(); } 372 373 /// Return @c true if the stored pointer is not null. 374 explicit operator bool() const noexcept 375 { return get() == pointer() ? false : true; } 376 377 // Modifiers. 378 379 /// Release ownership of any stored pointer. 380 pointer 381 release() noexcept 382 { 383 pointer __p = get(); 384 _M_t._M_ptr() = pointer(); 385 return __p; 386 } 387 388 /** @brief Replace the stored pointer. 389 * 390 * @param __p The new pointer to store. 391 * 392 * The deleter will be invoked if a pointer is already owned. 393 */ 394 void 395 reset(pointer __p = pointer()) noexcept 396 { 397 static_assert(__is_invocable<deleter_type&, pointer>::value, 398 "unique_ptr's deleter must be invocable with a pointer"); 399 using std::swap; 400 swap(_M_t._M_ptr(), __p); 401 if (__p != pointer()) 402 get_deleter()(std::move(__p)); 403 } 404 405 /// Exchange the pointer and deleter with another object. 406 void 407 swap(unique_ptr& __u) noexcept 408 { 409 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); 410 _M_t.swap(__u._M_t); 411 } 412 413 // Disable copy from lvalue. 414 unique_ptr(const unique_ptr&) = delete; 415 unique_ptr& operator=(const unique_ptr&) = delete; 416 }; 417 418 /// 20.7.1.3 unique_ptr for array objects with a runtime length 419 // [unique.ptr.runtime] 420 // _GLIBCXX_RESOLVE_LIB_DEFECTS 421 // DR 740 - omit specialization for array objects with a compile time length 422 template<typename _Tp, typename _Dp> 423 class unique_ptr<_Tp[], _Dp> 424 { 425 template <typename _Up> 426 using _DeleterConstraint = 427 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 428 429 __uniq_ptr_impl<_Tp, _Dp> _M_t; 430 431 template<typename _Up> 432 using __remove_cv = typename remove_cv<_Up>::type; 433 434 // like is_base_of<_Tp, _Up> but false if unqualified types are the same 435 template<typename _Up> 436 using __is_derived_Tp 437 = __and_< is_base_of<_Tp, _Up>, 438 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 439 440 public: 441 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 442 using element_type = _Tp; 443 using deleter_type = _Dp; 444 445 // helper template for detecting a safe conversion from another 446 // unique_ptr 447 template<typename _Up, typename _Ep, 448 typename _UPtr = unique_ptr<_Up, _Ep>, 449 typename _UP_pointer = typename _UPtr::pointer, 450 typename _UP_element_type = typename _UPtr::element_type> 451 using __safe_conversion_up = __and_< 452 is_array<_Up>, 453 is_same<pointer, element_type*>, 454 is_same<_UP_pointer, _UP_element_type*>, 455 is_convertible<_UP_element_type(*)[], element_type(*)[]> 456 >; 457 458 // helper template for detecting a safe conversion from a raw pointer 459 template<typename _Up> 460 using __safe_conversion_raw = __and_< 461 __or_<__or_<is_same<_Up, pointer>, 462 is_same<_Up, nullptr_t>>, 463 __and_<is_pointer<_Up>, 464 is_same<pointer, element_type*>, 465 is_convertible< 466 typename remove_pointer<_Up>::type(*)[], 467 element_type(*)[]> 468 > 469 > 470 >; 471 472 // Constructors. 473 474 /// Default constructor, creates a unique_ptr that owns nothing. 475 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 476 constexpr unique_ptr() noexcept 477 : _M_t() 478 { } 479 480 /** Takes ownership of a pointer. 481 * 482 * @param __p A pointer to an array of a type safely convertible 483 * to an array of @c element_type 484 * 485 * The deleter will be value-initialized. 486 */ 487 template<typename _Up, 488 typename _Vp = _Dp, 489 typename = _DeleterConstraint<_Vp>, 490 typename = typename enable_if< 491 __safe_conversion_raw<_Up>::value, bool>::type> 492 explicit 493 unique_ptr(_Up __p) noexcept 494 : _M_t(__p) 495 { } 496 497 /** Takes ownership of a pointer. 498 * 499 * @param __p A pointer to an array of a type safely convertible 500 * to an array of @c element_type 501 * @param __d A reference to a deleter. 502 * 503 * The deleter will be initialized with @p __d 504 */ 505 template<typename _Up, typename _Del = deleter_type, 506 typename = _Require<__safe_conversion_raw<_Up>, 507 is_copy_constructible<_Del>>> 508 unique_ptr(_Up __p, const deleter_type& __d) noexcept 509 : _M_t(__p, __d) { } 510 511 /** Takes ownership of a pointer. 512 * 513 * @param __p A pointer to an array of a type safely convertible 514 * to an array of @c element_type 515 * @param __d A reference to a deleter. 516 * 517 * The deleter will be initialized with @p std::move(__d) 518 */ 519 template<typename _Up, typename _Del = deleter_type, 520 typename = _Require<__safe_conversion_raw<_Up>, 521 is_move_constructible<_Del>>> 522 unique_ptr(_Up __p, 523 __enable_if_t<!is_lvalue_reference<_Del>::value, 524 _Del&&> __d) noexcept 525 : _M_t(std::move(__p), std::move(__d)) 526 { } 527 528 template<typename _Up, typename _Del = deleter_type, 529 typename _DelUnref = typename remove_reference<_Del>::type, 530 typename = _Require<__safe_conversion_raw<_Up>>> 531 unique_ptr(_Up, 532 __enable_if_t<is_lvalue_reference<_Del>::value, 533 _DelUnref&&>) = delete; 534 535 /// Move constructor. 536 unique_ptr(unique_ptr&& __u) noexcept 537 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 538 539 /// Creates a unique_ptr that owns nothing. 540 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 541 constexpr unique_ptr(nullptr_t) noexcept 542 : _M_t() 543 { } 544 545 template<typename _Up, typename _Ep, typename = _Require< 546 __safe_conversion_up<_Up, _Ep>, 547 typename conditional<is_reference<_Dp>::value, 548 is_same<_Ep, _Dp>, 549 is_convertible<_Ep, _Dp>>::type>> 550 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 551 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 552 { } 553 554 /// Destructor, invokes the deleter if the stored pointer is not null. 555 ~unique_ptr() 556 { 557 auto& __ptr = _M_t._M_ptr(); 558 if (__ptr != nullptr) 559 get_deleter()(__ptr); 560 __ptr = pointer(); 561 } 562 563 // Assignment. 564 565 /** @brief Move assignment operator. 566 * 567 * @param __u The object to transfer ownership from. 568 * 569 * Invokes the deleter first if this object owns a pointer. 570 */ 571 unique_ptr& 572 operator=(unique_ptr&& __u) noexcept 573 { 574 reset(__u.release()); 575 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 576 return *this; 577 } 578 579 /** @brief Assignment from another type. 580 * 581 * @param __u The object to transfer ownership from, which owns a 582 * convertible pointer to an array object. 583 * 584 * Invokes the deleter first if this object owns a pointer. 585 */ 586 template<typename _Up, typename _Ep> 587 typename 588 enable_if<__and_<__safe_conversion_up<_Up, _Ep>, 589 is_assignable<deleter_type&, _Ep&&> 590 >::value, 591 unique_ptr&>::type 592 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 593 { 594 reset(__u.release()); 595 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 596 return *this; 597 } 598 599 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 600 unique_ptr& 601 operator=(nullptr_t) noexcept 602 { 603 reset(); 604 return *this; 605 } 606 607 // Observers. 608 609 /// Access an element of owned array. 610 typename std::add_lvalue_reference<element_type>::type 611 operator[](size_t __i) const 612 { 613 __glibcxx_assert(get() != pointer()); 614 return get()[__i]; 615 } 616 617 /// Return the stored pointer. 618 pointer 619 get() const noexcept 620 { return _M_t._M_ptr(); } 621 622 /// Return a reference to the stored deleter. 623 deleter_type& 624 get_deleter() noexcept 625 { return _M_t._M_deleter(); } 626 627 /// Return a reference to the stored deleter. 628 const deleter_type& 629 get_deleter() const noexcept 630 { return _M_t._M_deleter(); } 631 632 /// Return @c true if the stored pointer is not null. 633 explicit operator bool() const noexcept 634 { return get() == pointer() ? false : true; } 635 636 // Modifiers. 637 638 /// Release ownership of any stored pointer. 639 pointer 640 release() noexcept 641 { 642 pointer __p = get(); 643 _M_t._M_ptr() = pointer(); 644 return __p; 645 } 646 647 /** @brief Replace the stored pointer. 648 * 649 * @param __p The new pointer to store. 650 * 651 * The deleter will be invoked if a pointer is already owned. 652 */ 653 template <typename _Up, 654 typename = _Require< 655 __or_<is_same<_Up, pointer>, 656 __and_<is_same<pointer, element_type*>, 657 is_pointer<_Up>, 658 is_convertible< 659 typename remove_pointer<_Up>::type(*)[], 660 element_type(*)[] 661 > 662 > 663 > 664 >> 665 void 666 reset(_Up __p) noexcept 667 { 668 pointer __ptr = __p; 669 using std::swap; 670 swap(_M_t._M_ptr(), __ptr); 671 if (__ptr != nullptr) 672 get_deleter()(__ptr); 673 } 674 675 void reset(nullptr_t = nullptr) noexcept 676 { 677 reset(pointer()); 678 } 679 680 /// Exchange the pointer and deleter with another object. 681 void 682 swap(unique_ptr& __u) noexcept 683 { 684 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); 685 _M_t.swap(__u._M_t); 686 } 687 688 // Disable copy from lvalue. 689 unique_ptr(const unique_ptr&) = delete; 690 unique_ptr& operator=(const unique_ptr&) = delete; 691 }; 692 693 template<typename _Tp, typename _Dp> 694 inline 695 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 696 // Constrained free swap overload, see p0185r1 697 typename enable_if<__is_swappable<_Dp>::value>::type 698 #else 699 void 700 #endif 701 swap(unique_ptr<_Tp, _Dp>& __x, 702 unique_ptr<_Tp, _Dp>& __y) noexcept 703 { __x.swap(__y); } 704 705 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 706 template<typename _Tp, typename _Dp> 707 typename enable_if<!__is_swappable<_Dp>::value>::type 708 swap(unique_ptr<_Tp, _Dp>&, 709 unique_ptr<_Tp, _Dp>&) = delete; 710 #endif 711 712 template<typename _Tp, typename _Dp, 713 typename _Up, typename _Ep> 714 _GLIBCXX_NODISCARD inline bool 715 operator==(const unique_ptr<_Tp, _Dp>& __x, 716 const unique_ptr<_Up, _Ep>& __y) 717 { return __x.get() == __y.get(); } 718 719 template<typename _Tp, typename _Dp> 720 _GLIBCXX_NODISCARD inline bool 721 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 722 { return !__x; } 723 724 template<typename _Tp, typename _Dp> 725 _GLIBCXX_NODISCARD inline bool 726 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 727 { return !__x; } 728 729 template<typename _Tp, typename _Dp, 730 typename _Up, typename _Ep> 731 _GLIBCXX_NODISCARD inline bool 732 operator!=(const unique_ptr<_Tp, _Dp>& __x, 733 const unique_ptr<_Up, _Ep>& __y) 734 { return __x.get() != __y.get(); } 735 736 template<typename _Tp, typename _Dp> 737 _GLIBCXX_NODISCARD inline bool 738 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 739 { return (bool)__x; } 740 741 template<typename _Tp, typename _Dp> 742 _GLIBCXX_NODISCARD inline bool 743 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 744 { return (bool)__x; } 745 746 template<typename _Tp, typename _Dp, 747 typename _Up, typename _Ep> 748 _GLIBCXX_NODISCARD inline bool 749 operator<(const unique_ptr<_Tp, _Dp>& __x, 750 const unique_ptr<_Up, _Ep>& __y) 751 { 752 typedef typename 753 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 754 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 755 return std::less<_CT>()(__x.get(), __y.get()); 756 } 757 758 template<typename _Tp, typename _Dp> 759 _GLIBCXX_NODISCARD inline bool 760 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 761 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 762 nullptr); } 763 764 template<typename _Tp, typename _Dp> 765 _GLIBCXX_NODISCARD inline bool 766 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 767 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 768 __x.get()); } 769 770 template<typename _Tp, typename _Dp, 771 typename _Up, typename _Ep> 772 _GLIBCXX_NODISCARD inline bool 773 operator<=(const unique_ptr<_Tp, _Dp>& __x, 774 const unique_ptr<_Up, _Ep>& __y) 775 { return !(__y < __x); } 776 777 template<typename _Tp, typename _Dp> 778 _GLIBCXX_NODISCARD inline bool 779 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 780 { return !(nullptr < __x); } 781 782 template<typename _Tp, typename _Dp> 783 _GLIBCXX_NODISCARD inline bool 784 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 785 { return !(__x < nullptr); } 786 787 template<typename _Tp, typename _Dp, 788 typename _Up, typename _Ep> 789 _GLIBCXX_NODISCARD inline bool 790 operator>(const unique_ptr<_Tp, _Dp>& __x, 791 const unique_ptr<_Up, _Ep>& __y) 792 { return (__y < __x); } 793 794 template<typename _Tp, typename _Dp> 795 _GLIBCXX_NODISCARD inline bool 796 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 797 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 798 __x.get()); } 799 800 template<typename _Tp, typename _Dp> 801 _GLIBCXX_NODISCARD inline bool 802 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 803 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 804 nullptr); } 805 806 template<typename _Tp, typename _Dp, 807 typename _Up, typename _Ep> 808 _GLIBCXX_NODISCARD inline bool 809 operator>=(const unique_ptr<_Tp, _Dp>& __x, 810 const unique_ptr<_Up, _Ep>& __y) 811 { return !(__x < __y); } 812 813 template<typename _Tp, typename _Dp> 814 _GLIBCXX_NODISCARD inline bool 815 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 816 { return !(__x < nullptr); } 817 818 template<typename _Tp, typename _Dp> 819 _GLIBCXX_NODISCARD inline bool 820 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 821 { return !(nullptr < __x); } 822 823 /// std::hash specialization for unique_ptr. 824 template<typename _Tp, typename _Dp> 825 struct hash<unique_ptr<_Tp, _Dp>> 826 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, 827 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer> 828 { 829 size_t 830 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept 831 { 832 typedef unique_ptr<_Tp, _Dp> _UP; 833 return std::hash<typename _UP::pointer>()(__u.get()); 834 } 835 }; 836 837 #if __cplusplus > 201103L 838 839 #define __cpp_lib_make_unique 201304 840 841 template<typename _Tp> 842 struct _MakeUniq 843 { typedef unique_ptr<_Tp> __single_object; }; 844 845 template<typename _Tp> 846 struct _MakeUniq<_Tp[]> 847 { typedef unique_ptr<_Tp[]> __array; }; 848 849 template<typename _Tp, size_t _Bound> 850 struct _MakeUniq<_Tp[_Bound]> 851 { struct __invalid_type { }; }; 852 853 /// std::make_unique for single objects 854 template<typename _Tp, typename... _Args> 855 inline typename _MakeUniq<_Tp>::__single_object 856 make_unique(_Args&&... __args) 857 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } 858 859 /// std::make_unique for arrays of unknown bound 860 template<typename _Tp> 861 inline typename _MakeUniq<_Tp>::__array 862 make_unique(size_t __num) 863 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } 864 865 /// Disable std::make_unique for arrays of known bound 866 template<typename _Tp, typename... _Args> 867 inline typename _MakeUniq<_Tp>::__invalid_type 868 make_unique(_Args&&...) = delete; 869 #endif 870 871 // @} group pointer_abstractions 872 873 #if __cplusplus >= 201703L 874 namespace __detail::__variant 875 { 876 template<typename> struct _Never_valueless_alt; // see <variant> 877 878 // Provide the strong exception-safety guarantee when emplacing a 879 // unique_ptr into a variant. 880 template<typename _Tp, typename _Del> 881 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>> 882 : std::true_type 883 { }; 884 } // namespace __detail::__variant 885 #endif // C++17 886 887 _GLIBCXX_END_NAMESPACE_VERSION 888 } // namespace 889 890 #endif /* _UNIQUE_PTR_H */ 891