libstdc++
|
00001 // Experimental shared_ptr with array support -*- C++ -*- 00002 00003 // Copyright (C) 2015-2018 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 experimental/bits/shared_ptr.h 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{experimental/memory} 00028 */ 00029 00030 #ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 00031 #define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1 00032 00033 #pragma GCC system_header 00034 00035 #if __cplusplus >= 201402L 00036 00037 #include <memory> 00038 #include <experimental/type_traits> 00039 00040 namespace std _GLIBCXX_VISIBILITY(default) 00041 { 00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00043 00044 namespace experimental 00045 { 00046 inline namespace fundamentals_v2 00047 { 00048 // 8.2.1 00049 00050 template<typename _Tp> class shared_ptr; 00051 template<typename _Tp> class weak_ptr; 00052 template<typename _Tp> class enable_shared_from_this; 00053 00054 template<typename _Yp, typename _Tp> 00055 constexpr bool __sp_compatible_v 00056 = std::__sp_compatible_with<_Yp*, _Tp*>::value; 00057 00058 template<typename _Tp, typename _Yp> 00059 constexpr bool __sp_is_constructible_v 00060 = std::__sp_is_constructible<_Tp, _Yp>::value; 00061 00062 template<typename _Tp> 00063 class shared_ptr : public __shared_ptr<_Tp> 00064 { 00065 using _Base_type = __shared_ptr<_Tp>; 00066 00067 public: 00068 using element_type = typename _Base_type::element_type; 00069 00070 private: 00071 // Constraint for construction from a pointer of type _Yp*: 00072 template<typename _Yp> 00073 using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>; 00074 00075 template<typename _Tp1, typename _Res = void> 00076 using _Compatible 00077 = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>; 00078 00079 template<typename _Tp1, typename _Del, 00080 typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer, 00081 typename _Res = void> 00082 using _UniqCompatible = enable_if_t< 00083 __sp_compatible_v<_Tp1, _Tp> 00084 && experimental::is_convertible_v<_Ptr, element_type*>, 00085 _Res>; 00086 00087 public: 00088 00089 // 8.2.1.1, shared_ptr constructors 00090 constexpr shared_ptr() noexcept = default; 00091 00092 template<typename _Tp1, typename = _SafeConv<_Tp1>> 00093 explicit 00094 shared_ptr(_Tp1* __p) : _Base_type(__p) 00095 { _M_enable_shared_from_this_with(__p); } 00096 00097 template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>> 00098 shared_ptr(_Tp1* __p, _Deleter __d) 00099 : _Base_type(__p, __d) 00100 { _M_enable_shared_from_this_with(__p); } 00101 00102 template<typename _Tp1, typename _Deleter, typename _Alloc, 00103 typename = _SafeConv<_Tp1>> 00104 shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 00105 : _Base_type(__p, __d, __a) 00106 { _M_enable_shared_from_this_with(__p); } 00107 00108 template<typename _Deleter> 00109 shared_ptr(nullptr_t __p, _Deleter __d) 00110 : _Base_type(__p, __d) { } 00111 00112 template<typename _Deleter, typename _Alloc> 00113 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 00114 : _Base_type(__p, __d, __a) { } 00115 00116 template<typename _Tp1> 00117 shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept 00118 : _Base_type(__r, __p) { } 00119 00120 shared_ptr(const shared_ptr& __r) noexcept 00121 : _Base_type(__r) { } 00122 00123 template<typename _Tp1, typename = _Compatible<_Tp1>> 00124 shared_ptr(const shared_ptr<_Tp1>& __r) noexcept 00125 : _Base_type(__r) { } 00126 00127 shared_ptr(shared_ptr&& __r) noexcept 00128 : _Base_type(std::move(__r)) { } 00129 00130 template<typename _Tp1, typename = _Compatible<_Tp1>> 00131 shared_ptr(shared_ptr<_Tp1>&& __r) noexcept 00132 : _Base_type(std::move(__r)) { } 00133 00134 template<typename _Tp1, typename = _Compatible<_Tp1>> 00135 explicit 00136 shared_ptr(const weak_ptr<_Tp1>& __r) 00137 : _Base_type(__r) { } 00138 00139 #if _GLIBCXX_USE_DEPRECATED 00140 template<typename _Tp1, typename = _Compatible<_Tp1>> 00141 shared_ptr(std::auto_ptr<_Tp1>&& __r) 00142 : _Base_type(std::move(__r)) 00143 { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); } 00144 #endif 00145 00146 template<typename _Tp1, typename _Del, 00147 typename = _UniqCompatible<_Tp1, _Del>> 00148 shared_ptr(unique_ptr<_Tp1, _Del>&& __r) 00149 : _Base_type(std::move(__r)) 00150 { 00151 // XXX assume conversion from __r.get() to this->get() to __elem_t* 00152 // is a round trip, which might not be true in all cases. 00153 using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type; 00154 _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get())); 00155 } 00156 00157 constexpr shared_ptr(nullptr_t __p) 00158 : _Base_type(__p) { } 00159 00160 // C++14 §20.8.2.2 00161 ~shared_ptr() = default; 00162 00163 // C++14 §20.8.2.3 00164 shared_ptr& operator=(const shared_ptr&) noexcept = default; 00165 00166 template <typename _Tp1> 00167 _Compatible<_Tp1, shared_ptr&> 00168 operator=(const shared_ptr<_Tp1>& __r) noexcept 00169 { 00170 _Base_type::operator=(__r); 00171 return *this; 00172 } 00173 00174 shared_ptr& 00175 operator=(shared_ptr&& __r) noexcept 00176 { 00177 _Base_type::operator=(std::move(__r)); 00178 return *this; 00179 } 00180 00181 template <typename _Tp1> 00182 _Compatible<_Tp1, shared_ptr&> 00183 operator=(shared_ptr<_Tp1>&& __r) noexcept 00184 { 00185 _Base_type::operator=(std::move(__r)); 00186 return *this; 00187 } 00188 00189 #if _GLIBCXX_USE_DEPRECATED 00190 template<typename _Tp1> 00191 _Compatible<_Tp1, shared_ptr&> 00192 operator=(std::auto_ptr<_Tp1>&& __r) 00193 { 00194 __shared_ptr<_Tp>::operator=(std::move(__r)); 00195 return *this; 00196 } 00197 #endif 00198 00199 template <typename _Tp1, typename _Del> 00200 _UniqCompatible<_Tp1, _Del, shared_ptr&> 00201 operator=(unique_ptr<_Tp1, _Del>&& __r) 00202 { 00203 _Base_type::operator=(std::move(__r)); 00204 return *this; 00205 } 00206 00207 // C++14 §20.8.2.2.4 00208 // swap & reset 00209 // 8.2.1.2 shared_ptr observers 00210 // in __shared_ptr 00211 00212 private: 00213 template<typename _Alloc, typename... _Args> 00214 shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 00215 _Args&&... __args) 00216 : _Base_type(__tag, __a, std::forward<_Args>(__args)...) 00217 { _M_enable_shared_from_this_with(this->get()); } 00218 00219 template<typename _Tp1, typename _Alloc, typename... _Args> 00220 friend shared_ptr<_Tp1> 00221 allocate_shared(const _Alloc& __a, _Args&&... __args); 00222 00223 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 00224 : _Base_type(__r, std::nothrow) { } 00225 00226 friend class weak_ptr<_Tp>; 00227 00228 template<typename _Yp> 00229 using __esft_base_t = 00230 decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>())); 00231 00232 // Detect an accessible and unambiguous enable_shared_from_this base. 00233 template<typename _Yp, typename = void> 00234 struct __has_esft_base 00235 : false_type { }; 00236 00237 template<typename _Yp> 00238 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> 00239 : __bool_constant<!is_array_v<_Tp>> { }; // ignore base for arrays 00240 00241 template<typename _Yp> 00242 typename enable_if<__has_esft_base<_Yp>::value>::type 00243 _M_enable_shared_from_this_with(const _Yp* __p) noexcept 00244 { 00245 if (auto __base = __expt_enable_shared_from_this_base(__p)) 00246 { 00247 __base->_M_weak_this 00248 = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p)); 00249 } 00250 } 00251 00252 template<typename _Yp> 00253 typename enable_if<!__has_esft_base<_Yp>::value>::type 00254 _M_enable_shared_from_this_with(const _Yp*) noexcept 00255 { } 00256 }; 00257 00258 // C++14 §20.8.2.2.7 //DOING 00259 template<typename _Tp1, typename _Tp2> 00260 bool operator==(const shared_ptr<_Tp1>& __a, 00261 const shared_ptr<_Tp2>& __b) noexcept 00262 { return __a.get() == __b.get(); } 00263 00264 template<typename _Tp> 00265 inline bool 00266 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00267 { return !__a; } 00268 00269 template<typename _Tp> 00270 inline bool 00271 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00272 { return !__a; } 00273 00274 template<typename _Tp1, typename _Tp2> 00275 inline bool 00276 operator!=(const shared_ptr<_Tp1>& __a, 00277 const shared_ptr<_Tp2>& __b) noexcept 00278 { return __a.get() != __b.get(); } 00279 00280 template<typename _Tp> 00281 inline bool 00282 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00283 { return (bool)__a; } 00284 00285 template<typename _Tp> 00286 inline bool 00287 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00288 { return (bool)__a; } 00289 00290 template<typename _Tp1, typename _Tp2> 00291 inline bool 00292 operator<(const shared_ptr<_Tp1>& __a, 00293 const shared_ptr<_Tp2>& __b) noexcept 00294 { 00295 using __elem_t1 = typename shared_ptr<_Tp1>::element_type; 00296 using __elem_t2 = typename shared_ptr<_Tp2>::element_type; 00297 using _CT = common_type_t<__elem_t1*, __elem_t2*>; 00298 return std::less<_CT>()(__a.get(), __b.get()); 00299 } 00300 00301 template<typename _Tp> 00302 inline bool 00303 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00304 { 00305 using __elem_t = typename shared_ptr<_Tp>::element_type; 00306 return std::less<__elem_t*>()(__a.get(), nullptr); 00307 } 00308 00309 template<typename _Tp> 00310 inline bool 00311 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00312 { 00313 using __elem_t = typename shared_ptr<_Tp>::element_type; 00314 return std::less<__elem_t*>()(nullptr, __a.get()); 00315 } 00316 00317 template<typename _Tp1, typename _Tp2> 00318 inline bool 00319 operator<=(const shared_ptr<_Tp1>& __a, 00320 const shared_ptr<_Tp2>& __b) noexcept 00321 { return !(__b < __a); } 00322 00323 template<typename _Tp> 00324 inline bool 00325 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00326 { return !(nullptr < __a); } 00327 00328 template<typename _Tp> 00329 inline bool 00330 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00331 { return !(__a < nullptr); } 00332 00333 template<typename _Tp1, typename _Tp2> 00334 inline bool 00335 operator>(const shared_ptr<_Tp1>& __a, 00336 const shared_ptr<_Tp2>& __b) noexcept 00337 { return (__b < __a); } 00338 00339 template<typename _Tp> 00340 inline bool 00341 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00342 { 00343 using __elem_t = typename shared_ptr<_Tp>::element_type; 00344 return std::less<__elem_t*>()(nullptr, __a.get()); 00345 } 00346 00347 template<typename _Tp> 00348 inline bool 00349 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00350 { 00351 using __elem_t = typename shared_ptr<_Tp>::element_type; 00352 return std::less<__elem_t*>()(__a.get(), nullptr); 00353 } 00354 00355 template<typename _Tp1, typename _Tp2> 00356 inline bool 00357 operator>=(const shared_ptr<_Tp1>& __a, 00358 const shared_ptr<_Tp2>& __b) noexcept 00359 { return !(__a < __b); } 00360 00361 template<typename _Tp> 00362 inline bool 00363 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00364 { return !(__a < nullptr); } 00365 00366 template<typename _Tp> 00367 inline bool 00368 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00369 { return !(nullptr < __a); } 00370 00371 // C++14 §20.8.2.2.8 00372 template<typename _Tp> 00373 inline void 00374 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 00375 { __a.swap(__b); } 00376 00377 // 8.2.1.3, shared_ptr casts 00378 template<typename _Tp, typename _Tp1> 00379 inline shared_ptr<_Tp> 00380 static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 00381 { 00382 using __elem_t = typename shared_ptr<_Tp>::element_type; 00383 return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get())); 00384 } 00385 00386 template<typename _Tp, typename _Tp1> 00387 inline shared_ptr<_Tp> 00388 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 00389 { 00390 using __elem_t = typename shared_ptr<_Tp>::element_type; 00391 if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get())) 00392 return shared_ptr<_Tp>(__r, __p); 00393 return shared_ptr<_Tp>(); 00394 } 00395 00396 template<typename _Tp, typename _Tp1> 00397 inline shared_ptr<_Tp> 00398 const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 00399 { 00400 using __elem_t = typename shared_ptr<_Tp>::element_type; 00401 return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get())); 00402 } 00403 00404 template<typename _Tp, typename _Tp1> 00405 inline shared_ptr<_Tp> 00406 reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 00407 { 00408 using __elem_t = typename shared_ptr<_Tp>::element_type; 00409 return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get())); 00410 } 00411 00412 // C++14 §20.8.2.3 00413 template<typename _Tp> 00414 class weak_ptr : public __weak_ptr<_Tp> 00415 { 00416 template<typename _Tp1, typename _Res = void> 00417 using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>; 00418 00419 using _Base_type = __weak_ptr<_Tp>; 00420 00421 public: 00422 constexpr weak_ptr() noexcept = default; 00423 00424 template<typename _Tp1, typename = _Compatible<_Tp1>> 00425 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept 00426 : _Base_type(__r) { } 00427 00428 weak_ptr(const weak_ptr&) noexcept = default; 00429 00430 template<typename _Tp1, typename = _Compatible<_Tp1>> 00431 weak_ptr(const weak_ptr<_Tp1>& __r) noexcept 00432 : _Base_type(__r) { } 00433 00434 weak_ptr(weak_ptr&&) noexcept = default; 00435 00436 template<typename _Tp1, typename = _Compatible<_Tp1>> 00437 weak_ptr(weak_ptr<_Tp1>&& __r) noexcept 00438 : _Base_type(std::move(__r)) { } 00439 00440 weak_ptr& 00441 operator=(const weak_ptr& __r) noexcept = default; 00442 00443 template<typename _Tp1> 00444 _Compatible<_Tp1, weak_ptr&> 00445 operator=(const weak_ptr<_Tp1>& __r) noexcept 00446 { 00447 this->_Base_type::operator=(__r); 00448 return *this; 00449 } 00450 00451 template<typename _Tp1> 00452 _Compatible<_Tp1, weak_ptr&> 00453 operator=(const shared_ptr<_Tp1>& __r) noexcept 00454 { 00455 this->_Base_type::operator=(__r); 00456 return *this; 00457 } 00458 00459 weak_ptr& 00460 operator=(weak_ptr&& __r) noexcept = default; 00461 00462 template<typename _Tp1> 00463 _Compatible<_Tp1, weak_ptr&> 00464 operator=(weak_ptr<_Tp1>&& __r) noexcept 00465 { 00466 this->_Base_type::operator=(std::move(__r)); 00467 return *this; 00468 } 00469 00470 shared_ptr<_Tp> 00471 lock() const noexcept 00472 { return shared_ptr<_Tp>(*this, std::nothrow); } 00473 00474 friend class enable_shared_from_this<_Tp>; 00475 }; 00476 00477 // C++14 §20.8.2.3.6 00478 template<typename _Tp> 00479 inline void 00480 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 00481 { __a.swap(__b); } 00482 00483 /// C++14 §20.8.2.2.10 00484 template<typename _Del, typename _Tp> 00485 inline _Del* 00486 get_deleter(const shared_ptr<_Tp>& __p) noexcept 00487 { return std::get_deleter<_Del>(__p); } 00488 00489 // C++14 §20.8.2.2.11 00490 template<typename _Ch, typename _Tr, typename _Tp> 00491 inline std::basic_ostream<_Ch, _Tr>& 00492 operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p) 00493 { 00494 __os << __p.get(); 00495 return __os; 00496 } 00497 00498 // C++14 §20.8.2.4 00499 template<typename _Tp = void> class owner_less; 00500 00501 /// Partial specialization of owner_less for shared_ptr. 00502 template<typename _Tp> 00503 struct owner_less<shared_ptr<_Tp>> 00504 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 00505 { }; 00506 00507 /// Partial specialization of owner_less for weak_ptr. 00508 template<typename _Tp> 00509 struct owner_less<weak_ptr<_Tp>> 00510 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 00511 { }; 00512 00513 template<> 00514 class owner_less<void> 00515 { 00516 template<typename _Tp, typename _Up> 00517 bool 00518 operator()(shared_ptr<_Tp> const& __lhs, 00519 shared_ptr<_Up> const& __rhs) const 00520 { return __lhs.owner_before(__rhs); } 00521 00522 template<typename _Tp, typename _Up> 00523 bool 00524 operator()(shared_ptr<_Tp> const& __lhs, 00525 weak_ptr<_Up> const& __rhs) const 00526 { return __lhs.owner_before(__rhs); } 00527 00528 template<typename _Tp, typename _Up> 00529 bool 00530 operator()(weak_ptr<_Tp> const& __lhs, 00531 shared_ptr<_Up> const& __rhs) const 00532 { return __lhs.owner_before(__rhs); } 00533 00534 template<typename _Tp, typename _Up> 00535 bool 00536 operator()(weak_ptr<_Tp> const& __lhs, 00537 weak_ptr<_Up> const& __rhs) const 00538 { return __lhs.owner_before(__rhs); } 00539 00540 typedef void is_transparent; 00541 }; 00542 00543 // C++14 §20.8.2.6 00544 template<typename _Tp> 00545 inline bool 00546 atomic_is_lock_free(const shared_ptr<_Tp>* __p) 00547 { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); } 00548 00549 template<typename _Tp> 00550 shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) 00551 { return std::atomic_load<_Tp>(__p); } 00552 00553 template<typename _Tp> 00554 shared_ptr<_Tp> 00555 atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo) 00556 { return std::atomic_load_explicit<_Tp>(__p, __mo); } 00557 00558 template<typename _Tp> 00559 void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 00560 { return std::atomic_store<_Tp>(__p, __r); } 00561 00562 template<typename _Tp> 00563 shared_ptr<_Tp> 00564 atomic_store_explicit(const shared_ptr<_Tp>* __p, 00565 shared_ptr<_Tp> __r, 00566 memory_order __mo) 00567 { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); } 00568 00569 template<typename _Tp> 00570 void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 00571 { return std::atomic_exchange<_Tp>(__p, __r); } 00572 00573 template<typename _Tp> 00574 shared_ptr<_Tp> 00575 atomic_exchange_explicit(const shared_ptr<_Tp>* __p, 00576 shared_ptr<_Tp> __r, 00577 memory_order __mo) 00578 { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); } 00579 00580 template<typename _Tp> 00581 bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, 00582 shared_ptr<_Tp>* __v, 00583 shared_ptr<_Tp> __w) 00584 { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); } 00585 00586 template<typename _Tp> 00587 bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, 00588 shared_ptr<_Tp>* __v, 00589 shared_ptr<_Tp> __w) 00590 { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); } 00591 00592 template<typename _Tp> 00593 bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, 00594 shared_ptr<_Tp>* __v, 00595 shared_ptr<_Tp> __w, 00596 memory_order __success, 00597 memory_order __failure) 00598 { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w, 00599 __success, 00600 __failure); } 00601 00602 template<typename _Tp> 00603 bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, 00604 shared_ptr<_Tp>* __v, 00605 shared_ptr<_Tp> __w, 00606 memory_order __success, 00607 memory_order __failure) 00608 { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w, 00609 __success, 00610 __failure); } 00611 00612 //enable_shared_from_this 00613 template<typename _Tp> 00614 class enable_shared_from_this 00615 { 00616 protected: 00617 constexpr enable_shared_from_this() noexcept { } 00618 00619 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 00620 00621 enable_shared_from_this& 00622 operator=(const enable_shared_from_this&) noexcept 00623 { return *this; } 00624 00625 ~enable_shared_from_this() { } 00626 00627 public: 00628 shared_ptr<_Tp> 00629 shared_from_this() 00630 { return shared_ptr<_Tp>(this->_M_weak_this); } 00631 00632 shared_ptr<const _Tp> 00633 shared_from_this() const 00634 { return shared_ptr<const _Tp>(this->_M_weak_this); } 00635 00636 weak_ptr<_Tp> 00637 weak_from_this() noexcept 00638 { return _M_weak_this; } 00639 00640 weak_ptr<const _Tp> 00641 weak_from_this() const noexcept 00642 { return _M_weak_this; } 00643 00644 private: 00645 template<typename _Tp1> 00646 void 00647 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 00648 { _M_weak_this._M_assign(__p, __n); } 00649 00650 // Found by ADL when this is an associated class. 00651 friend const enable_shared_from_this* 00652 __expt_enable_shared_from_this_base(const enable_shared_from_this* __p) 00653 { return __p; } 00654 00655 template<typename> 00656 friend class shared_ptr; 00657 00658 mutable weak_ptr<_Tp> _M_weak_this; 00659 }; 00660 } // namespace fundamentals_v2 00661 } // namespace experimental 00662 00663 /// std::hash specialization for shared_ptr. 00664 template<typename _Tp> 00665 struct hash<experimental::shared_ptr<_Tp>> 00666 : public __hash_base<size_t, experimental::shared_ptr<_Tp>> 00667 { 00668 size_t 00669 operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept 00670 { return std::hash<_Tp*>()(__s.get()); } 00671 }; 00672 00673 _GLIBCXX_END_NAMESPACE_VERSION 00674 } // namespace std 00675 00676 #endif // __cplusplus <= 201103L 00677 00678 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H