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