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