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