libstdc++
|
00001 // unique_ptr implementation -*- C++ -*- 00002 00003 // Copyright (C) 2008-2013 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/debug.h> 00035 #include <type_traits> 00036 #include <utility> 00037 #include <tuple> 00038 00039 namespace std _GLIBCXX_VISIBILITY(default) 00040 { 00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00042 00043 /** 00044 * @addtogroup pointer_abstractions 00045 * @{ 00046 */ 00047 00048 #if _GLIBCXX_USE_DEPRECATED 00049 template<typename> class auto_ptr; 00050 #endif 00051 00052 /// Primary template, default_delete. 00053 template<typename _Tp> 00054 struct default_delete 00055 { 00056 constexpr default_delete() noexcept = default; 00057 00058 template<typename _Up, typename = typename 00059 enable_if<is_convertible<_Up*, _Tp*>::value>::type> 00060 default_delete(const default_delete<_Up>&) noexcept { } 00061 00062 void 00063 operator()(_Tp* __ptr) const 00064 { 00065 static_assert(sizeof(_Tp)>0, 00066 "can't delete pointer to incomplete type"); 00067 delete __ptr; 00068 } 00069 }; 00070 00071 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00072 // DR 740 - omit specialization for array objects with a compile time length 00073 /// Specialization, default_delete. 00074 template<typename _Tp> 00075 struct default_delete<_Tp[]> 00076 { 00077 private: 00078 template<typename _Up> 00079 using __remove_cv = typename remove_cv<_Up>::type; 00080 00081 // Like is_base_of<_Tp, _Up> but false if unqualified types are the same 00082 template<typename _Up> 00083 using __is_derived_Tp 00084 = __and_< is_base_of<_Tp, _Up>, 00085 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 00086 00087 public: 00088 constexpr default_delete() noexcept = default; 00089 00090 template<typename _Up, typename = typename 00091 enable_if<!__is_derived_Tp<_Up>::value>::type> 00092 default_delete(const default_delete<_Up[]>&) noexcept { } 00093 00094 void 00095 operator()(_Tp* __ptr) const 00096 { 00097 static_assert(sizeof(_Tp)>0, 00098 "can't delete pointer to incomplete type"); 00099 delete [] __ptr; 00100 } 00101 00102 template<typename _Up> 00103 typename enable_if<__is_derived_Tp<_Up>::value>::type 00104 operator()(_Up*) const = delete; 00105 }; 00106 00107 /// 20.7.1.2 unique_ptr for single objects. 00108 template <typename _Tp, typename _Dp = default_delete<_Tp> > 00109 class unique_ptr 00110 { 00111 // use SFINAE to determine whether _Del::pointer exists 00112 class _Pointer 00113 { 00114 template<typename _Up> 00115 static typename _Up::pointer __test(typename _Up::pointer*); 00116 00117 template<typename _Up> 00118 static _Tp* __test(...); 00119 00120 typedef typename remove_reference<_Dp>::type _Del; 00121 00122 public: 00123 typedef decltype(__test<_Del>(0)) type; 00124 }; 00125 00126 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; 00127 __tuple_type _M_t; 00128 00129 public: 00130 typedef typename _Pointer::type pointer; 00131 typedef _Tp element_type; 00132 typedef _Dp deleter_type; 00133 00134 // Constructors. 00135 constexpr unique_ptr() noexcept 00136 : _M_t() 00137 { static_assert(!is_pointer<deleter_type>::value, 00138 "constructed with null function pointer deleter"); } 00139 00140 explicit 00141 unique_ptr(pointer __p) noexcept 00142 : _M_t(__p, deleter_type()) 00143 { static_assert(!is_pointer<deleter_type>::value, 00144 "constructed with null function pointer deleter"); } 00145 00146 unique_ptr(pointer __p, 00147 typename conditional<is_reference<deleter_type>::value, 00148 deleter_type, const deleter_type&>::type __d) noexcept 00149 : _M_t(__p, __d) { } 00150 00151 unique_ptr(pointer __p, 00152 typename remove_reference<deleter_type>::type&& __d) noexcept 00153 : _M_t(std::move(__p), std::move(__d)) 00154 { static_assert(!std::is_reference<deleter_type>::value, 00155 "rvalue deleter bound to reference"); } 00156 00157 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } 00158 00159 // Move constructors. 00160 unique_ptr(unique_ptr&& __u) noexcept 00161 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00162 00163 template<typename _Up, typename _Ep, typename = _Require< 00164 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00165 __not_<is_array<_Up>>, 00166 typename conditional<is_reference<_Dp>::value, 00167 is_same<_Ep, _Dp>, 00168 is_convertible<_Ep, _Dp>>::type>> 00169 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00170 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00171 { } 00172 00173 #if _GLIBCXX_USE_DEPRECATED 00174 template<typename _Up, typename = _Require< 00175 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 00176 unique_ptr(auto_ptr<_Up>&& __u) noexcept; 00177 #endif 00178 00179 // Destructor. 00180 ~unique_ptr() noexcept 00181 { 00182 auto& __ptr = std::get<0>(_M_t); 00183 if (__ptr != nullptr) 00184 get_deleter()(__ptr); 00185 __ptr = pointer(); 00186 } 00187 00188 // Assignment. 00189 unique_ptr& 00190 operator=(unique_ptr&& __u) noexcept 00191 { 00192 reset(__u.release()); 00193 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00194 return *this; 00195 } 00196 00197 template<typename _Up, typename _Ep> 00198 typename enable_if< __and_< 00199 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00200 __not_<is_array<_Up>> 00201 >::value, 00202 unique_ptr&>::type 00203 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00204 { 00205 reset(__u.release()); 00206 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00207 return *this; 00208 } 00209 00210 unique_ptr& 00211 operator=(nullptr_t) noexcept 00212 { 00213 reset(); 00214 return *this; 00215 } 00216 00217 // Observers. 00218 typename add_lvalue_reference<element_type>::type 00219 operator*() const 00220 { 00221 _GLIBCXX_DEBUG_ASSERT(get() != pointer()); 00222 return *get(); 00223 } 00224 00225 pointer 00226 operator->() const noexcept 00227 { 00228 _GLIBCXX_DEBUG_ASSERT(get() != pointer()); 00229 return get(); 00230 } 00231 00232 pointer 00233 get() const noexcept 00234 { return std::get<0>(_M_t); } 00235 00236 deleter_type& 00237 get_deleter() noexcept 00238 { return std::get<1>(_M_t); } 00239 00240 const deleter_type& 00241 get_deleter() const noexcept 00242 { return std::get<1>(_M_t); } 00243 00244 explicit operator bool() const noexcept 00245 { return get() == pointer() ? false : true; } 00246 00247 // Modifiers. 00248 pointer 00249 release() noexcept 00250 { 00251 pointer __p = get(); 00252 std::get<0>(_M_t) = pointer(); 00253 return __p; 00254 } 00255 00256 void 00257 reset(pointer __p = pointer()) noexcept 00258 { 00259 using std::swap; 00260 swap(std::get<0>(_M_t), __p); 00261 if (__p != pointer()) 00262 get_deleter()(__p); 00263 } 00264 00265 void 00266 swap(unique_ptr& __u) noexcept 00267 { 00268 using std::swap; 00269 swap(_M_t, __u._M_t); 00270 } 00271 00272 // Disable copy from lvalue. 00273 unique_ptr(const unique_ptr&) = delete; 00274 unique_ptr& operator=(const unique_ptr&) = delete; 00275 }; 00276 00277 /// 20.7.1.3 unique_ptr for array objects with a runtime length 00278 // [unique.ptr.runtime] 00279 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00280 // DR 740 - omit specialization for array objects with a compile time length 00281 template<typename _Tp, typename _Dp> 00282 class unique_ptr<_Tp[], _Dp> 00283 { 00284 // use SFINAE to determine whether _Del::pointer exists 00285 class _Pointer 00286 { 00287 template<typename _Up> 00288 static typename _Up::pointer __test(typename _Up::pointer*); 00289 00290 template<typename _Up> 00291 static _Tp* __test(...); 00292 00293 typedef typename remove_reference<_Dp>::type _Del; 00294 00295 public: 00296 typedef decltype(__test<_Del>(0)) type; 00297 }; 00298 00299 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; 00300 __tuple_type _M_t; 00301 00302 template<typename _Up> 00303 using __remove_cv = typename remove_cv<_Up>::type; 00304 00305 // like is_base_of<_Tp, _Up> but false if unqualified types are the same 00306 template<typename _Up> 00307 using __is_derived_Tp 00308 = __and_< is_base_of<_Tp, _Up>, 00309 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 00310 00311 template<typename _Up, typename _Ep, 00312 typename _Tp_pointer = typename _Pointer::type, 00313 typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer> 00314 using __safe_conversion = __and_< 00315 is_convertible<_Up_pointer, _Tp_pointer>, 00316 is_array<_Up>, 00317 __or_<__not_<is_pointer<_Up_pointer>>, 00318 __not_<is_pointer<_Tp_pointer>>, 00319 __not_<__is_derived_Tp<typename remove_extent<_Up>::type>> 00320 > 00321 >; 00322 00323 public: 00324 typedef typename _Pointer::type pointer; 00325 typedef _Tp element_type; 00326 typedef _Dp deleter_type; 00327 00328 // Constructors. 00329 constexpr unique_ptr() noexcept 00330 : _M_t() 00331 { static_assert(!std::is_pointer<deleter_type>::value, 00332 "constructed with null function pointer deleter"); } 00333 00334 explicit 00335 unique_ptr(pointer __p) noexcept 00336 : _M_t(__p, deleter_type()) 00337 { static_assert(!is_pointer<deleter_type>::value, 00338 "constructed with null function pointer deleter"); } 00339 00340 template<typename _Up, typename = _Require<is_pointer<pointer>, 00341 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00342 explicit 00343 unique_ptr(_Up* __p) = delete; 00344 00345 unique_ptr(pointer __p, 00346 typename conditional<is_reference<deleter_type>::value, 00347 deleter_type, const deleter_type&>::type __d) noexcept 00348 : _M_t(__p, __d) { } 00349 00350 unique_ptr(pointer __p, typename 00351 remove_reference<deleter_type>::type&& __d) noexcept 00352 : _M_t(std::move(__p), std::move(__d)) 00353 { static_assert(!is_reference<deleter_type>::value, 00354 "rvalue deleter bound to reference"); } 00355 00356 // Move constructor. 00357 unique_ptr(unique_ptr&& __u) noexcept 00358 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00359 00360 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } 00361 00362 template<typename _Up, typename _Ep, 00363 typename = _Require<__safe_conversion<_Up, _Ep>, 00364 typename conditional<is_reference<_Dp>::value, 00365 is_same<_Ep, _Dp>, 00366 is_convertible<_Ep, _Dp>>::type 00367 >> 00368 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00369 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00370 { } 00371 00372 // Destructor. 00373 ~unique_ptr() 00374 { 00375 auto& __ptr = std::get<0>(_M_t); 00376 if (__ptr != nullptr) 00377 get_deleter()(__ptr); 00378 __ptr = pointer(); 00379 } 00380 00381 // Assignment. 00382 unique_ptr& 00383 operator=(unique_ptr&& __u) noexcept 00384 { 00385 reset(__u.release()); 00386 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00387 return *this; 00388 } 00389 00390 template<typename _Up, typename _Ep> 00391 typename 00392 enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type 00393 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00394 { 00395 reset(__u.release()); 00396 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00397 return *this; 00398 } 00399 00400 unique_ptr& 00401 operator=(nullptr_t) noexcept 00402 { 00403 reset(); 00404 return *this; 00405 } 00406 00407 // Observers. 00408 typename std::add_lvalue_reference<element_type>::type 00409 operator[](size_t __i) const 00410 { 00411 _GLIBCXX_DEBUG_ASSERT(get() != pointer()); 00412 return get()[__i]; 00413 } 00414 00415 pointer 00416 get() const noexcept 00417 { return std::get<0>(_M_t); } 00418 00419 deleter_type& 00420 get_deleter() noexcept 00421 { return std::get<1>(_M_t); } 00422 00423 const deleter_type& 00424 get_deleter() const noexcept 00425 { return std::get<1>(_M_t); } 00426 00427 explicit operator bool() const noexcept 00428 { return get() == pointer() ? false : true; } 00429 00430 // Modifiers. 00431 pointer 00432 release() noexcept 00433 { 00434 pointer __p = get(); 00435 std::get<0>(_M_t) = pointer(); 00436 return __p; 00437 } 00438 00439 void 00440 reset() noexcept 00441 { reset(pointer()); } 00442 00443 void 00444 reset(pointer __p) noexcept 00445 { 00446 using std::swap; 00447 swap(std::get<0>(_M_t), __p); 00448 if (__p != nullptr) 00449 get_deleter()(__p); 00450 } 00451 00452 template<typename _Up, typename = _Require<is_pointer<pointer>, 00453 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00454 void reset(_Up*) = delete; 00455 00456 void 00457 swap(unique_ptr& __u) noexcept 00458 { 00459 using std::swap; 00460 swap(_M_t, __u._M_t); 00461 } 00462 00463 // Disable copy from lvalue. 00464 unique_ptr(const unique_ptr&) = delete; 00465 unique_ptr& operator=(const unique_ptr&) = delete; 00466 00467 // Disable construction from convertible pointer types. 00468 template<typename _Up, typename = _Require<is_pointer<pointer>, 00469 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00470 unique_ptr(_Up*, typename 00471 conditional<is_reference<deleter_type>::value, 00472 deleter_type, const deleter_type&>::type) = delete; 00473 00474 template<typename _Up, typename = _Require<is_pointer<pointer>, 00475 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00476 unique_ptr(_Up*, typename 00477 remove_reference<deleter_type>::type&&) = delete; 00478 }; 00479 00480 template<typename _Tp, typename _Dp> 00481 inline void 00482 swap(unique_ptr<_Tp, _Dp>& __x, 00483 unique_ptr<_Tp, _Dp>& __y) noexcept 00484 { __x.swap(__y); } 00485 00486 template<typename _Tp, typename _Dp, 00487 typename _Up, typename _Ep> 00488 inline bool 00489 operator==(const unique_ptr<_Tp, _Dp>& __x, 00490 const unique_ptr<_Up, _Ep>& __y) 00491 { return __x.get() == __y.get(); } 00492 00493 template<typename _Tp, typename _Dp> 00494 inline bool 00495 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00496 { return !__x; } 00497 00498 template<typename _Tp, typename _Dp> 00499 inline bool 00500 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00501 { return !__x; } 00502 00503 template<typename _Tp, typename _Dp, 00504 typename _Up, typename _Ep> 00505 inline bool 00506 operator!=(const unique_ptr<_Tp, _Dp>& __x, 00507 const unique_ptr<_Up, _Ep>& __y) 00508 { return __x.get() != __y.get(); } 00509 00510 template<typename _Tp, typename _Dp> 00511 inline bool 00512 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00513 { return (bool)__x; } 00514 00515 template<typename _Tp, typename _Dp> 00516 inline bool 00517 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00518 { return (bool)__x; } 00519 00520 template<typename _Tp, typename _Dp, 00521 typename _Up, typename _Ep> 00522 inline bool 00523 operator<(const unique_ptr<_Tp, _Dp>& __x, 00524 const unique_ptr<_Up, _Ep>& __y) 00525 { 00526 typedef typename 00527 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 00528 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 00529 return std::less<_CT>()(__x.get(), __y.get()); 00530 } 00531 00532 template<typename _Tp, typename _Dp> 00533 inline bool 00534 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00535 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00536 nullptr); } 00537 00538 template<typename _Tp, typename _Dp> 00539 inline bool 00540 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00541 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00542 __x.get()); } 00543 00544 template<typename _Tp, typename _Dp, 00545 typename _Up, typename _Ep> 00546 inline bool 00547 operator<=(const unique_ptr<_Tp, _Dp>& __x, 00548 const unique_ptr<_Up, _Ep>& __y) 00549 { return !(__y < __x); } 00550 00551 template<typename _Tp, typename _Dp> 00552 inline bool 00553 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00554 { return !(nullptr < __x); } 00555 00556 template<typename _Tp, typename _Dp> 00557 inline bool 00558 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00559 { return !(__x < nullptr); } 00560 00561 template<typename _Tp, typename _Dp, 00562 typename _Up, typename _Ep> 00563 inline bool 00564 operator>(const unique_ptr<_Tp, _Dp>& __x, 00565 const unique_ptr<_Up, _Ep>& __y) 00566 { return (__y < __x); } 00567 00568 template<typename _Tp, typename _Dp> 00569 inline bool 00570 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00571 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00572 __x.get()); } 00573 00574 template<typename _Tp, typename _Dp> 00575 inline bool 00576 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00577 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00578 nullptr); } 00579 00580 template<typename _Tp, typename _Dp, 00581 typename _Up, typename _Ep> 00582 inline bool 00583 operator>=(const unique_ptr<_Tp, _Dp>& __x, 00584 const unique_ptr<_Up, _Ep>& __y) 00585 { return !(__x < __y); } 00586 00587 template<typename _Tp, typename _Dp> 00588 inline bool 00589 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00590 { return !(__x < nullptr); } 00591 00592 template<typename _Tp, typename _Dp> 00593 inline bool 00594 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00595 { return !(nullptr < __x); } 00596 00597 /// std::hash specialization for unique_ptr. 00598 template<typename _Tp, typename _Dp> 00599 struct hash<unique_ptr<_Tp, _Dp>> 00600 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>> 00601 { 00602 size_t 00603 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept 00604 { 00605 typedef unique_ptr<_Tp, _Dp> _UP; 00606 return std::hash<typename _UP::pointer>()(__u.get()); 00607 } 00608 }; 00609 00610 // @} group pointer_abstractions 00611 00612 _GLIBCXX_END_NAMESPACE_VERSION 00613 } // namespace 00614 00615 #endif /* _UNIQUE_PTR_H */