|
libstdc++
|
00001 // unique_ptr implementation -*- C++ -*- 00002 00003 // Copyright (C) 2008-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/unique_ptr.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{memory} 00028 */ 00029 00030 #ifndef _UNIQUE_PTR_H 00031 #define _UNIQUE_PTR_H 1 00032 00033 #include <bits/c++config.h> 00034 #include <debug/assertions.h> 00035 #include <type_traits> 00036 #include <utility> 00037 #include <tuple> 00038 #include <bits/stl_function.h> 00039 #include <bits/functional_hash.h> 00040 00041 namespace std _GLIBCXX_VISIBILITY(default) 00042 { 00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00044 00045 /** 00046 * @addtogroup pointer_abstractions 00047 * @{ 00048 */ 00049 00050 #if _GLIBCXX_USE_DEPRECATED 00051 #pragma GCC diagnostic push 00052 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00053 template<typename> class auto_ptr; 00054 #pragma GCC diagnostic pop 00055 #endif 00056 00057 /// Primary template of default_delete, used by unique_ptr 00058 template<typename _Tp> 00059 struct default_delete 00060 { 00061 /// Default constructor 00062 constexpr default_delete() noexcept = default; 00063 00064 /** @brief Converting constructor. 00065 * 00066 * Allows conversion from a deleter for arrays of another type, @p _Up, 00067 * only if @p _Up* is convertible to @p _Tp*. 00068 */ 00069 template<typename _Up, typename = typename 00070 enable_if<is_convertible<_Up*, _Tp*>::value>::type> 00071 default_delete(const default_delete<_Up>&) noexcept { } 00072 00073 /// Calls @c delete @p __ptr 00074 void 00075 operator()(_Tp* __ptr) const 00076 { 00077 static_assert(!is_void<_Tp>::value, 00078 "can't delete pointer to incomplete type"); 00079 static_assert(sizeof(_Tp)>0, 00080 "can't delete pointer to incomplete type"); 00081 delete __ptr; 00082 } 00083 }; 00084 00085 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00086 // DR 740 - omit specialization for array objects with a compile time length 00087 /// Specialization for arrays, default_delete. 00088 template<typename _Tp> 00089 struct default_delete<_Tp[]> 00090 { 00091 public: 00092 /// Default constructor 00093 constexpr default_delete() noexcept = default; 00094 00095 /** @brief Converting constructor. 00096 * 00097 * Allows conversion from a deleter for arrays of another type, such as 00098 * a const-qualified version of @p _Tp. 00099 * 00100 * Conversions from types derived from @c _Tp are not allowed because 00101 * it is unsafe to @c delete[] an array of derived types through a 00102 * pointer to the base type. 00103 */ 00104 template<typename _Up, typename = typename 00105 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type> 00106 default_delete(const default_delete<_Up[]>&) noexcept { } 00107 00108 /// Calls @c delete[] @p __ptr 00109 template<typename _Up> 00110 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type 00111 operator()(_Up* __ptr) const 00112 { 00113 static_assert(sizeof(_Tp)>0, 00114 "can't delete pointer to incomplete type"); 00115 delete [] __ptr; 00116 } 00117 }; 00118 00119 template <typename _Tp, typename _Dp> 00120 class __uniq_ptr_impl 00121 { 00122 template <typename _Up, typename _Ep, typename = void> 00123 struct _Ptr 00124 { 00125 using type = _Up*; 00126 }; 00127 00128 template <typename _Up, typename _Ep> 00129 struct 00130 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> 00131 { 00132 using type = typename remove_reference<_Ep>::type::pointer; 00133 }; 00134 00135 public: 00136 using _DeleterConstraint = enable_if< 00137 __and_<__not_<is_pointer<_Dp>>, 00138 is_default_constructible<_Dp>>::value>; 00139 00140 using pointer = typename _Ptr<_Tp, _Dp>::type; 00141 00142 static_assert( !is_rvalue_reference<_Dp>::value, 00143 "unique_ptr's deleter type must be a function object type" 00144 " or an lvalue reference type" ); 00145 00146 __uniq_ptr_impl() = default; 00147 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; } 00148 00149 template<typename _Del> 00150 __uniq_ptr_impl(pointer __p, _Del&& __d) 00151 : _M_t(__p, std::forward<_Del>(__d)) { } 00152 00153 pointer& _M_ptr() { return std::get<0>(_M_t); } 00154 pointer _M_ptr() const { return std::get<0>(_M_t); } 00155 _Dp& _M_deleter() { return std::get<1>(_M_t); } 00156 const _Dp& _M_deleter() const { return std::get<1>(_M_t); } 00157 00158 void 00159 swap(__uniq_ptr_impl& __rhs) noexcept 00160 { 00161 using std::swap; 00162 swap(this->_M_ptr(), __rhs._M_ptr()); 00163 swap(this->_M_deleter(), __rhs._M_deleter()); 00164 } 00165 00166 private: 00167 tuple<pointer, _Dp> _M_t; 00168 }; 00169 00170 /// 20.7.1.2 unique_ptr for single objects. 00171 template <typename _Tp, typename _Dp = default_delete<_Tp>> 00172 class unique_ptr 00173 { 00174 template <typename _Up> 00175 using _DeleterConstraint = 00176 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 00177 00178 __uniq_ptr_impl<_Tp, _Dp> _M_t; 00179 00180 public: 00181 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 00182 using element_type = _Tp; 00183 using deleter_type = _Dp; 00184 00185 private: 00186 // helper template for detecting a safe conversion from another 00187 // unique_ptr 00188 template<typename _Up, typename _Ep> 00189 using __safe_conversion_up = __and_< 00190 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00191 __not_<is_array<_Up>> 00192 >; 00193 00194 public: 00195 // Constructors. 00196 00197 /// Default constructor, creates a unique_ptr that owns nothing. 00198 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00199 constexpr unique_ptr() noexcept 00200 : _M_t() 00201 { } 00202 00203 /** Takes ownership of a pointer. 00204 * 00205 * @param __p A pointer to an object of @c element_type 00206 * 00207 * The deleter will be value-initialized. 00208 */ 00209 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00210 explicit 00211 unique_ptr(pointer __p) noexcept 00212 : _M_t(__p) 00213 { } 00214 00215 /** Takes ownership of a pointer. 00216 * 00217 * @param __p A pointer to an object of @c element_type 00218 * @param __d A reference to a deleter. 00219 * 00220 * The deleter will be initialized with @p __d 00221 */ 00222 template<typename _Del = deleter_type, 00223 typename = _Require<is_copy_constructible<_Del>>> 00224 unique_ptr(pointer __p, const deleter_type& __d) noexcept 00225 : _M_t(__p, __d) { } 00226 00227 /** Takes ownership of a pointer. 00228 * 00229 * @param __p A pointer to an object of @c element_type 00230 * @param __d An rvalue reference to a (non-reference) deleter. 00231 * 00232 * The deleter will be initialized with @p std::move(__d) 00233 */ 00234 template<typename _Del = deleter_type, 00235 typename = _Require<is_move_constructible<_Del>>> 00236 unique_ptr(pointer __p, 00237 __enable_if_t<!is_lvalue_reference<_Del>::value, 00238 _Del&&> __d) noexcept 00239 : _M_t(__p, std::move(__d)) 00240 { } 00241 00242 template<typename _Del = deleter_type, 00243 typename _DelUnref = typename remove_reference<_Del>::type> 00244 unique_ptr(pointer, 00245 __enable_if_t<is_lvalue_reference<_Del>::value, 00246 _DelUnref&&>) = delete; 00247 00248 /// Creates a unique_ptr that owns nothing. 00249 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00250 constexpr unique_ptr(nullptr_t) noexcept 00251 : _M_t() 00252 { } 00253 00254 // Move constructors. 00255 00256 /// Move constructor. 00257 unique_ptr(unique_ptr&& __u) noexcept 00258 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00259 00260 /** @brief Converting constructor from another type 00261 * 00262 * Requires that the pointer owned by @p __u is convertible to the 00263 * type of pointer owned by this object, @p __u does not own an array, 00264 * and @p __u has a compatible deleter type. 00265 */ 00266 template<typename _Up, typename _Ep, typename = _Require< 00267 __safe_conversion_up<_Up, _Ep>, 00268 typename conditional<is_reference<_Dp>::value, 00269 is_same<_Ep, _Dp>, 00270 is_convertible<_Ep, _Dp>>::type>> 00271 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00272 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00273 { } 00274 00275 #if _GLIBCXX_USE_DEPRECATED 00276 #pragma GCC diagnostic push 00277 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00278 /// Converting constructor from @c auto_ptr 00279 template<typename _Up, typename = _Require< 00280 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 00281 unique_ptr(auto_ptr<_Up>&& __u) noexcept; 00282 #pragma GCC diagnostic pop 00283 #endif 00284 00285 /// Destructor, invokes the deleter if the stored pointer is not null. 00286 ~unique_ptr() noexcept 00287 { 00288 static_assert(__is_invocable<deleter_type&, pointer>::value, 00289 "unique_ptr's deleter must be invocable with a pointer"); 00290 auto& __ptr = _M_t._M_ptr(); 00291 if (__ptr != nullptr) 00292 get_deleter()(std::move(__ptr)); 00293 __ptr = pointer(); 00294 } 00295 00296 // Assignment. 00297 00298 /** @brief Move assignment operator. 00299 * 00300 * @param __u The object to transfer ownership from. 00301 * 00302 * Invokes the deleter first if this object owns a pointer. 00303 */ 00304 unique_ptr& 00305 operator=(unique_ptr&& __u) noexcept 00306 { 00307 reset(__u.release()); 00308 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00309 return *this; 00310 } 00311 00312 /** @brief Assignment from another type. 00313 * 00314 * @param __u The object to transfer ownership from, which owns a 00315 * convertible pointer to a non-array object. 00316 * 00317 * Invokes the deleter first if this object owns a pointer. 00318 */ 00319 template<typename _Up, typename _Ep> 00320 typename enable_if< __and_< 00321 __safe_conversion_up<_Up, _Ep>, 00322 is_assignable<deleter_type&, _Ep&&> 00323 >::value, 00324 unique_ptr&>::type 00325 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00326 { 00327 reset(__u.release()); 00328 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00329 return *this; 00330 } 00331 00332 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00333 unique_ptr& 00334 operator=(nullptr_t) noexcept 00335 { 00336 reset(); 00337 return *this; 00338 } 00339 00340 // Observers. 00341 00342 /// Dereference the stored pointer. 00343 typename add_lvalue_reference<element_type>::type 00344 operator*() const 00345 { 00346 __glibcxx_assert(get() != pointer()); 00347 return *get(); 00348 } 00349 00350 /// Return the stored pointer. 00351 pointer 00352 operator->() const noexcept 00353 { 00354 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); 00355 return get(); 00356 } 00357 00358 /// Return the stored pointer. 00359 pointer 00360 get() const noexcept 00361 { return _M_t._M_ptr(); } 00362 00363 /// Return a reference to the stored deleter. 00364 deleter_type& 00365 get_deleter() noexcept 00366 { return _M_t._M_deleter(); } 00367 00368 /// Return a reference to the stored deleter. 00369 const deleter_type& 00370 get_deleter() const noexcept 00371 { return _M_t._M_deleter(); } 00372 00373 /// Return @c true if the stored pointer is not null. 00374 explicit operator bool() const noexcept 00375 { return get() == pointer() ? false : true; } 00376 00377 // Modifiers. 00378 00379 /// Release ownership of any stored pointer. 00380 pointer 00381 release() noexcept 00382 { 00383 pointer __p = get(); 00384 _M_t._M_ptr() = pointer(); 00385 return __p; 00386 } 00387 00388 /** @brief Replace the stored pointer. 00389 * 00390 * @param __p The new pointer to store. 00391 * 00392 * The deleter will be invoked if a pointer is already owned. 00393 */ 00394 void 00395 reset(pointer __p = pointer()) noexcept 00396 { 00397 static_assert(__is_invocable<deleter_type&, pointer>::value, 00398 "unique_ptr's deleter must be invocable with a pointer"); 00399 using std::swap; 00400 swap(_M_t._M_ptr(), __p); 00401 if (__p != pointer()) 00402 get_deleter()(std::move(__p)); 00403 } 00404 00405 /// Exchange the pointer and deleter with another object. 00406 void 00407 swap(unique_ptr& __u) noexcept 00408 { 00409 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); 00410 _M_t.swap(__u._M_t); 00411 } 00412 00413 // Disable copy from lvalue. 00414 unique_ptr(const unique_ptr&) = delete; 00415 unique_ptr& operator=(const unique_ptr&) = delete; 00416 }; 00417 00418 /// 20.7.1.3 unique_ptr for array objects with a runtime length 00419 // [unique.ptr.runtime] 00420 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00421 // DR 740 - omit specialization for array objects with a compile time length 00422 template<typename _Tp, typename _Dp> 00423 class unique_ptr<_Tp[], _Dp> 00424 { 00425 template <typename _Up> 00426 using _DeleterConstraint = 00427 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 00428 00429 __uniq_ptr_impl<_Tp, _Dp> _M_t; 00430 00431 template<typename _Up> 00432 using __remove_cv = typename remove_cv<_Up>::type; 00433 00434 // like is_base_of<_Tp, _Up> but false if unqualified types are the same 00435 template<typename _Up> 00436 using __is_derived_Tp 00437 = __and_< is_base_of<_Tp, _Up>, 00438 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 00439 00440 public: 00441 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 00442 using element_type = _Tp; 00443 using deleter_type = _Dp; 00444 00445 // helper template for detecting a safe conversion from another 00446 // unique_ptr 00447 template<typename _Up, typename _Ep, 00448 typename _UPtr = unique_ptr<_Up, _Ep>, 00449 typename _UP_pointer = typename _UPtr::pointer, 00450 typename _UP_element_type = typename _UPtr::element_type> 00451 using __safe_conversion_up = __and_< 00452 is_array<_Up>, 00453 is_same<pointer, element_type*>, 00454 is_same<_UP_pointer, _UP_element_type*>, 00455 is_convertible<_UP_element_type(*)[], element_type(*)[]> 00456 >; 00457 00458 // helper template for detecting a safe conversion from a raw pointer 00459 template<typename _Up> 00460 using __safe_conversion_raw = __and_< 00461 __or_<__or_<is_same<_Up, pointer>, 00462 is_same<_Up, nullptr_t>>, 00463 __and_<is_pointer<_Up>, 00464 is_same<pointer, element_type*>, 00465 is_convertible< 00466 typename remove_pointer<_Up>::type(*)[], 00467 element_type(*)[]> 00468 > 00469 > 00470 >; 00471 00472 // Constructors. 00473 00474 /// Default constructor, creates a unique_ptr that owns nothing. 00475 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00476 constexpr unique_ptr() noexcept 00477 : _M_t() 00478 { } 00479 00480 /** Takes ownership of a pointer. 00481 * 00482 * @param __p A pointer to an array of a type safely convertible 00483 * to an array of @c element_type 00484 * 00485 * The deleter will be value-initialized. 00486 */ 00487 template<typename _Up, 00488 typename _Vp = _Dp, 00489 typename = _DeleterConstraint<_Vp>, 00490 typename = typename enable_if< 00491 __safe_conversion_raw<_Up>::value, bool>::type> 00492 explicit 00493 unique_ptr(_Up __p) noexcept 00494 : _M_t(__p) 00495 { } 00496 00497 /** Takes ownership of a pointer. 00498 * 00499 * @param __p A pointer to an array of a type safely convertible 00500 * to an array of @c element_type 00501 * @param __d A reference to a deleter. 00502 * 00503 * The deleter will be initialized with @p __d 00504 */ 00505 template<typename _Up, typename _Del = deleter_type, 00506 typename = _Require<__safe_conversion_raw<_Up>, 00507 is_copy_constructible<_Del>>> 00508 unique_ptr(_Up __p, const deleter_type& __d) noexcept 00509 : _M_t(__p, __d) { } 00510 00511 /** Takes ownership of a pointer. 00512 * 00513 * @param __p A pointer to an array of a type safely convertible 00514 * to an array of @c element_type 00515 * @param __d A reference to a deleter. 00516 * 00517 * The deleter will be initialized with @p std::move(__d) 00518 */ 00519 template<typename _Up, typename _Del = deleter_type, 00520 typename = _Require<__safe_conversion_raw<_Up>, 00521 is_move_constructible<_Del>>> 00522 unique_ptr(_Up __p, 00523 __enable_if_t<!is_lvalue_reference<_Del>::value, 00524 _Del&&> __d) noexcept 00525 : _M_t(std::move(__p), std::move(__d)) 00526 { } 00527 00528 template<typename _Up, typename _Del = deleter_type, 00529 typename _DelUnref = typename remove_reference<_Del>::type, 00530 typename = _Require<__safe_conversion_raw<_Up>>> 00531 unique_ptr(_Up, 00532 __enable_if_t<is_lvalue_reference<_Del>::value, 00533 _DelUnref&&>) = delete; 00534 00535 /// Move constructor. 00536 unique_ptr(unique_ptr&& __u) noexcept 00537 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00538 00539 /// Creates a unique_ptr that owns nothing. 00540 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00541 constexpr unique_ptr(nullptr_t) noexcept 00542 : _M_t() 00543 { } 00544 00545 template<typename _Up, typename _Ep, typename = _Require< 00546 __safe_conversion_up<_Up, _Ep>, 00547 typename conditional<is_reference<_Dp>::value, 00548 is_same<_Ep, _Dp>, 00549 is_convertible<_Ep, _Dp>>::type>> 00550 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00551 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00552 { } 00553 00554 /// Destructor, invokes the deleter if the stored pointer is not null. 00555 ~unique_ptr() 00556 { 00557 auto& __ptr = _M_t._M_ptr(); 00558 if (__ptr != nullptr) 00559 get_deleter()(__ptr); 00560 __ptr = pointer(); 00561 } 00562 00563 // Assignment. 00564 00565 /** @brief Move assignment operator. 00566 * 00567 * @param __u The object to transfer ownership from. 00568 * 00569 * Invokes the deleter first if this object owns a pointer. 00570 */ 00571 unique_ptr& 00572 operator=(unique_ptr&& __u) noexcept 00573 { 00574 reset(__u.release()); 00575 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00576 return *this; 00577 } 00578 00579 /** @brief Assignment from another type. 00580 * 00581 * @param __u The object to transfer ownership from, which owns a 00582 * convertible pointer to an array object. 00583 * 00584 * Invokes the deleter first if this object owns a pointer. 00585 */ 00586 template<typename _Up, typename _Ep> 00587 typename 00588 enable_if<__and_<__safe_conversion_up<_Up, _Ep>, 00589 is_assignable<deleter_type&, _Ep&&> 00590 >::value, 00591 unique_ptr&>::type 00592 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00593 { 00594 reset(__u.release()); 00595 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00596 return *this; 00597 } 00598 00599 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00600 unique_ptr& 00601 operator=(nullptr_t) noexcept 00602 { 00603 reset(); 00604 return *this; 00605 } 00606 00607 // Observers. 00608 00609 /// Access an element of owned array. 00610 typename std::add_lvalue_reference<element_type>::type 00611 operator[](size_t __i) const 00612 { 00613 __glibcxx_assert(get() != pointer()); 00614 return get()[__i]; 00615 } 00616 00617 /// Return the stored pointer. 00618 pointer 00619 get() const noexcept 00620 { return _M_t._M_ptr(); } 00621 00622 /// Return a reference to the stored deleter. 00623 deleter_type& 00624 get_deleter() noexcept 00625 { return _M_t._M_deleter(); } 00626 00627 /// Return a reference to the stored deleter. 00628 const deleter_type& 00629 get_deleter() const noexcept 00630 { return _M_t._M_deleter(); } 00631 00632 /// Return @c true if the stored pointer is not null. 00633 explicit operator bool() const noexcept 00634 { return get() == pointer() ? false : true; } 00635 00636 // Modifiers. 00637 00638 /// Release ownership of any stored pointer. 00639 pointer 00640 release() noexcept 00641 { 00642 pointer __p = get(); 00643 _M_t._M_ptr() = pointer(); 00644 return __p; 00645 } 00646 00647 /** @brief Replace the stored pointer. 00648 * 00649 * @param __p The new pointer to store. 00650 * 00651 * The deleter will be invoked if a pointer is already owned. 00652 */ 00653 template <typename _Up, 00654 typename = _Require< 00655 __or_<is_same<_Up, pointer>, 00656 __and_<is_same<pointer, element_type*>, 00657 is_pointer<_Up>, 00658 is_convertible< 00659 typename remove_pointer<_Up>::type(*)[], 00660 element_type(*)[] 00661 > 00662 > 00663 > 00664 >> 00665 void 00666 reset(_Up __p) noexcept 00667 { 00668 pointer __ptr = __p; 00669 using std::swap; 00670 swap(_M_t._M_ptr(), __ptr); 00671 if (__ptr != nullptr) 00672 get_deleter()(__ptr); 00673 } 00674 00675 void reset(nullptr_t = nullptr) noexcept 00676 { 00677 reset(pointer()); 00678 } 00679 00680 /// Exchange the pointer and deleter with another object. 00681 void 00682 swap(unique_ptr& __u) noexcept 00683 { 00684 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); 00685 _M_t.swap(__u._M_t); 00686 } 00687 00688 // Disable copy from lvalue. 00689 unique_ptr(const unique_ptr&) = delete; 00690 unique_ptr& operator=(const unique_ptr&) = delete; 00691 }; 00692 00693 template<typename _Tp, typename _Dp> 00694 inline 00695 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 00696 // Constrained free swap overload, see p0185r1 00697 typename enable_if<__is_swappable<_Dp>::value>::type 00698 #else 00699 void 00700 #endif 00701 swap(unique_ptr<_Tp, _Dp>& __x, 00702 unique_ptr<_Tp, _Dp>& __y) noexcept 00703 { __x.swap(__y); } 00704 00705 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 00706 template<typename _Tp, typename _Dp> 00707 typename enable_if<!__is_swappable<_Dp>::value>::type 00708 swap(unique_ptr<_Tp, _Dp>&, 00709 unique_ptr<_Tp, _Dp>&) = delete; 00710 #endif 00711 00712 template<typename _Tp, typename _Dp, 00713 typename _Up, typename _Ep> 00714 _GLIBCXX_NODISCARD inline bool 00715 operator==(const unique_ptr<_Tp, _Dp>& __x, 00716 const unique_ptr<_Up, _Ep>& __y) 00717 { return __x.get() == __y.get(); } 00718 00719 template<typename _Tp, typename _Dp> 00720 _GLIBCXX_NODISCARD inline bool 00721 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00722 { return !__x; } 00723 00724 template<typename _Tp, typename _Dp> 00725 _GLIBCXX_NODISCARD inline bool 00726 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00727 { return !__x; } 00728 00729 template<typename _Tp, typename _Dp, 00730 typename _Up, typename _Ep> 00731 _GLIBCXX_NODISCARD inline bool 00732 operator!=(const unique_ptr<_Tp, _Dp>& __x, 00733 const unique_ptr<_Up, _Ep>& __y) 00734 { return __x.get() != __y.get(); } 00735 00736 template<typename _Tp, typename _Dp> 00737 _GLIBCXX_NODISCARD inline bool 00738 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00739 { return (bool)__x; } 00740 00741 template<typename _Tp, typename _Dp> 00742 _GLIBCXX_NODISCARD inline bool 00743 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00744 { return (bool)__x; } 00745 00746 template<typename _Tp, typename _Dp, 00747 typename _Up, typename _Ep> 00748 _GLIBCXX_NODISCARD inline bool 00749 operator<(const unique_ptr<_Tp, _Dp>& __x, 00750 const unique_ptr<_Up, _Ep>& __y) 00751 { 00752 typedef typename 00753 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 00754 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 00755 return std::less<_CT>()(__x.get(), __y.get()); 00756 } 00757 00758 template<typename _Tp, typename _Dp> 00759 _GLIBCXX_NODISCARD inline bool 00760 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00761 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00762 nullptr); } 00763 00764 template<typename _Tp, typename _Dp> 00765 _GLIBCXX_NODISCARD inline bool 00766 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00767 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00768 __x.get()); } 00769 00770 template<typename _Tp, typename _Dp, 00771 typename _Up, typename _Ep> 00772 _GLIBCXX_NODISCARD inline bool 00773 operator<=(const unique_ptr<_Tp, _Dp>& __x, 00774 const unique_ptr<_Up, _Ep>& __y) 00775 { return !(__y < __x); } 00776 00777 template<typename _Tp, typename _Dp> 00778 _GLIBCXX_NODISCARD inline bool 00779 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00780 { return !(nullptr < __x); } 00781 00782 template<typename _Tp, typename _Dp> 00783 _GLIBCXX_NODISCARD inline bool 00784 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00785 { return !(__x < nullptr); } 00786 00787 template<typename _Tp, typename _Dp, 00788 typename _Up, typename _Ep> 00789 _GLIBCXX_NODISCARD inline bool 00790 operator>(const unique_ptr<_Tp, _Dp>& __x, 00791 const unique_ptr<_Up, _Ep>& __y) 00792 { return (__y < __x); } 00793 00794 template<typename _Tp, typename _Dp> 00795 _GLIBCXX_NODISCARD inline bool 00796 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00797 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00798 __x.get()); } 00799 00800 template<typename _Tp, typename _Dp> 00801 _GLIBCXX_NODISCARD inline bool 00802 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00803 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00804 nullptr); } 00805 00806 template<typename _Tp, typename _Dp, 00807 typename _Up, typename _Ep> 00808 _GLIBCXX_NODISCARD inline bool 00809 operator>=(const unique_ptr<_Tp, _Dp>& __x, 00810 const unique_ptr<_Up, _Ep>& __y) 00811 { return !(__x < __y); } 00812 00813 template<typename _Tp, typename _Dp> 00814 _GLIBCXX_NODISCARD inline bool 00815 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00816 { return !(__x < nullptr); } 00817 00818 template<typename _Tp, typename _Dp> 00819 _GLIBCXX_NODISCARD inline bool 00820 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00821 { return !(nullptr < __x); } 00822 00823 /// std::hash specialization for unique_ptr. 00824 template<typename _Tp, typename _Dp> 00825 struct hash<unique_ptr<_Tp, _Dp>> 00826 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, 00827 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer> 00828 { 00829 size_t 00830 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept 00831 { 00832 typedef unique_ptr<_Tp, _Dp> _UP; 00833 return std::hash<typename _UP::pointer>()(__u.get()); 00834 } 00835 }; 00836 00837 #if __cplusplus > 201103L 00838 00839 #define __cpp_lib_make_unique 201304 00840 00841 template<typename _Tp> 00842 struct _MakeUniq 00843 { typedef unique_ptr<_Tp> __single_object; }; 00844 00845 template<typename _Tp> 00846 struct _MakeUniq<_Tp[]> 00847 { typedef unique_ptr<_Tp[]> __array; }; 00848 00849 template<typename _Tp, size_t _Bound> 00850 struct _MakeUniq<_Tp[_Bound]> 00851 { struct __invalid_type { }; }; 00852 00853 /// std::make_unique for single objects 00854 template<typename _Tp, typename... _Args> 00855 inline typename _MakeUniq<_Tp>::__single_object 00856 make_unique(_Args&&... __args) 00857 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } 00858 00859 /// std::make_unique for arrays of unknown bound 00860 template<typename _Tp> 00861 inline typename _MakeUniq<_Tp>::__array 00862 make_unique(size_t __num) 00863 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } 00864 00865 /// Disable std::make_unique for arrays of known bound 00866 template<typename _Tp, typename... _Args> 00867 inline typename _MakeUniq<_Tp>::__invalid_type 00868 make_unique(_Args&&...) = delete; 00869 #endif 00870 00871 // @} group pointer_abstractions 00872 00873 #if __cplusplus >= 201703L 00874 namespace __detail::__variant 00875 { 00876 template<typename> struct _Never_valueless_alt; // see <variant> 00877 00878 // Provide the strong exception-safety guarantee when emplacing a 00879 // unique_ptr into a variant. 00880 template<typename _Tp, typename _Del> 00881 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>> 00882 : std::true_type 00883 { }; 00884 } // namespace __detail::__variant 00885 #endif // C++17 00886 00887 _GLIBCXX_END_NAMESPACE_VERSION 00888 } // namespace 00889 00890 #endif /* _UNIQUE_PTR_H */