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 private: 00159 tuple<pointer, _Dp> _M_t; 00160 }; 00161 00162 /// 20.7.1.2 unique_ptr for single objects. 00163 template <typename _Tp, typename _Dp = default_delete<_Tp>> 00164 class unique_ptr 00165 { 00166 template <typename _Up> 00167 using _DeleterConstraint = 00168 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 00169 00170 __uniq_ptr_impl<_Tp, _Dp> _M_t; 00171 00172 public: 00173 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 00174 using element_type = _Tp; 00175 using deleter_type = _Dp; 00176 00177 private: 00178 // helper template for detecting a safe conversion from another 00179 // unique_ptr 00180 template<typename _Up, typename _Ep> 00181 using __safe_conversion_up = __and_< 00182 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00183 __not_<is_array<_Up>>, 00184 __or_<__and_<is_reference<deleter_type>, 00185 is_same<deleter_type, _Ep>>, 00186 __and_<__not_<is_reference<deleter_type>>, 00187 is_convertible<_Ep, deleter_type>> 00188 > 00189 >; 00190 00191 public: 00192 // Constructors. 00193 00194 /// Default constructor, creates a unique_ptr that owns nothing. 00195 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00196 constexpr unique_ptr() noexcept 00197 : _M_t() 00198 { } 00199 00200 /** Takes ownership of a pointer. 00201 * 00202 * @param __p A pointer to an object of @c element_type 00203 * 00204 * The deleter will be value-initialized. 00205 */ 00206 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00207 explicit 00208 unique_ptr(pointer __p) noexcept 00209 : _M_t(__p) 00210 { } 00211 00212 /** Takes ownership of a pointer. 00213 * 00214 * @param __p A pointer to an object of @c element_type 00215 * @param __d A reference to a deleter. 00216 * 00217 * The deleter will be initialized with @p __d 00218 */ 00219 template<typename _Del = deleter_type, 00220 typename = _Require<is_copy_constructible<_Del>>> 00221 unique_ptr(pointer __p, const deleter_type& __d) noexcept 00222 : _M_t(__p, __d) { } 00223 00224 /** Takes ownership of a pointer. 00225 * 00226 * @param __p A pointer to an object of @c element_type 00227 * @param __d An rvalue reference to a (non-reference) deleter. 00228 * 00229 * The deleter will be initialized with @p std::move(__d) 00230 */ 00231 template<typename _Del = deleter_type, 00232 typename = _Require<is_move_constructible<_Del>>> 00233 unique_ptr(pointer __p, 00234 __enable_if_t<!is_lvalue_reference<_Del>::value, 00235 _Del&&> __d) noexcept 00236 : _M_t(__p, std::move(__d)) 00237 { } 00238 00239 template<typename _Del = deleter_type, 00240 typename _DelUnref = typename remove_reference<_Del>::type> 00241 unique_ptr(pointer, 00242 __enable_if_t<is_lvalue_reference<_Del>::value, 00243 _DelUnref&&>) = delete; 00244 00245 /// Creates a unique_ptr that owns nothing. 00246 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00247 constexpr unique_ptr(nullptr_t) noexcept 00248 : _M_t() 00249 { } 00250 00251 // Move constructors. 00252 00253 /// Move constructor. 00254 unique_ptr(unique_ptr&& __u) noexcept 00255 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00256 00257 /** @brief Converting constructor from another type 00258 * 00259 * Requires that the pointer owned by @p __u is convertible to the 00260 * type of pointer owned by this object, @p __u does not own an array, 00261 * and @p __u has a compatible deleter type. 00262 */ 00263 template<typename _Up, typename _Ep, typename = _Require< 00264 __safe_conversion_up<_Up, _Ep>, 00265 typename conditional<is_reference<_Dp>::value, 00266 is_same<_Ep, _Dp>, 00267 is_convertible<_Ep, _Dp>>::type>> 00268 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00269 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00270 { } 00271 00272 #if _GLIBCXX_USE_DEPRECATED 00273 #pragma GCC diagnostic push 00274 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00275 /// Converting constructor from @c auto_ptr 00276 template<typename _Up, typename = _Require< 00277 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 00278 unique_ptr(auto_ptr<_Up>&& __u) noexcept; 00279 #pragma GCC diagnostic pop 00280 #endif 00281 00282 /// Destructor, invokes the deleter if the stored pointer is not null. 00283 ~unique_ptr() noexcept 00284 { 00285 static_assert(__is_invocable<deleter_type&, pointer>::value, 00286 "unique_ptr's deleter must be invocable with a pointer"); 00287 auto& __ptr = _M_t._M_ptr(); 00288 if (__ptr != nullptr) 00289 get_deleter()(std::move(__ptr)); 00290 __ptr = pointer(); 00291 } 00292 00293 // Assignment. 00294 00295 /** @brief Move assignment operator. 00296 * 00297 * @param __u The object to transfer ownership from. 00298 * 00299 * Invokes the deleter first if this object owns a pointer. 00300 */ 00301 unique_ptr& 00302 operator=(unique_ptr&& __u) noexcept 00303 { 00304 reset(__u.release()); 00305 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00306 return *this; 00307 } 00308 00309 /** @brief Assignment from another type. 00310 * 00311 * @param __u The object to transfer ownership from, which owns a 00312 * convertible pointer to a non-array object. 00313 * 00314 * Invokes the deleter first if this object owns a pointer. 00315 */ 00316 template<typename _Up, typename _Ep> 00317 typename enable_if< __and_< 00318 __safe_conversion_up<_Up, _Ep>, 00319 is_assignable<deleter_type&, _Ep&&> 00320 >::value, 00321 unique_ptr&>::type 00322 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00323 { 00324 reset(__u.release()); 00325 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00326 return *this; 00327 } 00328 00329 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00330 unique_ptr& 00331 operator=(nullptr_t) noexcept 00332 { 00333 reset(); 00334 return *this; 00335 } 00336 00337 // Observers. 00338 00339 /// Dereference the stored pointer. 00340 typename add_lvalue_reference<element_type>::type 00341 operator*() const 00342 { 00343 __glibcxx_assert(get() != pointer()); 00344 return *get(); 00345 } 00346 00347 /// Return the stored pointer. 00348 pointer 00349 operator->() const noexcept 00350 { 00351 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); 00352 return get(); 00353 } 00354 00355 /// Return the stored pointer. 00356 pointer 00357 get() const noexcept 00358 { return _M_t._M_ptr(); } 00359 00360 /// Return a reference to the stored deleter. 00361 deleter_type& 00362 get_deleter() noexcept 00363 { return _M_t._M_deleter(); } 00364 00365 /// Return a reference to the stored deleter. 00366 const deleter_type& 00367 get_deleter() const noexcept 00368 { return _M_t._M_deleter(); } 00369 00370 /// Return @c true if the stored pointer is not null. 00371 explicit operator bool() const noexcept 00372 { return get() == pointer() ? false : true; } 00373 00374 // Modifiers. 00375 00376 /// Release ownership of any stored pointer. 00377 pointer 00378 release() noexcept 00379 { 00380 pointer __p = get(); 00381 _M_t._M_ptr() = pointer(); 00382 return __p; 00383 } 00384 00385 /** @brief Replace the stored pointer. 00386 * 00387 * @param __p The new pointer to store. 00388 * 00389 * The deleter will be invoked if a pointer is already owned. 00390 */ 00391 void 00392 reset(pointer __p = pointer()) noexcept 00393 { 00394 static_assert(__is_invocable<deleter_type&, pointer>::value, 00395 "unique_ptr's deleter must be invocable with a pointer"); 00396 using std::swap; 00397 swap(_M_t._M_ptr(), __p); 00398 if (__p != pointer()) 00399 get_deleter()(std::move(__p)); 00400 } 00401 00402 /// Exchange the pointer and deleter with another object. 00403 void 00404 swap(unique_ptr& __u) noexcept 00405 { 00406 using std::swap; 00407 swap(_M_t, __u._M_t); 00408 } 00409 00410 // Disable copy from lvalue. 00411 unique_ptr(const unique_ptr&) = delete; 00412 unique_ptr& operator=(const unique_ptr&) = delete; 00413 }; 00414 00415 /// 20.7.1.3 unique_ptr for array objects with a runtime length 00416 // [unique.ptr.runtime] 00417 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00418 // DR 740 - omit specialization for array objects with a compile time length 00419 template<typename _Tp, typename _Dp> 00420 class unique_ptr<_Tp[], _Dp> 00421 { 00422 template <typename _Up> 00423 using _DeleterConstraint = 00424 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; 00425 00426 __uniq_ptr_impl<_Tp, _Dp> _M_t; 00427 00428 template<typename _Up> 00429 using __remove_cv = typename remove_cv<_Up>::type; 00430 00431 // like is_base_of<_Tp, _Up> but false if unqualified types are the same 00432 template<typename _Up> 00433 using __is_derived_Tp 00434 = __and_< is_base_of<_Tp, _Up>, 00435 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 00436 00437 public: 00438 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; 00439 using element_type = _Tp; 00440 using deleter_type = _Dp; 00441 00442 // helper template for detecting a safe conversion from another 00443 // unique_ptr 00444 template<typename _Up, typename _Ep, 00445 typename _Up_up = unique_ptr<_Up, _Ep>, 00446 typename _Up_element_type = typename _Up_up::element_type> 00447 using __safe_conversion_up = __and_< 00448 is_array<_Up>, 00449 is_same<pointer, element_type*>, 00450 is_same<typename _Up_up::pointer, _Up_element_type*>, 00451 is_convertible<_Up_element_type(*)[], element_type(*)[]>, 00452 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>, 00453 __and_<__not_<is_reference<deleter_type>>, 00454 is_convertible<_Ep, deleter_type>>> 00455 >; 00456 00457 // helper template for detecting a safe conversion from a raw pointer 00458 template<typename _Up> 00459 using __safe_conversion_raw = __and_< 00460 __or_<__or_<is_same<_Up, pointer>, 00461 is_same<_Up, nullptr_t>>, 00462 __and_<is_pointer<_Up>, 00463 is_same<pointer, element_type*>, 00464 is_convertible< 00465 typename remove_pointer<_Up>::type(*)[], 00466 element_type(*)[]> 00467 > 00468 > 00469 >; 00470 00471 // Constructors. 00472 00473 /// Default constructor, creates a unique_ptr that owns nothing. 00474 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00475 constexpr unique_ptr() noexcept 00476 : _M_t() 00477 { } 00478 00479 /** Takes ownership of a pointer. 00480 * 00481 * @param __p A pointer to an array of a type safely convertible 00482 * to an array of @c element_type 00483 * 00484 * The deleter will be value-initialized. 00485 */ 00486 template<typename _Up, 00487 typename _Vp = _Dp, 00488 typename = _DeleterConstraint<_Vp>, 00489 typename = typename enable_if< 00490 __safe_conversion_raw<_Up>::value, bool>::type> 00491 explicit 00492 unique_ptr(_Up __p) noexcept 00493 : _M_t(__p) 00494 { } 00495 00496 /** Takes ownership of a pointer. 00497 * 00498 * @param __p A pointer to an array of a type safely convertible 00499 * to an array of @c element_type 00500 * @param __d A reference to a deleter. 00501 * 00502 * The deleter will be initialized with @p __d 00503 */ 00504 template<typename _Up, typename _Del = deleter_type, 00505 typename = _Require<__safe_conversion_raw<_Up>, 00506 is_copy_constructible<_Del>>> 00507 unique_ptr(_Up __p, const deleter_type& __d) noexcept 00508 : _M_t(__p, __d) { } 00509 00510 /** Takes ownership of a pointer. 00511 * 00512 * @param __p A pointer to an array of a type safely convertible 00513 * to an array of @c element_type 00514 * @param __d A reference to a deleter. 00515 * 00516 * The deleter will be initialized with @p std::move(__d) 00517 */ 00518 template<typename _Up, typename _Del = deleter_type, 00519 typename = _Require<__safe_conversion_raw<_Up>, 00520 is_move_constructible<_Del>>> 00521 unique_ptr(_Up __p, 00522 __enable_if_t<!is_lvalue_reference<_Del>::value, 00523 _Del&&> __d) noexcept 00524 : _M_t(std::move(__p), std::move(__d)) 00525 { } 00526 00527 template<typename _Up, typename _Del = deleter_type, 00528 typename _DelUnref = typename remove_reference<_Del>::type, 00529 typename = _Require<__safe_conversion_raw<_Up>>> 00530 unique_ptr(_Up, 00531 __enable_if_t<is_lvalue_reference<_Del>::value, 00532 _DelUnref&&>) = delete; 00533 00534 /// Move constructor. 00535 unique_ptr(unique_ptr&& __u) noexcept 00536 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00537 00538 /// Creates a unique_ptr that owns nothing. 00539 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> 00540 constexpr unique_ptr(nullptr_t) noexcept 00541 : _M_t() 00542 { } 00543 00544 template<typename _Up, typename _Ep, 00545 typename = _Require<__safe_conversion_up<_Up, _Ep>>> 00546 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00547 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00548 { } 00549 00550 /// Destructor, invokes the deleter if the stored pointer is not null. 00551 ~unique_ptr() 00552 { 00553 auto& __ptr = _M_t._M_ptr(); 00554 if (__ptr != nullptr) 00555 get_deleter()(__ptr); 00556 __ptr = pointer(); 00557 } 00558 00559 // Assignment. 00560 00561 /** @brief Move assignment operator. 00562 * 00563 * @param __u The object to transfer ownership from. 00564 * 00565 * Invokes the deleter first if this object owns a pointer. 00566 */ 00567 unique_ptr& 00568 operator=(unique_ptr&& __u) noexcept 00569 { 00570 reset(__u.release()); 00571 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00572 return *this; 00573 } 00574 00575 /** @brief Assignment from another type. 00576 * 00577 * @param __u The object to transfer ownership from, which owns a 00578 * convertible pointer to an array object. 00579 * 00580 * Invokes the deleter first if this object owns a pointer. 00581 */ 00582 template<typename _Up, typename _Ep> 00583 typename 00584 enable_if<__and_<__safe_conversion_up<_Up, _Ep>, 00585 is_assignable<deleter_type&, _Ep&&> 00586 >::value, 00587 unique_ptr&>::type 00588 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00589 { 00590 reset(__u.release()); 00591 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00592 return *this; 00593 } 00594 00595 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00596 unique_ptr& 00597 operator=(nullptr_t) noexcept 00598 { 00599 reset(); 00600 return *this; 00601 } 00602 00603 // Observers. 00604 00605 /// Access an element of owned array. 00606 typename std::add_lvalue_reference<element_type>::type 00607 operator[](size_t __i) const 00608 { 00609 __glibcxx_assert(get() != pointer()); 00610 return get()[__i]; 00611 } 00612 00613 /// Return the stored pointer. 00614 pointer 00615 get() const noexcept 00616 { return _M_t._M_ptr(); } 00617 00618 /// Return a reference to the stored deleter. 00619 deleter_type& 00620 get_deleter() noexcept 00621 { return _M_t._M_deleter(); } 00622 00623 /// Return a reference to the stored deleter. 00624 const deleter_type& 00625 get_deleter() const noexcept 00626 { return _M_t._M_deleter(); } 00627 00628 /// Return @c true if the stored pointer is not null. 00629 explicit operator bool() const noexcept 00630 { return get() == pointer() ? false : true; } 00631 00632 // Modifiers. 00633 00634 /// Release ownership of any stored pointer. 00635 pointer 00636 release() noexcept 00637 { 00638 pointer __p = get(); 00639 _M_t._M_ptr() = pointer(); 00640 return __p; 00641 } 00642 00643 /** @brief Replace the stored pointer. 00644 * 00645 * @param __p The new pointer to store. 00646 * 00647 * The deleter will be invoked if a pointer is already owned. 00648 */ 00649 template <typename _Up, 00650 typename = _Require< 00651 __or_<is_same<_Up, pointer>, 00652 __and_<is_same<pointer, element_type*>, 00653 is_pointer<_Up>, 00654 is_convertible< 00655 typename remove_pointer<_Up>::type(*)[], 00656 element_type(*)[] 00657 > 00658 > 00659 > 00660 >> 00661 void 00662 reset(_Up __p) noexcept 00663 { 00664 pointer __ptr = __p; 00665 using std::swap; 00666 swap(_M_t._M_ptr(), __ptr); 00667 if (__ptr != nullptr) 00668 get_deleter()(__ptr); 00669 } 00670 00671 void reset(nullptr_t = nullptr) noexcept 00672 { 00673 reset(pointer()); 00674 } 00675 00676 /// Exchange the pointer and deleter with another object. 00677 void 00678 swap(unique_ptr& __u) noexcept 00679 { 00680 using std::swap; 00681 swap(_M_t, __u._M_t); 00682 } 00683 00684 // Disable copy from lvalue. 00685 unique_ptr(const unique_ptr&) = delete; 00686 unique_ptr& operator=(const unique_ptr&) = delete; 00687 }; 00688 00689 template<typename _Tp, typename _Dp> 00690 inline 00691 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 00692 // Constrained free swap overload, see p0185r1 00693 typename enable_if<__is_swappable<_Dp>::value>::type 00694 #else 00695 void 00696 #endif 00697 swap(unique_ptr<_Tp, _Dp>& __x, 00698 unique_ptr<_Tp, _Dp>& __y) noexcept 00699 { __x.swap(__y); } 00700 00701 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 00702 template<typename _Tp, typename _Dp> 00703 typename enable_if<!__is_swappable<_Dp>::value>::type 00704 swap(unique_ptr<_Tp, _Dp>&, 00705 unique_ptr<_Tp, _Dp>&) = delete; 00706 #endif 00707 00708 template<typename _Tp, typename _Dp, 00709 typename _Up, typename _Ep> 00710 _GLIBCXX_NODISCARD inline bool 00711 operator==(const unique_ptr<_Tp, _Dp>& __x, 00712 const unique_ptr<_Up, _Ep>& __y) 00713 { return __x.get() == __y.get(); } 00714 00715 template<typename _Tp, typename _Dp> 00716 _GLIBCXX_NODISCARD inline bool 00717 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00718 { return !__x; } 00719 00720 template<typename _Tp, typename _Dp> 00721 _GLIBCXX_NODISCARD inline bool 00722 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00723 { return !__x; } 00724 00725 template<typename _Tp, typename _Dp, 00726 typename _Up, typename _Ep> 00727 _GLIBCXX_NODISCARD inline bool 00728 operator!=(const unique_ptr<_Tp, _Dp>& __x, 00729 const unique_ptr<_Up, _Ep>& __y) 00730 { return __x.get() != __y.get(); } 00731 00732 template<typename _Tp, typename _Dp> 00733 _GLIBCXX_NODISCARD inline bool 00734 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00735 { return (bool)__x; } 00736 00737 template<typename _Tp, typename _Dp> 00738 _GLIBCXX_NODISCARD inline bool 00739 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00740 { return (bool)__x; } 00741 00742 template<typename _Tp, typename _Dp, 00743 typename _Up, typename _Ep> 00744 _GLIBCXX_NODISCARD inline bool 00745 operator<(const unique_ptr<_Tp, _Dp>& __x, 00746 const unique_ptr<_Up, _Ep>& __y) 00747 { 00748 typedef typename 00749 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 00750 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 00751 return std::less<_CT>()(__x.get(), __y.get()); 00752 } 00753 00754 template<typename _Tp, typename _Dp> 00755 _GLIBCXX_NODISCARD inline bool 00756 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00757 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00758 nullptr); } 00759 00760 template<typename _Tp, typename _Dp> 00761 _GLIBCXX_NODISCARD inline bool 00762 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00763 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00764 __x.get()); } 00765 00766 template<typename _Tp, typename _Dp, 00767 typename _Up, typename _Ep> 00768 _GLIBCXX_NODISCARD inline bool 00769 operator<=(const unique_ptr<_Tp, _Dp>& __x, 00770 const unique_ptr<_Up, _Ep>& __y) 00771 { return !(__y < __x); } 00772 00773 template<typename _Tp, typename _Dp> 00774 _GLIBCXX_NODISCARD inline bool 00775 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00776 { return !(nullptr < __x); } 00777 00778 template<typename _Tp, typename _Dp> 00779 _GLIBCXX_NODISCARD inline bool 00780 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00781 { return !(__x < nullptr); } 00782 00783 template<typename _Tp, typename _Dp, 00784 typename _Up, typename _Ep> 00785 _GLIBCXX_NODISCARD inline bool 00786 operator>(const unique_ptr<_Tp, _Dp>& __x, 00787 const unique_ptr<_Up, _Ep>& __y) 00788 { return (__y < __x); } 00789 00790 template<typename _Tp, typename _Dp> 00791 _GLIBCXX_NODISCARD inline bool 00792 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00793 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00794 __x.get()); } 00795 00796 template<typename _Tp, typename _Dp> 00797 _GLIBCXX_NODISCARD inline bool 00798 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00799 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00800 nullptr); } 00801 00802 template<typename _Tp, typename _Dp, 00803 typename _Up, typename _Ep> 00804 _GLIBCXX_NODISCARD inline bool 00805 operator>=(const unique_ptr<_Tp, _Dp>& __x, 00806 const unique_ptr<_Up, _Ep>& __y) 00807 { return !(__x < __y); } 00808 00809 template<typename _Tp, typename _Dp> 00810 _GLIBCXX_NODISCARD inline bool 00811 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00812 { return !(__x < nullptr); } 00813 00814 template<typename _Tp, typename _Dp> 00815 _GLIBCXX_NODISCARD inline bool 00816 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00817 { return !(nullptr < __x); } 00818 00819 /// std::hash specialization for unique_ptr. 00820 template<typename _Tp, typename _Dp> 00821 struct hash<unique_ptr<_Tp, _Dp>> 00822 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, 00823 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer> 00824 { 00825 size_t 00826 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept 00827 { 00828 typedef unique_ptr<_Tp, _Dp> _UP; 00829 return std::hash<typename _UP::pointer>()(__u.get()); 00830 } 00831 }; 00832 00833 #if __cplusplus > 201103L 00834 00835 #define __cpp_lib_make_unique 201304 00836 00837 template<typename _Tp> 00838 struct _MakeUniq 00839 { typedef unique_ptr<_Tp> __single_object; }; 00840 00841 template<typename _Tp> 00842 struct _MakeUniq<_Tp[]> 00843 { typedef unique_ptr<_Tp[]> __array; }; 00844 00845 template<typename _Tp, size_t _Bound> 00846 struct _MakeUniq<_Tp[_Bound]> 00847 { struct __invalid_type { }; }; 00848 00849 /// std::make_unique for single objects 00850 template<typename _Tp, typename... _Args> 00851 inline typename _MakeUniq<_Tp>::__single_object 00852 make_unique(_Args&&... __args) 00853 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } 00854 00855 /// std::make_unique for arrays of unknown bound 00856 template<typename _Tp> 00857 inline typename _MakeUniq<_Tp>::__array 00858 make_unique(size_t __num) 00859 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } 00860 00861 /// Disable std::make_unique for arrays of known bound 00862 template<typename _Tp, typename... _Args> 00863 inline typename _MakeUniq<_Tp>::__invalid_type 00864 make_unique(_Args&&...) = delete; 00865 #endif 00866 00867 // @} group pointer_abstractions 00868 00869 #if __cplusplus >= 201703L 00870 namespace __detail::__variant 00871 { 00872 template<typename> struct _Never_valueless_alt; // see <variant> 00873 00874 // Provide the strong exception-safety guarantee when emplacing a 00875 // unique_ptr into a variant. 00876 template<typename _Tp, typename _Del> 00877 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>> 00878 : std::true_type 00879 { }; 00880 } // namespace __detail::__variant 00881 #endif // C++17 00882 00883 _GLIBCXX_END_NAMESPACE_VERSION 00884 } // namespace 00885 00886 #endif /* _UNIQUE_PTR_H */