libstdc++
|
00001 // unique_ptr implementation -*- C++ -*- 00002 00003 // Copyright (C) 2008-2016 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 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 public: 00087 /// Default constructor 00088 constexpr default_delete() noexcept = default; 00089 00090 /** @brief Converting constructor. 00091 * 00092 * Allows conversion from a deleter for arrays of another type, such as 00093 * a const-qualified version of @p _Tp. 00094 * 00095 * Conversions from types derived from @c _Tp are not allowed because 00096 * it is unsafe to @c delete[] an array of derived types through a 00097 * pointer to the base type. 00098 */ 00099 template<typename _Up, typename = typename 00100 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type> 00101 default_delete(const default_delete<_Up[]>&) noexcept { } 00102 00103 /// Calls @c delete[] @p __ptr 00104 template<typename _Up> 00105 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type 00106 operator()(_Up* __ptr) const 00107 { 00108 static_assert(sizeof(_Tp)>0, 00109 "can't delete pointer to incomplete type"); 00110 delete [] __ptr; 00111 } 00112 }; 00113 00114 /// 20.7.1.2 unique_ptr for single objects. 00115 template <typename _Tp, typename _Dp = default_delete<_Tp> > 00116 class unique_ptr 00117 { 00118 // use SFINAE to determine whether _Del::pointer exists 00119 class _Pointer 00120 { 00121 template<typename _Up> 00122 static typename _Up::pointer __test(typename _Up::pointer*); 00123 00124 template<typename _Up> 00125 static _Tp* __test(...); 00126 00127 typedef typename remove_reference<_Dp>::type _Del; 00128 00129 public: 00130 typedef decltype(__test<_Del>(0)) type; 00131 }; 00132 00133 typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; 00134 __tuple_type _M_t; 00135 00136 public: 00137 typedef typename _Pointer::type pointer; 00138 typedef _Tp element_type; 00139 typedef _Dp deleter_type; 00140 00141 00142 // helper template for detecting a safe conversion from another 00143 // unique_ptr 00144 template<typename _Up, typename _Ep> 00145 using __safe_conversion_up = __and_< 00146 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, 00147 __not_<is_array<_Up>>, 00148 __or_<__and_<is_reference<deleter_type>, 00149 is_same<deleter_type, _Ep>>, 00150 __and_<__not_<is_reference<deleter_type>>, 00151 is_convertible<_Ep, deleter_type>> 00152 > 00153 >; 00154 00155 // Constructors. 00156 00157 /// Default constructor, creates a unique_ptr that owns nothing. 00158 constexpr unique_ptr() noexcept 00159 : _M_t() 00160 { static_assert(!is_pointer<deleter_type>::value, 00161 "constructed with null function pointer deleter"); } 00162 00163 /** Takes ownership of a pointer. 00164 * 00165 * @param __p A pointer to an object of @c element_type 00166 * 00167 * The deleter will be value-initialized. 00168 */ 00169 explicit 00170 unique_ptr(pointer __p) noexcept 00171 : _M_t(__p, deleter_type()) 00172 { static_assert(!is_pointer<deleter_type>::value, 00173 "constructed with null function pointer deleter"); } 00174 00175 /** Takes ownership of a pointer. 00176 * 00177 * @param __p A pointer to an object of @c element_type 00178 * @param __d A reference to a deleter. 00179 * 00180 * The deleter will be initialized with @p __d 00181 */ 00182 unique_ptr(pointer __p, 00183 typename conditional<is_reference<deleter_type>::value, 00184 deleter_type, const deleter_type&>::type __d) noexcept 00185 : _M_t(__p, __d) { } 00186 00187 /** Takes ownership of a pointer. 00188 * 00189 * @param __p A pointer to an object of @c element_type 00190 * @param __d An rvalue reference to a deleter. 00191 * 00192 * The deleter will be initialized with @p std::move(__d) 00193 */ 00194 unique_ptr(pointer __p, 00195 typename remove_reference<deleter_type>::type&& __d) noexcept 00196 : _M_t(std::move(__p), std::move(__d)) 00197 { static_assert(!std::is_reference<deleter_type>::value, 00198 "rvalue deleter bound to reference"); } 00199 00200 /// Creates a unique_ptr that owns nothing. 00201 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } 00202 00203 // Move constructors. 00204 00205 /// Move constructor. 00206 unique_ptr(unique_ptr&& __u) noexcept 00207 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00208 00209 /** @brief Converting constructor from another type 00210 * 00211 * Requires that the pointer owned by @p __u is convertible to the 00212 * type of pointer owned by this object, @p __u does not own an array, 00213 * and @p __u has a compatible deleter type. 00214 */ 00215 template<typename _Up, typename _Ep, typename = _Require< 00216 __safe_conversion_up<_Up, _Ep>, 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 __safe_conversion_up<_Up, _Ep>, 00266 is_assignable<deleter_type&, _Ep&&> 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_assert(get() != pointer()); 00291 return *get(); 00292 } 00293 00294 /// Return the stored pointer. 00295 pointer 00296 operator->() const noexcept 00297 { 00298 _GLIBCXX_DEBUG_PEDASSERT(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 00395 public: 00396 typedef typename _Pointer::type pointer; 00397 typedef _Tp element_type; 00398 typedef _Dp deleter_type; 00399 00400 // helper template for detecting a safe conversion from another 00401 // unique_ptr 00402 template<typename _Up, typename _Ep, 00403 typename _Up_up = unique_ptr<_Up, _Ep>, 00404 typename _Up_element_type = typename _Up_up::element_type> 00405 using __safe_conversion_up = __and_< 00406 is_array<_Up>, 00407 is_same<pointer, element_type*>, 00408 is_same<typename _Up_up::pointer, _Up_element_type*>, 00409 is_convertible<_Up_element_type(*)[], element_type(*)[]>, 00410 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>, 00411 __and_<__not_<is_reference<deleter_type>>, 00412 is_convertible<_Ep, deleter_type>>> 00413 >; 00414 00415 // helper template for detecting a safe conversion from a raw pointer 00416 template<typename _Up> 00417 using __safe_conversion_raw = __and_< 00418 __or_<__or_<is_same<_Up, pointer>, 00419 is_same<_Up, nullptr_t>>, 00420 __and_<is_pointer<_Up>, 00421 is_same<pointer, element_type*>, 00422 is_convertible< 00423 typename remove_pointer<_Up>::type(*)[], 00424 element_type(*)[]> 00425 > 00426 > 00427 >; 00428 00429 // Constructors. 00430 00431 /// Default constructor, creates a unique_ptr that owns nothing. 00432 constexpr unique_ptr() noexcept 00433 : _M_t() 00434 { static_assert(!std::is_pointer<deleter_type>::value, 00435 "constructed with null function pointer deleter"); } 00436 00437 /** Takes ownership of a pointer. 00438 * 00439 * @param __p A pointer to an array of a type safely convertible 00440 * to an array of @c element_type 00441 * 00442 * The deleter will be value-initialized. 00443 */ 00444 template<typename _Up, 00445 typename = typename enable_if< 00446 __safe_conversion_raw<_Up>::value, bool>::type> 00447 explicit 00448 unique_ptr(_Up __p) noexcept 00449 : _M_t(__p, deleter_type()) 00450 { static_assert(!is_pointer<deleter_type>::value, 00451 "constructed with null function pointer deleter"); } 00452 00453 /** Takes ownership of a pointer. 00454 * 00455 * @param __p A pointer to an array of a type safely convertible 00456 * to an array of @c element_type 00457 * @param __d A reference to a deleter. 00458 * 00459 * The deleter will be initialized with @p __d 00460 */ 00461 template<typename _Up, 00462 typename = typename enable_if< 00463 __safe_conversion_raw<_Up>::value, bool>::type> 00464 unique_ptr(_Up __p, 00465 typename conditional<is_reference<deleter_type>::value, 00466 deleter_type, const deleter_type&>::type __d) noexcept 00467 : _M_t(__p, __d) { } 00468 00469 /** Takes ownership of a pointer. 00470 * 00471 * @param __p A pointer to an array of a type safely convertible 00472 * to an array of @c element_type 00473 * @param __d A reference to a deleter. 00474 * 00475 * The deleter will be initialized with @p std::move(__d) 00476 */ 00477 template<typename _Up, 00478 typename = typename enable_if< 00479 __safe_conversion_raw<_Up>::value, bool>::type> 00480 unique_ptr(_Up __p, typename 00481 remove_reference<deleter_type>::type&& __d) noexcept 00482 : _M_t(std::move(__p), std::move(__d)) 00483 { static_assert(!is_reference<deleter_type>::value, 00484 "rvalue deleter bound to reference"); } 00485 00486 /// Move constructor. 00487 unique_ptr(unique_ptr&& __u) noexcept 00488 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } 00489 00490 /// Creates a unique_ptr that owns nothing. 00491 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } 00492 00493 template<typename _Up, typename _Ep, 00494 typename = _Require<__safe_conversion_up<_Up, _Ep>>> 00495 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept 00496 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) 00497 { } 00498 00499 /// Destructor, invokes the deleter if the stored pointer is not null. 00500 ~unique_ptr() 00501 { 00502 auto& __ptr = std::get<0>(_M_t); 00503 if (__ptr != nullptr) 00504 get_deleter()(__ptr); 00505 __ptr = pointer(); 00506 } 00507 00508 // Assignment. 00509 00510 /** @brief Move assignment operator. 00511 * 00512 * @param __u The object to transfer ownership from. 00513 * 00514 * Invokes the deleter first if this object owns a pointer. 00515 */ 00516 unique_ptr& 00517 operator=(unique_ptr&& __u) noexcept 00518 { 00519 reset(__u.release()); 00520 get_deleter() = std::forward<deleter_type>(__u.get_deleter()); 00521 return *this; 00522 } 00523 00524 /** @brief Assignment from another type. 00525 * 00526 * @param __u The object to transfer ownership from, which owns a 00527 * convertible pointer to an array object. 00528 * 00529 * Invokes the deleter first if this object owns a pointer. 00530 */ 00531 template<typename _Up, typename _Ep> 00532 typename 00533 enable_if<__and_<__safe_conversion_up<_Up, _Ep>, 00534 is_assignable<deleter_type&, _Ep&&> 00535 >::value, 00536 unique_ptr&>::type 00537 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept 00538 { 00539 reset(__u.release()); 00540 get_deleter() = std::forward<_Ep>(__u.get_deleter()); 00541 return *this; 00542 } 00543 00544 /// Reset the %unique_ptr to empty, invoking the deleter if necessary. 00545 unique_ptr& 00546 operator=(nullptr_t) noexcept 00547 { 00548 reset(); 00549 return *this; 00550 } 00551 00552 // Observers. 00553 00554 /// Access an element of owned array. 00555 typename std::add_lvalue_reference<element_type>::type 00556 operator[](size_t __i) const 00557 { 00558 __glibcxx_assert(get() != pointer()); 00559 return get()[__i]; 00560 } 00561 00562 /// Return the stored pointer. 00563 pointer 00564 get() const noexcept 00565 { return std::get<0>(_M_t); } 00566 00567 /// Return a reference to the stored deleter. 00568 deleter_type& 00569 get_deleter() noexcept 00570 { return std::get<1>(_M_t); } 00571 00572 /// Return a reference to the stored deleter. 00573 const deleter_type& 00574 get_deleter() const noexcept 00575 { return std::get<1>(_M_t); } 00576 00577 /// Return @c true if the stored pointer is not null. 00578 explicit operator bool() const noexcept 00579 { return get() == pointer() ? false : true; } 00580 00581 // Modifiers. 00582 00583 /// Release ownership of any stored pointer. 00584 pointer 00585 release() noexcept 00586 { 00587 pointer __p = get(); 00588 std::get<0>(_M_t) = pointer(); 00589 return __p; 00590 } 00591 00592 /** @brief Replace the stored pointer. 00593 * 00594 * @param __p The new pointer to store. 00595 * 00596 * The deleter will be invoked if a pointer is already owned. 00597 */ 00598 template <typename _Up, 00599 typename = _Require< 00600 __or_<is_same<_Up, pointer>, 00601 __and_<is_same<pointer, element_type*>, 00602 is_pointer<_Up>, 00603 is_convertible< 00604 typename remove_pointer<_Up>::type(*)[], 00605 element_type(*)[] 00606 > 00607 > 00608 > 00609 >> 00610 void 00611 reset(_Up __p) noexcept 00612 { 00613 using std::swap; 00614 swap(std::get<0>(_M_t), __p); 00615 if (__p != nullptr) 00616 get_deleter()(__p); 00617 } 00618 00619 void reset(nullptr_t = nullptr) noexcept 00620 { 00621 reset(pointer()); 00622 } 00623 00624 /// Exchange the pointer and deleter with another object. 00625 void 00626 swap(unique_ptr& __u) noexcept 00627 { 00628 using std::swap; 00629 swap(_M_t, __u._M_t); 00630 } 00631 00632 // Disable copy from lvalue. 00633 unique_ptr(const unique_ptr&) = delete; 00634 unique_ptr& operator=(const unique_ptr&) = delete; 00635 }; 00636 00637 template<typename _Tp, typename _Dp> 00638 inline void 00639 swap(unique_ptr<_Tp, _Dp>& __x, 00640 unique_ptr<_Tp, _Dp>& __y) noexcept 00641 { __x.swap(__y); } 00642 00643 template<typename _Tp, typename _Dp, 00644 typename _Up, typename _Ep> 00645 inline bool 00646 operator==(const unique_ptr<_Tp, _Dp>& __x, 00647 const unique_ptr<_Up, _Ep>& __y) 00648 { return __x.get() == __y.get(); } 00649 00650 template<typename _Tp, typename _Dp> 00651 inline bool 00652 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00653 { return !__x; } 00654 00655 template<typename _Tp, typename _Dp> 00656 inline bool 00657 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00658 { return !__x; } 00659 00660 template<typename _Tp, typename _Dp, 00661 typename _Up, typename _Ep> 00662 inline bool 00663 operator!=(const unique_ptr<_Tp, _Dp>& __x, 00664 const unique_ptr<_Up, _Ep>& __y) 00665 { return __x.get() != __y.get(); } 00666 00667 template<typename _Tp, typename _Dp> 00668 inline bool 00669 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept 00670 { return (bool)__x; } 00671 00672 template<typename _Tp, typename _Dp> 00673 inline bool 00674 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept 00675 { return (bool)__x; } 00676 00677 template<typename _Tp, typename _Dp, 00678 typename _Up, typename _Ep> 00679 inline bool 00680 operator<(const unique_ptr<_Tp, _Dp>& __x, 00681 const unique_ptr<_Up, _Ep>& __y) 00682 { 00683 typedef typename 00684 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, 00685 typename unique_ptr<_Up, _Ep>::pointer>::type _CT; 00686 return std::less<_CT>()(__x.get(), __y.get()); 00687 } 00688 00689 template<typename _Tp, typename _Dp> 00690 inline bool 00691 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00692 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00693 nullptr); } 00694 00695 template<typename _Tp, typename _Dp> 00696 inline bool 00697 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00698 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00699 __x.get()); } 00700 00701 template<typename _Tp, typename _Dp, 00702 typename _Up, typename _Ep> 00703 inline bool 00704 operator<=(const unique_ptr<_Tp, _Dp>& __x, 00705 const unique_ptr<_Up, _Ep>& __y) 00706 { return !(__y < __x); } 00707 00708 template<typename _Tp, typename _Dp> 00709 inline bool 00710 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00711 { return !(nullptr < __x); } 00712 00713 template<typename _Tp, typename _Dp> 00714 inline bool 00715 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00716 { return !(__x < 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 (__y < __x); } 00724 00725 template<typename _Tp, typename _Dp> 00726 inline bool 00727 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00728 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, 00729 __x.get()); } 00730 00731 template<typename _Tp, typename _Dp> 00732 inline bool 00733 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00734 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), 00735 nullptr); } 00736 00737 template<typename _Tp, typename _Dp, 00738 typename _Up, typename _Ep> 00739 inline bool 00740 operator>=(const unique_ptr<_Tp, _Dp>& __x, 00741 const unique_ptr<_Up, _Ep>& __y) 00742 { return !(__x < __y); } 00743 00744 template<typename _Tp, typename _Dp> 00745 inline bool 00746 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) 00747 { return !(__x < nullptr); } 00748 00749 template<typename _Tp, typename _Dp> 00750 inline bool 00751 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) 00752 { return !(nullptr < __x); } 00753 00754 /// std::hash specialization for unique_ptr. 00755 template<typename _Tp, typename _Dp> 00756 struct hash<unique_ptr<_Tp, _Dp>> 00757 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>> 00758 { 00759 size_t 00760 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept 00761 { 00762 typedef unique_ptr<_Tp, _Dp> _UP; 00763 return std::hash<typename _UP::pointer>()(__u.get()); 00764 } 00765 }; 00766 00767 #if __cplusplus > 201103L 00768 00769 #define __cpp_lib_make_unique 201304 00770 00771 template<typename _Tp> 00772 struct _MakeUniq 00773 { typedef unique_ptr<_Tp> __single_object; }; 00774 00775 template<typename _Tp> 00776 struct _MakeUniq<_Tp[]> 00777 { typedef unique_ptr<_Tp[]> __array; }; 00778 00779 template<typename _Tp, size_t _Bound> 00780 struct _MakeUniq<_Tp[_Bound]> 00781 { struct __invalid_type { }; }; 00782 00783 /// std::make_unique for single objects 00784 template<typename _Tp, typename... _Args> 00785 inline typename _MakeUniq<_Tp>::__single_object 00786 make_unique(_Args&&... __args) 00787 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } 00788 00789 /// std::make_unique for arrays of unknown bound 00790 template<typename _Tp> 00791 inline typename _MakeUniq<_Tp>::__array 00792 make_unique(size_t __num) 00793 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } 00794 00795 /// Disable std::make_unique for arrays of known bound 00796 template<typename _Tp, typename... _Args> 00797 inline typename _MakeUniq<_Tp>::__invalid_type 00798 make_unique(_Args&&...) = delete; 00799 #endif 00800 00801 // @} group pointer_abstractions 00802 00803 _GLIBCXX_END_NAMESPACE_VERSION 00804 } // namespace 00805 00806 #endif /* _UNIQUE_PTR_H */