libstdc++
|
00001 // unique_ptr implementation -*- C++ -*- 00002 00003 // Copyright (C) 2008-2015 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 of default_delete, used by unique_ptr 00053 template<typename _Tp> 00054 struct default_delete 00055 { 00056 /// Default constructor 00057 constexpr default_delete() noexcept = default; 00058 00059 /** @brief Converting constructor. 00060 * 00061 * Allows conversion from a deleter for arrays of another type, @p _Up, 00062 * only if @p _Up* is convertible to @p _Tp*. 00063 */ 00064 template<typename _Up, typename = typename 00065 enable_if<is_convertible<_Up*, _Tp*>::value>::type> 00066 default_delete(const default_delete<_Up>&) noexcept { } 00067 00068 /// Calls @c delete @p __ptr 00069 void 00070 operator()(_Tp* __ptr) const 00071 { 00072 static_assert(!is_void<_Tp>::value, 00073 "can't delete pointer to incomplete type"); 00074 static_assert(sizeof(_Tp)>0, 00075 "can't delete pointer to incomplete type"); 00076 delete __ptr; 00077 } 00078 }; 00079 00080 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00081 // DR 740 - omit specialization for array objects with a compile time length 00082 /// Specialization for arrays, default_delete. 00083 template<typename _Tp> 00084 struct default_delete<_Tp[]> 00085 { 00086 private: 00087 template<typename _Up> 00088 using __remove_cv = typename remove_cv<_Up>::type; 00089 00090 // Like is_base_of<_Tp, _Up> but false if unqualified types are the same 00091 template<typename _Up> 00092 using __is_derived_Tp 00093 = __and_< is_base_of<_Tp, _Up>, 00094 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 00095 00096 public: 00097 /// Default constructor 00098 constexpr default_delete() noexcept = default; 00099 00100 /** @brief Converting constructor. 00101 * 00102 * Allows conversion from a deleter for arrays of another type, such as 00103 * a const-qualified version of @p _Tp. 00104 * 00105 * Conversions from types derived from @c _Tp are not allowed because 00106 * it is unsafe to @c delete[] an array of derived types through a 00107 * pointer to the base type. 00108 */ 00109 template<typename _Up, typename = typename 00110 enable_if<!__is_derived_Tp<_Up>::value>::type> 00111 default_delete(const default_delete<_Up[]>&) noexcept { } 00112 00113 /// Calls @c delete[] @p __ptr 00114 void 00115 operator()(_Tp* __ptr) const 00116 { 00117 static_assert(sizeof(_Tp)>0, 00118 "can't delete pointer to incomplete type"); 00119 delete [] __ptr; 00120 } 00121 00122 template<typename _Up> 00123 typename enable_if<__is_derived_Tp<_Up>::value>::type 00124 operator()(_Up*) const = delete; 00125 }; 00126 00127 /// 20.7.1.2 unique_ptr for single objects. 00128 template <typename _Tp, typename _Dp = default_delete<_Tp> > 00129 class unique_ptr 00130 { 00131 // use SFINAE to determine whether _Del::pointer exists 00132 class _Pointer 00133 { 00134 template<typename _Up> 00135 static typename _Up::pointer __test(typename _Up::pointer*); 00136 00137 template<typename _Up> 00138 static _Tp* __test(...); 00139 00140 typedef typename remove_reference<_Dp>::type _Del; 00141 00142 public: 00143 typedef decltype(__test<_Del>(0)) type; 00144 }; 00145 00146 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; 00147 __tuple_type _M_t; 00148 00149 public: 00150 typedef typename _Pointer::type pointer; 00151 typedef _Tp element_type; 00152 typedef _Dp deleter_type; 00153 00154 // Constructors. 00155 00156 /// Default constructor, creates a unique_ptr that owns nothing. 00157 constexpr unique_ptr() noexcept 00158 : _M_t() 00159 { static_assert(!is_pointer<deleter_type>::value, 00160 "constructed with null function pointer deleter"); } 00161 00162 /** Takes ownership of a pointer. 00163 * 00164 * @param __p A pointer to an object of @c element_type 00165 * 00166 * The deleter will be value-initialized. 00167 */ 00168 explicit 00169 unique_ptr(pointer __p) noexcept 00170 : _M_t(__p, deleter_type()) 00171 { static_assert(!is_pointer<deleter_type>::value, 00172 "constructed with null function pointer deleter"); } 00173 00174 /** Takes ownership of a pointer. 00175 * 00176 * @param __p A pointer to an object of @c element_type 00177 * @param __d A reference to a deleter. 00178 * 00179 * The deleter will be initialized with @p __d 00180 */ 00181 unique_ptr(pointer __p, 00182 typename conditional<is_reference<deleter_type>::value, 00183 deleter_type, const deleter_type&>::type __d) noexcept 00184 : _M_t(__p, __d) { } 00185 00186 /** Takes ownership of a pointer. 00187 * 00188 * @param __p A pointer to an object of @c element_type 00189 * @param __d An rvalue reference to a deleter. 00190 * 00191 * The deleter will be initialized with @p std::move(__d) 00192 */ 00193 unique_ptr(pointer __p, 00194 typename remove_reference<deleter_type>::type&& __d) noexcept 00195 : _M_t(std::move(__p), std::move(__d)) 00196 { static_assert(!std::is_reference<deleter_type>::value, 00197 "rvalue deleter bound to reference"); } 00198 00199 /// Creates a unique_ptr that owns nothing. 00200 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } 00201 00202 // Move constructors. 00203 00204 /// Move constructor. 00205 unique_ptr(unique_ptr&& __u) noexcept 00206 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00207 00208 /** @brief Converting constructor from another type 00209 * 00210 * Requires that the pointer owned by @p __u is convertible to the 00211 * type of pointer owned by this object, @p __u does not own an array, 00212 * and @p __u has a compatible deleter type. 00213 */ 00214 template<typename _Up, typename _Ep, typename = _Require< 00215 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00216 __not_<is_array<_Up>>, 00217 typename conditional<is_reference<_Dp>::value, 00218 is_same<_Ep, _Dp>, 00219 is_convertible<_Ep, _Dp>>::type>> 00220 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00221 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00222 { } 00223 00224 #if _GLIBCXX_USE_DEPRECATED 00225 /// Converting constructor from @c auto_ptr 00226 template<typename _Up, typename = _Require< 00227 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 00228 unique_ptr(auto_ptr<_Up>&& __u) noexcept; 00229 #endif 00230 00231 /// Destructor, invokes the deleter if the stored pointer is not null. 00232 ~unique_ptr() noexcept 00233 { 00234 auto& __ptr = std::get<0>(_M_t); 00235 if (__ptr != nullptr) 00236 get_deleter()(__ptr); 00237 __ptr = pointer(); 00238 } 00239 00240 // Assignment. 00241 00242 /** @brief Move assignment operator. 00243 * 00244 * @param __u The object to transfer ownership from. 00245 * 00246 * Invokes the deleter first if this object owns a pointer. 00247 */ 00248 unique_ptr& 00249 operator=(unique_ptr&& __u) noexcept 00250 { 00251 reset(__u.release()); 00252 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00253 return *this; 00254 } 00255 00256 /** @brief Assignment from another type. 00257 * 00258 * @param __u The object to transfer ownership from, which owns a 00259 * convertible pointer to a non-array object. 00260 * 00261 * Invokes the deleter first if this object owns a pointer. 00262 */ 00263 template<typename _Up, typename _Ep> 00264 typename enable_if< __and_< 00265 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00266 __not_<is_array<_Up>> 00267 >::value, 00268 unique_ptr&>::type 00269 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00270 { 00271 reset(__u.release()); 00272 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00273 return *this; 00274 } 00275 00276 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00277 unique_ptr& 00278 operator=(nullptr_t) noexcept 00279 { 00280 reset(); 00281 return *this; 00282 } 00283 00284 // Observers. 00285 00286 /// Dereference the stored pointer. 00287 typename add_lvalue_reference<element_type>::type 00288 operator*() const 00289 { 00290 _GLIBCXX_DEBUG_ASSERT(get() != pointer()); 00291 return *get(); 00292 } 00293 00294 /// Return the stored pointer. 00295 pointer 00296 operator->() const noexcept 00297 { 00298 _GLIBCXX_DEBUG_ASSERT(get() != pointer()); 00299 return get(); 00300 } 00301 00302 /// Return the stored pointer. 00303 pointer 00304 get() const noexcept 00305 { return std::get<0>(_M_t); } 00306 00307 /// Return a reference to the stored deleter. 00308 deleter_type& 00309 get_deleter() noexcept 00310 { return std::get<1>(_M_t); } 00311 00312 /// Return a reference to the stored deleter. 00313 const deleter_type& 00314 get_deleter() const noexcept 00315 { return std::get<1>(_M_t); } 00316 00317 /// Return @c true if the stored pointer is not null. 00318 explicit operator bool() const noexcept 00319 { return get() == pointer() ? false : true; } 00320 00321 // Modifiers. 00322 00323 /// Release ownership of any stored pointer. 00324 pointer 00325 release() noexcept 00326 { 00327 pointer __p = get(); 00328 std::get<0>(_M_t) = pointer(); 00329 return __p; 00330 } 00331 00332 /** @brief Replace the stored pointer. 00333 * 00334 * @param __p The new pointer to store. 00335 * 00336 * The deleter will be invoked if a pointer is already owned. 00337 */ 00338 void 00339 reset(pointer __p = pointer()) noexcept 00340 { 00341 using std::swap; 00342 swap(std::get<0>(_M_t), __p); 00343 if (__p != pointer()) 00344 get_deleter()(__p); 00345 } 00346 00347 /// Exchange the pointer and deleter with another object. 00348 void 00349 swap(unique_ptr& __u) noexcept 00350 { 00351 using std::swap; 00352 swap(_M_t, __u._M_t); 00353 } 00354 00355 // Disable copy from lvalue. 00356 unique_ptr(const unique_ptr&) = delete; 00357 unique_ptr& operator=(const unique_ptr&) = delete; 00358 }; 00359 00360 /// 20.7.1.3 unique_ptr for array objects with a runtime length 00361 // [unique.ptr.runtime] 00362 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00363 // DR 740 - omit specialization for array objects with a compile time length 00364 template<typename _Tp, typename _Dp> 00365 class unique_ptr<_Tp[], _Dp> 00366 { 00367 // use SFINAE to determine whether _Del::pointer exists 00368 class _Pointer 00369 { 00370 template<typename _Up> 00371 static typename _Up::pointer __test(typename _Up::pointer*); 00372 00373 template<typename _Up> 00374 static _Tp* __test(...); 00375 00376 typedef typename remove_reference<_Dp>::type _Del; 00377 00378 public: 00379 typedef decltype(__test<_Del>(0)) type; 00380 }; 00381 00382 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; 00383 __tuple_type _M_t; 00384 00385 template<typename _Up> 00386 using __remove_cv = typename remove_cv<_Up>::type; 00387 00388 // like is_base_of<_Tp, _Up> but false if unqualified types are the same 00389 template<typename _Up> 00390 using __is_derived_Tp 00391 = __and_< is_base_of<_Tp, _Up>, 00392 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; 00393 00394 template<typename _Up, typename _Ep, 00395 typename _Tp_pointer = typename _Pointer::type, 00396 typename _Up_pointer = typename unique_ptr<_Up, _Ep>::pointer> 00397 using __safe_conversion = __and_< 00398 is_convertible<_Up_pointer, _Tp_pointer>, 00399 is_array<_Up>, 00400 __or_<__not_<is_pointer<_Up_pointer>>, 00401 __not_<is_pointer<_Tp_pointer>>, 00402 __not_<__is_derived_Tp<typename remove_extent<_Up>::type>> 00403 > 00404 >; 00405 00406 public: 00407 typedef typename _Pointer::type pointer; 00408 typedef _Tp element_type; 00409 typedef _Dp deleter_type; 00410 00411 // Constructors. 00412 00413 /// Default constructor, creates a unique_ptr that owns nothing. 00414 constexpr unique_ptr() noexcept 00415 : _M_t() 00416 { static_assert(!std::is_pointer<deleter_type>::value, 00417 "constructed with null function pointer deleter"); } 00418 00419 /** Takes ownership of a pointer. 00420 * 00421 * @param __p A pointer to an array of @c element_type 00422 * 00423 * The deleter will be value-initialized. 00424 */ 00425 explicit 00426 unique_ptr(pointer __p) noexcept 00427 : _M_t(__p, deleter_type()) 00428 { static_assert(!is_pointer<deleter_type>::value, 00429 "constructed with null function pointer deleter"); } 00430 00431 // Disable construction from convertible pointer types. 00432 template<typename _Up, typename = _Require<is_pointer<pointer>, 00433 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00434 explicit 00435 unique_ptr(_Up* __p) = delete; 00436 00437 /** Takes ownership of a pointer. 00438 * 00439 * @param __p A pointer to an array of @c element_type 00440 * @param __d A reference to a deleter. 00441 * 00442 * The deleter will be initialized with @p __d 00443 */ 00444 unique_ptr(pointer __p, 00445 typename conditional<is_reference<deleter_type>::value, 00446 deleter_type, const deleter_type&>::type __d) noexcept 00447 : _M_t(__p, __d) { } 00448 00449 /** Takes ownership of a pointer. 00450 * 00451 * @param __p A pointer to an array of @c element_type 00452 * @param __d A reference to a deleter. 00453 * 00454 * The deleter will be initialized with @p std::move(__d) 00455 */ 00456 unique_ptr(pointer __p, typename 00457 remove_reference<deleter_type>::type&& __d) noexcept 00458 : _M_t(std::move(__p), std::move(__d)) 00459 { static_assert(!is_reference<deleter_type>::value, 00460 "rvalue deleter bound to reference"); } 00461 00462 /// Move constructor. 00463 unique_ptr(unique_ptr&& __u) noexcept 00464 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00465 00466 /// Creates a unique_ptr that owns nothing. 00467 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } 00468 00469 template<typename _Up, typename _Ep, 00470 typename = _Require<__safe_conversion<_Up, _Ep>, 00471 typename conditional<is_reference<_Dp>::value, 00472 is_same<_Ep, _Dp>, 00473 is_convertible<_Ep, _Dp>>::type 00474 >> 00475 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00476 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00477 { } 00478 00479 /// Destructor, invokes the deleter if the stored pointer is not null. 00480 ~unique_ptr() 00481 { 00482 auto& __ptr = std::get<0>(_M_t); 00483 if (__ptr != nullptr) 00484 get_deleter()(__ptr); 00485 __ptr = pointer(); 00486 } 00487 00488 // Assignment. 00489 00490 /** @brief Move assignment operator. 00491 * 00492 * @param __u The object to transfer ownership from. 00493 * 00494 * Invokes the deleter first if this object owns a pointer. 00495 */ 00496 unique_ptr& 00497 operator=(unique_ptr&& __u) noexcept 00498 { 00499 reset(__u.release()); 00500 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00501 return *this; 00502 } 00503 00504 /** @brief Assignment from another type. 00505 * 00506 * @param __u The object to transfer ownership from, which owns a 00507 * convertible pointer to an array object. 00508 * 00509 * Invokes the deleter first if this object owns a pointer. 00510 */ 00511 template<typename _Up, typename _Ep> 00512 typename 00513 enable_if<__safe_conversion<_Up, _Ep>::value, unique_ptr&>::type 00514 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00515 { 00516 reset(__u.release()); 00517 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00518 return *this; 00519 } 00520 00521 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00522 unique_ptr& 00523 operator=(nullptr_t) noexcept 00524 { 00525 reset(); 00526 return *this; 00527 } 00528 00529 // Observers. 00530 00531 /// Access an element of owned array. 00532 typename std::add_lvalue_reference<element_type>::type 00533 operator[](size_t __i) const 00534 { 00535 _GLIBCXX_DEBUG_ASSERT(get() != pointer()); 00536 return get()[__i]; 00537 } 00538 00539 /// Return the stored pointer. 00540 pointer 00541 get() const noexcept 00542 { return std::get<0>(_M_t); } 00543 00544 /// Return a reference to the stored deleter. 00545 deleter_type& 00546 get_deleter() noexcept 00547 { return std::get<1>(_M_t); } 00548 00549 /// Return a reference to the stored deleter. 00550 const deleter_type& 00551 get_deleter() const noexcept 00552 { return std::get<1>(_M_t); } 00553 00554 /// Return @c true if the stored pointer is not null. 00555 explicit operator bool() const noexcept 00556 { return get() == pointer() ? false : true; } 00557 00558 // Modifiers. 00559 00560 /// Release ownership of any stored pointer. 00561 pointer 00562 release() noexcept 00563 { 00564 pointer __p = get(); 00565 std::get<0>(_M_t) = pointer(); 00566 return __p; 00567 } 00568 00569 /** @brief Replace the stored pointer. 00570 * 00571 * @param __p The new pointer to store. 00572 * 00573 * The deleter will be invoked if a pointer is already owned. 00574 */ 00575 void 00576 reset(pointer __p = pointer()) noexcept 00577 { 00578 using std::swap; 00579 swap(std::get<0>(_M_t), __p); 00580 if (__p != nullptr) 00581 get_deleter()(__p); 00582 } 00583 00584 // Disable resetting from convertible pointer types. 00585 template<typename _Up, typename = _Require<is_pointer<pointer>, 00586 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00587 void reset(_Up*) = delete; 00588 00589 /// Exchange the pointer and deleter with another object. 00590 void 00591 swap(unique_ptr& __u) noexcept 00592 { 00593 using std::swap; 00594 swap(_M_t, __u._M_t); 00595 } 00596 00597 // Disable copy from lvalue. 00598 unique_ptr(const unique_ptr&) = delete; 00599 unique_ptr& operator=(const unique_ptr&) = delete; 00600 00601 // Disable construction from convertible pointer types. 00602 template<typename _Up, typename = _Require<is_pointer<pointer>, 00603 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00604 unique_ptr(_Up*, typename 00605 conditional<is_reference<deleter_type>::value, 00606 deleter_type, const deleter_type&>::type) = delete; 00607 00608 // Disable construction from convertible pointer types. 00609 template<typename _Up, typename = _Require<is_pointer<pointer>, 00610 is_convertible<_Up*, pointer>, __is_derived_Tp<_Up>>> 00611 unique_ptr(_Up*, typename 00612 remove_reference<deleter_type>::type&&) = delete; 00613 }; 00614 00615 template<typename _Tp, typename _Dp> 00616 inline void 00617 swap(unique_ptr<_Tp, _Dp>& __x, 00618 unique_ptr<_Tp, _Dp>& __y) noexcept 00619 { __x.swap(__y); } 00620 00621 template<typename _Tp, typename _Dp, 00622 typename _Up, typename _Ep> 00623 inline bool 00624 operator==(const unique_ptr<_Tp, _Dp>& __x, 00625 const unique_ptr<_Up, _Ep>& __y) 00626 { return __x.get() == __y.get(); } 00627 00628 template<typename _Tp, typename _Dp> 00629 inline bool 00630 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00631 { return !__x; } 00632 00633 template<typename _Tp, typename _Dp> 00634 inline bool 00635 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00636 { return !__x; } 00637 00638 template<typename _Tp, typename _Dp, 00639 typename _Up, typename _Ep> 00640 inline bool 00641 operator!=(const unique_ptr<_Tp, _Dp>& __x, 00642 const unique_ptr<_Up, _Ep>& __y) 00643 { return __x.get() != __y.get(); } 00644 00645 template<typename _Tp, typename _Dp> 00646 inline bool 00647 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00648 { return (bool)__x; } 00649 00650 template<typename _Tp, typename _Dp> 00651 inline bool 00652 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00653 { return (bool)__x; } 00654 00655 template<typename _Tp, typename _Dp, 00656 typename _Up, typename _Ep> 00657 inline bool 00658 operator<(const unique_ptr<_Tp, _Dp>& __x, 00659 const unique_ptr<_Up, _Ep>& __y) 00660 { 00661 typedef typename 00662 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 00663 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 00664 return std::less<_CT>()(__x.get(), __y.get()); 00665 } 00666 00667 template<typename _Tp, typename _Dp> 00668 inline bool 00669 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00670 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00671 nullptr); } 00672 00673 template<typename _Tp, typename _Dp> 00674 inline bool 00675 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00676 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00677 __x.get()); } 00678 00679 template<typename _Tp, typename _Dp, 00680 typename _Up, typename _Ep> 00681 inline bool 00682 operator<=(const unique_ptr<_Tp, _Dp>& __x, 00683 const unique_ptr<_Up, _Ep>& __y) 00684 { return !(__y < __x); } 00685 00686 template<typename _Tp, typename _Dp> 00687 inline bool 00688 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00689 { return !(nullptr < __x); } 00690 00691 template<typename _Tp, typename _Dp> 00692 inline bool 00693 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00694 { return !(__x < nullptr); } 00695 00696 template<typename _Tp, typename _Dp, 00697 typename _Up, typename _Ep> 00698 inline bool 00699 operator>(const unique_ptr<_Tp, _Dp>& __x, 00700 const unique_ptr<_Up, _Ep>& __y) 00701 { return (__y < __x); } 00702 00703 template<typename _Tp, typename _Dp> 00704 inline bool 00705 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00706 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00707 __x.get()); } 00708 00709 template<typename _Tp, typename _Dp> 00710 inline bool 00711 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00712 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00713 nullptr); } 00714 00715 template<typename _Tp, typename _Dp, 00716 typename _Up, typename _Ep> 00717 inline bool 00718 operator>=(const unique_ptr<_Tp, _Dp>& __x, 00719 const unique_ptr<_Up, _Ep>& __y) 00720 { return !(__x < __y); } 00721 00722 template<typename _Tp, typename _Dp> 00723 inline bool 00724 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00725 { return !(__x < nullptr); } 00726 00727 template<typename _Tp, typename _Dp> 00728 inline bool 00729 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00730 { return !(nullptr < __x); } 00731 00732 /// std::hash specialization for unique_ptr. 00733 template<typename _Tp, typename _Dp> 00734 struct hash<unique_ptr<_Tp, _Dp>> 00735 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>> 00736 { 00737 size_t 00738 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept 00739 { 00740 typedef unique_ptr<_Tp, _Dp> _UP; 00741 return std::hash<typename _UP::pointer>()(__u.get()); 00742 } 00743 }; 00744 00745 #if __cplusplus > 201103L 00746 00747 #define __cpp_lib_make_unique 201304 00748 00749 template<typename _Tp> 00750 struct _MakeUniq 00751 { typedef unique_ptr<_Tp> __single_object; }; 00752 00753 template<typename _Tp> 00754 struct _MakeUniq<_Tp[]> 00755 { typedef unique_ptr<_Tp[]> __array; }; 00756 00757 template<typename _Tp, size_t _Bound> 00758 struct _MakeUniq<_Tp[_Bound]> 00759 { struct __invalid_type { }; }; 00760 00761 /// std::make_unique for single objects 00762 template<typename _Tp, typename... _Args> 00763 inline typename _MakeUniq<_Tp>::__single_object 00764 make_unique(_Args&&... __args) 00765 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } 00766 00767 /// std::make_unique for arrays of unknown bound 00768 template<typename _Tp> 00769 inline typename _MakeUniq<_Tp>::__array 00770 make_unique(size_t __num) 00771 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } 00772 00773 /// Disable std::make_unique for arrays of known bound 00774 template<typename _Tp, typename... _Args> 00775 inline typename _MakeUniq<_Tp>::__invalid_type 00776 make_unique(_Args&&...) = delete; 00777 #endif 00778 00779 // @} group pointer_abstractions 00780 00781 _GLIBCXX_END_NAMESPACE_VERSION 00782 } // namespace 00783 00784 #endif /* _UNIQUE_PTR_H */