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