1 // Experimental shared_ptr with array support -*- C++ -*- 2 3 // Copyright (C) 2015-2016 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file experimental/bits/shared_ptr.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{experimental/memory} 28 */ 29 30 #ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 31 #define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1 32 33 #pragma GCC system_header 34 35 #if __cplusplus <= 201103L 36 # include <bits/c++14_warning.h> 37 #else 38 39 #include <memory> 40 #include <experimental/type_traits> 41 42 namespace std _GLIBCXX_VISIBILITY(default) 43 { 44 namespace experimental 45 { 46 inline namespace fundamentals_v2 47 { 48 _GLIBCXX_BEGIN_NAMESPACE_VERSION 49 template<typename _Tp> class enable_shared_from_this; 50 _GLIBCXX_END_NAMESPACE_VERSION 51 } // namespace fundamentals_v2 52 } // namespace experimental 53 54 #define __cpp_lib_experimental_shared_ptr_arrays 201406 55 56 _GLIBCXX_BEGIN_NAMESPACE_VERSION 57 58 /* 59 * The specification of std::experimental::shared_ptr is slightly different 60 * to std::shared_ptr (specifically in terms of "compatible" pointers) so 61 * to implement std::experimental::shared_ptr without too much duplication 62 * we make it derive from a partial specialization of std::__shared_ptr 63 * using a special tag type, __libfund_v1. 64 * 65 * There are two partial specializations for the tag type, supporting the 66 * different interfaces of the array and non-array forms. 67 */ 68 69 template <typename _Tp, bool = is_array<_Tp>::value> 70 struct __libfund_v1 { using type = _Tp; }; 71 72 // Partial specialization for base class of experimental::shared_ptr<T> 73 // (i.e. the non-array form of experimental::shared_ptr) 74 template<typename _Tp, _Lock_policy _Lp> 75 class __shared_ptr<__libfund_v1<_Tp, false>, _Lp> 76 : private __shared_ptr<_Tp, _Lp> 77 { 78 // For non-arrays, Y* is compatible with T* if Y* is convertible to T*. 79 template<typename _Yp, typename _Res = void> 80 using _Compatible 81 = enable_if_t<experimental::is_convertible_v<_Yp*, _Tp*>, _Res>; 82 83 template<typename _Yp, typename _Del, 84 typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer, 85 typename _Res = void> 86 using _UniqCompatible = enable_if_t< 87 experimental::is_convertible_v<_Yp*, _Tp*> 88 && experimental::is_convertible_v<_Ptr, _Tp*>, 89 _Res>; 90 91 using _Base_type = __shared_ptr<_Tp>; 92 93 _Base_type& _M_get_base() { return *this; } 94 const _Base_type& _M_get_base() const { return *this; } 95 96 public: 97 using element_type = _Tp; 98 99 constexpr __shared_ptr() noexcept = default; 100 101 template<typename _Tp1, typename = _Compatible<_Tp1>> 102 explicit 103 __shared_ptr(_Tp1* __p) 104 : _Base_type(__p) 105 { } 106 107 template<typename _Tp1, typename _Deleter, typename = _Compatible<_Tp1>> 108 __shared_ptr(_Tp1* __p, _Deleter __d) 109 : _Base_type(__p, __d) 110 { } 111 112 template<typename _Tp1, typename _Deleter, typename _Alloc, 113 typename = _Compatible<_Tp1>> 114 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 115 : _Base_type(__p, __d, __a) 116 { } 117 118 template<typename _Deleter> 119 __shared_ptr(nullptr_t __p, _Deleter __d) 120 : _Base_type(__p, __d) 121 { } 122 123 template<typename _Deleter, typename _Alloc> 124 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 125 : _Base_type(__p, __d, __a) 126 { } 127 128 template<typename _Tp1> 129 __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r, 130 element_type* __p) noexcept 131 : _Base_type(__r._M_get_base(), __p) 132 { } 133 134 __shared_ptr(const __shared_ptr&) noexcept = default; 135 __shared_ptr(__shared_ptr&&) noexcept = default; 136 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 137 __shared_ptr& operator=(__shared_ptr&&) noexcept = default; 138 ~__shared_ptr() = default; 139 140 template<typename _Tp1, typename = _Compatible<_Tp1>> 141 __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 142 : _Base_type(__r._M_get_base()) 143 { } 144 145 template<typename _Tp1, typename = _Compatible<_Tp1>> 146 __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept 147 : _Base_type(std::move((__r._M_get_base()))) 148 { } 149 150 template<typename _Tp1, typename = _Compatible<_Tp1>> 151 explicit 152 __shared_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) 153 : _Base_type(__r._M_get_base()) 154 { } 155 156 template<typename _Tp1, typename _Del, 157 typename = _UniqCompatible<_Tp1, _Del>> 158 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r) 159 : _Base_type(std::move(__r)) 160 { } 161 162 #if _GLIBCXX_USE_DEPRECATED 163 // Postcondition: use_count() == 1 and __r.get() == 0 164 template<typename _Tp1, typename = _Compatible<_Tp1>> 165 __shared_ptr(std::auto_ptr<_Tp1>&& __r) 166 : _Base_type(std::move(__r)) 167 { } 168 #endif 169 170 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 171 172 // reset 173 void 174 reset() noexcept 175 { __shared_ptr(nullptr).swap(*this); } 176 177 template<typename _Tp1> 178 _Compatible<_Tp1> 179 reset(_Tp1* __p) 180 { 181 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != get()); 182 __shared_ptr(__p).swap(*this); 183 } 184 185 template<typename _Tp1, typename _Deleter> 186 _Compatible<_Tp1> 187 reset(_Tp1* __p, _Deleter __d) 188 { __shared_ptr(__p, __d).swap(*this); } 189 190 template<typename _Tp1, typename _Deleter, typename _Alloc> 191 _Compatible<_Tp1> 192 reset(_Tp1* __p, _Deleter __d, _Alloc __a) 193 { __shared_ptr(__p, __d, std::move(__a)).swap(*this); } 194 195 using _Base_type::operator*; 196 using _Base_type::operator->; 197 198 template<typename _Tp1> 199 _Compatible<_Tp1, __shared_ptr&> 200 operator=(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 201 { 202 _Base_type::operator=(__r._M_get_base()); 203 return *this; 204 } 205 206 template<class _Tp1> 207 _Compatible<_Tp1, __shared_ptr&> 208 operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept 209 { 210 _Base_type::operator=(std::move(__r._M_get_base())); 211 return *this; 212 } 213 214 template<typename _Tp1, typename _Del> 215 _UniqCompatible<_Tp1, _Del, __shared_ptr&> 216 operator=(unique_ptr<_Tp1, _Del>&& __r) 217 { 218 _Base_type::operator=(std::move(__r)); 219 return *this; 220 } 221 222 #if _GLIBCXX_USE_DEPRECATED 223 template<typename _Tp1> 224 _Compatible<_Tp1, __shared_ptr&> 225 operator=(std::auto_ptr<_Tp1>&& __r) 226 { 227 _Base_type::operator=(std::move(__r)); 228 return *this; 229 } 230 #endif 231 232 void 233 swap(__shared_ptr& __other) noexcept 234 { _Base_type::swap(__other); } 235 236 template<typename _Tp1> 237 bool 238 owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const 239 { return _Base_type::owner_before(__rhs._M_get_base()); } 240 241 template<typename _Tp1> 242 bool 243 owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const 244 { return _Base_type::owner_before(__rhs._M_get_base()); } 245 246 using _Base_type::operator bool; 247 using _Base_type::get; 248 using _Base_type::unique; 249 using _Base_type::use_count; 250 251 protected: 252 253 // make_shared not yet support for shared_ptr_arrays 254 //template<typename _Alloc, typename... _Args> 255 // __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 256 // _Args&&... __args) 257 // : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 258 // std::forward<_Args>(__args)...) 259 // { 260 // void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 261 // _M_ptr = static_cast<_Tp*>(__p); 262 // } 263 264 // __weak_ptr::lock() 265 __shared_ptr(const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r, 266 std::nothrow_t) 267 : _Base_type(__r._M_get_base(), std::nothrow) 268 { } 269 270 private: 271 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 272 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 273 274 // TODO 275 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 276 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 277 }; 278 279 // Helper traits for shared_ptr of array: 280 281 // Trait that tests if Y* is compatible with T*, for shared_ptr purposes. 282 template<typename _Yp, typename _Tp> 283 struct __sp_compatible 284 : is_convertible<_Yp*, _Tp*>::type 285 { }; 286 287 template<size_t _Nm, typename _Tp> 288 struct __sp_compatible<_Tp[_Nm], _Tp[]> 289 : true_type 290 { }; 291 292 template<size_t _Nm, typename _Tp> 293 struct __sp_compatible<_Tp[_Nm], const _Tp[]> 294 : true_type 295 { }; 296 297 template<typename _Yp, typename _Tp> 298 constexpr bool __sp_compatible_v 299 = __sp_compatible<_Yp, _Tp>::value; 300 301 // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N]. 302 template<typename _Up, size_t _Nm, typename _Yp, typename = void> 303 struct __sp_is_constructible_arrN 304 : false_type 305 { }; 306 307 template<typename _Up, size_t _Nm, typename _Yp> 308 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>> 309 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type 310 { }; 311 312 // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[]. 313 template<typename _Up, typename _Yp, typename = void> 314 struct __sp_is_constructible_arr 315 : false_type 316 { }; 317 318 template<typename _Up, typename _Yp> 319 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>> 320 : is_convertible<_Yp(*)[], _Up(*)[]>::type 321 { }; 322 323 // Trait to check if shared_ptr<T> can be constructed from Y*. 324 template<typename _Tp, typename _Yp> 325 struct __sp_is_constructible; 326 327 // When T is U[N], Y(*)[N] shall be convertible to T*; 328 template<typename _Up, size_t _Nm, typename _Yp> 329 struct __sp_is_constructible<_Up[_Nm], _Yp> 330 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type 331 { }; 332 333 // when T is U[], Y(*)[] shall be convertible to T*; 334 template<typename _Up, typename _Yp> 335 struct __sp_is_constructible<_Up[], _Yp> 336 : __sp_is_constructible_arr<_Up, _Yp>::type 337 { }; 338 339 // otherwise, Y* shall be convertible to T*. 340 template<typename _Tp, typename _Yp> 341 struct __sp_is_constructible 342 : is_convertible<_Yp*, _Tp*>::type 343 { }; 344 345 template<typename _Tp, typename _Yp> 346 constexpr bool __sp_is_constructible_v 347 = __sp_is_constructible<_Tp, _Yp>::value; 348 349 350 // Partial specialization for base class of experimental::shared_ptr<T[N]> 351 // and experimental::shared_ptr<T[]> (i.e. the array forms). 352 template<typename _Tp, _Lock_policy _Lp> 353 class __shared_ptr<__libfund_v1<_Tp, true>, _Lp> 354 : private __shared_ptr<remove_extent_t<_Tp>, _Lp> 355 { 356 public: 357 using element_type = remove_extent_t<_Tp>; 358 359 private: 360 struct _Array_deleter 361 { 362 void 363 operator()(element_type const *__p) const 364 { delete [] __p; } 365 }; 366 367 // Constraint for constructing/resetting with a pointer of type _Yp*: 368 template<typename _Yp> 369 using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>; 370 371 // Constraint for constructing/assigning from smart_pointer<_Tp1>: 372 template<typename _Tp1, typename _Res = void> 373 using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>; 374 375 // Constraint for constructing/assigning from unique_ptr<_Tp1, _Del>: 376 template<typename _Tp1, typename _Del, 377 typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer, 378 typename _Res = void> 379 using _UniqCompatible = enable_if_t< 380 __sp_compatible_v<_Tp1, _Tp> 381 && experimental::is_convertible_v<_Ptr, element_type*>, 382 _Res>; 383 384 using _Base_type = __shared_ptr<element_type>; 385 386 _Base_type& _M_get_base() { return *this; } 387 const _Base_type& _M_get_base() const { return *this; } 388 389 public: 390 constexpr __shared_ptr() noexcept 391 : _Base_type() 392 { } 393 394 template<typename _Tp1, typename = _SafeConv<_Tp1>> 395 explicit 396 __shared_ptr(_Tp1* __p) 397 : _Base_type(__p, _Array_deleter()) 398 { } 399 400 template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>> 401 __shared_ptr(_Tp1* __p, _Deleter __d) 402 : _Base_type(__p, __d) 403 { } 404 405 template<typename _Tp1, typename _Deleter, typename _Alloc, 406 typename = _SafeConv<_Tp1>> 407 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 408 : _Base_type(__p, __d, __a) 409 { } 410 411 template<typename _Deleter> 412 __shared_ptr(nullptr_t __p, _Deleter __d) 413 : _Base_type(__p, __d) 414 { } 415 416 template<typename _Deleter, typename _Alloc> 417 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 418 : _Base_type(__p, __d, __a) 419 { } 420 421 template<typename _Tp1> 422 __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r, 423 element_type* __p) noexcept 424 : _Base_type(__r._M_get_base(), __p) 425 { } 426 427 __shared_ptr(const __shared_ptr&) noexcept = default; 428 __shared_ptr(__shared_ptr&&) noexcept = default; 429 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 430 __shared_ptr& operator=(__shared_ptr&&) noexcept = default; 431 ~__shared_ptr() = default; 432 433 template<typename _Tp1, typename = _Compatible<_Tp1>> 434 __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 435 : _Base_type(__r._M_get_base()) 436 { } 437 438 template<typename _Tp1, typename = _Compatible<_Tp1>> 439 __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept 440 : _Base_type(std::move((__r._M_get_base()))) 441 { } 442 443 template<typename _Tp1, typename = _Compatible<_Tp1>> 444 explicit 445 __shared_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) 446 : _Base_type(__r._M_get_base()) 447 { } 448 449 template<typename _Tp1, typename _Del, 450 typename = _UniqCompatible<_Tp1, _Del>> 451 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r) 452 : _Base_type(std::move(__r)) 453 { } 454 455 #if _GLIBCXX_USE_DEPRECATED 456 // Postcondition: use_count() == 1 and __r.get() == 0 457 template<typename _Tp1, typename = _Compatible<_Tp1>> 458 __shared_ptr(auto_ptr<_Tp1>&& __r) 459 : _Base_type(std::move(__r)) 460 { } 461 #endif 462 463 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 464 465 // reset 466 void 467 reset() noexcept 468 { __shared_ptr(nullptr).swap(*this); } 469 470 template<typename _Tp1> 471 _SafeConv<_Tp1> 472 reset(_Tp1* __p) 473 { 474 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != get()); 475 __shared_ptr(__p, _Array_deleter()).swap(*this); 476 } 477 478 template<typename _Tp1, typename _Deleter> 479 _SafeConv<_Tp1> 480 reset(_Tp1* __p, _Deleter __d) 481 { __shared_ptr(__p, __d).swap(*this); } 482 483 template<typename _Tp1, typename _Deleter, typename _Alloc> 484 _SafeConv<_Tp1> 485 reset(_Tp1* __p, _Deleter __d, _Alloc __a) 486 { __shared_ptr(__p, __d, std::move(__a)).swap(*this); } 487 488 element_type& 489 operator[](ptrdiff_t i) const noexcept 490 { 491 _GLIBCXX_DEBUG_ASSERT(get() != 0 && i >= 0); 492 return get()[i]; 493 } 494 495 template<typename _Tp1> 496 _Compatible<_Tp1, __shared_ptr&> 497 operator=(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 498 { 499 _Base_type::operator=(__r._M_get_base()); 500 return *this; 501 } 502 503 template<class _Tp1> 504 _Compatible<_Tp1, __shared_ptr&> 505 operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept 506 { 507 _Base_type::operator=(std::move(__r._M_get_base())); 508 return *this; 509 } 510 511 template<typename _Tp1, typename _Del> 512 _UniqCompatible<_Tp1, _Del, __shared_ptr&> 513 operator=(unique_ptr<_Tp1, _Del>&& __r) 514 { 515 _Base_type::operator=(std::move(__r)); 516 return *this; 517 } 518 519 #if _GLIBCXX_USE_DEPRECATED 520 template<typename _Tp1> 521 _Compatible<_Tp1, __shared_ptr&> 522 operator=(auto_ptr<_Tp1>&& __r) 523 { 524 _Base_type::operator=(std::move(__r)); 525 return *this; 526 } 527 #endif 528 529 void 530 swap(__shared_ptr& __other) noexcept 531 { _Base_type::swap(__other); } 532 533 template<typename _Tp1> 534 bool 535 owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const 536 { return _Base_type::owner_before(__rhs._M_get_base()); } 537 538 template<typename _Tp1> 539 bool 540 owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const 541 { return _Base_type::owner_before(__rhs._M_get_base()); } 542 543 using _Base_type::operator bool; 544 using _Base_type::get; 545 using _Base_type::unique; 546 using _Base_type::use_count; 547 548 protected: 549 550 // make_shared not yet support for shared_ptr_arrays 551 //template<typename _Alloc, typename... _Args> 552 // __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 553 // _Args&&... __args) 554 // : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 555 // std::forward<_Args>(__args)...) 556 // { 557 // void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 558 // _M_ptr = static_cast<_Tp*>(__p); 559 // } 560 561 // __weak_ptr::lock() 562 __shared_ptr(const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r, 563 std::nothrow_t) 564 : _Base_type(__r._M_get_base(), std::nothrow) 565 { } 566 567 private: 568 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 569 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 570 571 // TODO 572 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 573 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 574 }; 575 576 // weak_ptr specialization for __shared_ptr array 577 template<typename _Tp, _Lock_policy _Lp> 578 class __weak_ptr<__libfund_v1<_Tp>, _Lp> 579 : __weak_ptr<remove_extent_t<_Tp>, _Lp> 580 { 581 template<typename _Tp1, typename _Res = void> 582 using _Compatible 583 = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>; 584 585 using _Base_type = __weak_ptr<remove_extent_t<_Tp>>; 586 587 _Base_type& _M_get_base() { return *this; } 588 const _Base_type& _M_get_base() const { return *this; } 589 590 public: 591 using element_type = remove_extent_t<_Tp>; 592 593 constexpr __weak_ptr() noexcept 594 : _Base_type() 595 { } 596 597 __weak_ptr(const __weak_ptr&) noexcept = default; 598 599 ~__weak_ptr() = default; 600 601 template<typename _Tp1, typename = _Compatible<_Tp1>> 602 __weak_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 603 : _Base_type(__r._M_get_base()) 604 { } 605 606 template<typename _Tp1, typename = _Compatible<_Tp1>> 607 __weak_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 608 : _Base_type(__r._M_get_base()) 609 { } 610 611 __weak_ptr(__weak_ptr&& __r) noexcept 612 : _Base_type(std::move(__r)) 613 { } 614 615 template<typename _Tp1, typename = _Compatible<_Tp1>> 616 __weak_ptr(__weak_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept 617 : _Base_type(std::move(__r._M_get_base())) 618 { } 619 620 __weak_ptr& 621 operator=(const __weak_ptr& __r) noexcept = default; 622 623 template<typename _Tp1> 624 _Compatible<_Tp1, __weak_ptr&> 625 operator=(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept 626 { 627 this->_Base_type::operator=(__r._M_get_base()); 628 return *this; 629 } 630 631 template<typename _Tp1> 632 _Compatible<_Tp1, __weak_ptr&> 633 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 634 { 635 this->_Base_type::operator=(__r._M_get_base()); 636 return *this; 637 } 638 639 __weak_ptr& 640 operator=(__weak_ptr&& __r) noexcept 641 { 642 this->_Base_type::operator=(std::move(__r)); 643 return *this; 644 } 645 646 template<typename _Tp1> 647 _Compatible<_Tp1, __weak_ptr&> 648 operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept 649 { 650 this->_Base_type::operator=(std::move(__r._M_get_base())); 651 return *this; 652 } 653 654 void 655 swap(__weak_ptr& __other) noexcept 656 { this->_Base_type::swap(__other); } 657 658 template<typename _Tp1> 659 bool 660 owner_before(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs) const 661 { return _Base_type::owner_before(__rhs._M_get_base()); } 662 663 template<typename _Tp1> 664 bool 665 owner_before(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs) const 666 { return _Base_type::owner_before(__rhs._M_get_base()); } 667 668 __shared_ptr<__libfund_v1<_Tp>, _Lp> 669 lock() const noexcept // should not be element_type 670 { return __shared_ptr<__libfund_v1<_Tp>, _Lp>(*this, std::nothrow); } 671 672 using _Base_type::use_count; 673 using _Base_type::expired; 674 using _Base_type::reset; 675 676 private: 677 // Used by __enable_shared_from_this. 678 void 679 _M_assign(element_type* __ptr, 680 const __shared_count<_Lp>& __refcount) noexcept 681 { this->_Base_type::_M_assign(__ptr, __refcount); } 682 683 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 684 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 685 friend class __enable_shared_from_this<_Tp, _Lp>; 686 friend class experimental::enable_shared_from_this<_Tp>; 687 friend class enable_shared_from_this<_Tp>; 688 }; 689 690 _GLIBCXX_END_NAMESPACE_VERSION 691 692 namespace experimental 693 { 694 inline namespace fundamentals_v2 695 { 696 _GLIBCXX_BEGIN_NAMESPACE_VERSION 697 698 // 8.2.1 699 700 template<typename _Tp> class shared_ptr; 701 template<typename _Tp> class weak_ptr; 702 703 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 704 using __shared_ptr = std::__shared_ptr<__libfund_v1<_Tp>, _Lp>; 705 706 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 707 using __weak_ptr = std::__weak_ptr<__libfund_v1<_Tp>, _Lp>; 708 709 template<typename _Tp> 710 class shared_ptr : public __shared_ptr<_Tp> 711 { 712 using _Base_type = __shared_ptr<_Tp>; 713 714 public: 715 using element_type = typename _Base_type::element_type; 716 717 private: 718 // Constraint for construction from a pointer of type _Yp*: 719 template<typename _Yp> 720 using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>; 721 722 template<typename _Tp1, typename _Res = void> 723 using _Compatible 724 = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>; 725 726 template<typename _Tp1, typename _Del, 727 typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer, 728 typename _Res = void> 729 using _UniqCompatible = enable_if_t< 730 __sp_compatible_v<_Tp1, _Tp> 731 && experimental::is_convertible_v<_Ptr, element_type*>, 732 _Res>; 733 734 public: 735 736 // 8.2.1.1, shared_ptr constructors 737 constexpr shared_ptr() noexcept = default; 738 739 template<typename _Tp1, typename = _SafeConv<_Tp1>> 740 explicit 741 shared_ptr(_Tp1* __p) : _Base_type(__p) 742 { _M_enable_shared_from_this_with(__p); } 743 744 template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>> 745 shared_ptr(_Tp1* __p, _Deleter __d) 746 : _Base_type(__p, __d) 747 { _M_enable_shared_from_this_with(__p); } 748 749 template<typename _Tp1, typename _Deleter, typename _Alloc, 750 typename = _SafeConv<_Tp1>> 751 shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 752 : _Base_type(__p, __d, __a) 753 { _M_enable_shared_from_this_with(__p); } 754 755 template<typename _Deleter> 756 shared_ptr(nullptr_t __p, _Deleter __d) 757 : _Base_type(__p, __d) { } 758 759 template<typename _Deleter, typename _Alloc> 760 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 761 : _Base_type(__p, __d, __a) { } 762 763 template<typename _Tp1> 764 shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept 765 : _Base_type(__r, __p) { } 766 767 shared_ptr(const shared_ptr& __r) noexcept 768 : _Base_type(__r) { } 769 770 template<typename _Tp1, typename = _Compatible<_Tp1>> 771 shared_ptr(const shared_ptr<_Tp1>& __r) noexcept 772 : _Base_type(__r) { } 773 774 shared_ptr(shared_ptr&& __r) noexcept 775 : _Base_type(std::move(__r)) { } 776 777 template<typename _Tp1, typename = _Compatible<_Tp1>> 778 shared_ptr(shared_ptr<_Tp1>&& __r) noexcept 779 : _Base_type(std::move(__r)) { } 780 781 template<typename _Tp1, typename = _Compatible<_Tp1>> 782 explicit 783 shared_ptr(const weak_ptr<_Tp1>& __r) 784 : _Base_type(__r) { } 785 786 #if _GLIBCXX_USE_DEPRECATED 787 template<typename _Tp1, typename = _Compatible<_Tp1>> 788 shared_ptr(std::auto_ptr<_Tp1>&& __r) 789 : _Base_type(std::move(__r)) 790 { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); } 791 #endif 792 793 template<typename _Tp1, typename _Del, 794 typename = _UniqCompatible<_Tp1, _Del>> 795 shared_ptr(unique_ptr<_Tp1, _Del>&& __r) 796 : _Base_type(std::move(__r)) 797 { 798 // XXX assume conversion from __r.get() to this->get() to __elem_t* 799 // is a round trip, which might not be true in all cases. 800 using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type; 801 _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get())); 802 } 803 804 constexpr shared_ptr(nullptr_t __p) 805 : _Base_type(__p) { } 806 807 // C++14 §20.8.2.2 808 ~shared_ptr() = default; 809 810 // C++14 §20.8.2.3 811 shared_ptr& operator=(const shared_ptr&) noexcept = default; 812 813 template <typename _Tp1> 814 _Compatible<_Tp1, shared_ptr&> 815 operator=(const shared_ptr<_Tp1>& __r) noexcept 816 { 817 _Base_type::operator=(__r); 818 return *this; 819 } 820 821 shared_ptr& 822 operator=(shared_ptr&& __r) noexcept 823 { 824 _Base_type::operator=(std::move(__r)); 825 return *this; 826 } 827 828 template <typename _Tp1> 829 _Compatible<_Tp1, shared_ptr&> 830 operator=(shared_ptr<_Tp1>&& __r) noexcept 831 { 832 _Base_type::operator=(std::move(__r)); 833 return *this; 834 } 835 836 #if _GLIBCXX_USE_DEPRECATED 837 template<typename _Tp1> 838 _Compatible<_Tp1, shared_ptr&> 839 operator=(std::auto_ptr<_Tp1>&& __r) 840 { 841 __shared_ptr<_Tp>::operator=(std::move(__r)); 842 return *this; 843 } 844 #endif 845 846 template <typename _Tp1, typename _Del> 847 _UniqCompatible<_Tp1, _Del, shared_ptr&> 848 operator=(unique_ptr<_Tp1, _Del>&& __r) 849 { 850 _Base_type::operator=(std::move(__r)); 851 return *this; 852 } 853 854 // C++14 §20.8.2.2.4 855 // swap & reset 856 // 8.2.1.2 shared_ptr observers 857 // in __shared_ptr 858 859 private: 860 template<typename _Alloc, typename... _Args> 861 shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 862 _Args&&... __args) 863 : _Base_type(__tag, __a, std::forward<_Args>(__args)...) 864 { _M_enable_shared_from_this_with(this->get()); } 865 866 template<typename _Tp1, typename _Alloc, typename... _Args> 867 friend shared_ptr<_Tp1> 868 allocate_shared(const _Alloc& __a, _Args&&... __args); 869 870 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 871 : _Base_type(__r, std::nothrow) { } 872 873 friend class weak_ptr<_Tp>; 874 875 template<typename _Yp> 876 using __esft_base_t = 877 decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>())); 878 879 // Detect an accessible and unambiguous enable_shared_from_this base. 880 template<typename _Yp, typename = void> 881 struct __has_esft_base 882 : false_type { }; 883 884 template<typename _Yp> 885 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> 886 : __bool_constant<!is_array_v<_Tp>> { }; // ignore base for arrays 887 888 template<typename _Yp> 889 typename enable_if<__has_esft_base<_Yp>::value>::type 890 _M_enable_shared_from_this_with(const _Yp* __p) noexcept 891 { 892 if (auto __base = __expt_enable_shared_from_this_base(__p)) 893 { 894 __base->_M_weak_this 895 = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p)); 896 } 897 } 898 899 template<typename _Yp> 900 typename enable_if<!__has_esft_base<_Yp>::value>::type 901 _M_enable_shared_from_this_with(const _Yp*) noexcept 902 { } 903 }; 904 905 // C++14 §20.8.2.2.7 //DOING 906 template<typename _Tp1, typename _Tp2> 907 bool operator==(const shared_ptr<_Tp1>& __a, 908 const shared_ptr<_Tp2>& __b) noexcept 909 { return __a.get() == __b.get(); } 910 911 template<typename _Tp> 912 inline bool 913 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 914 { return !__a; } 915 916 template<typename _Tp> 917 inline bool 918 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 919 { return !__a; } 920 921 template<typename _Tp1, typename _Tp2> 922 inline bool 923 operator!=(const shared_ptr<_Tp1>& __a, 924 const shared_ptr<_Tp2>& __b) noexcept 925 { return __a.get() != __b.get(); } 926 927 template<typename _Tp> 928 inline bool 929 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 930 { return (bool)__a; } 931 932 template<typename _Tp> 933 inline bool 934 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 935 { return (bool)__a; } 936 937 template<typename _Tp1, typename _Tp2> 938 inline bool 939 operator<(const shared_ptr<_Tp1>& __a, 940 const shared_ptr<_Tp2>& __b) noexcept 941 { 942 using __elem_t1 = typename shared_ptr<_Tp1>::element_type; 943 using __elem_t2 = typename shared_ptr<_Tp2>::element_type; 944 using _CT = common_type_t<__elem_t1*, __elem_t2*>; 945 return std::less<_CT>()(__a.get(), __b.get()); 946 } 947 948 template<typename _Tp> 949 inline bool 950 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 951 { 952 using __elem_t = typename shared_ptr<_Tp>::element_type; 953 return std::less<__elem_t*>()(__a.get(), nullptr); 954 } 955 956 template<typename _Tp> 957 inline bool 958 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 959 { 960 using __elem_t = typename shared_ptr<_Tp>::element_type; 961 return std::less<__elem_t*>()(nullptr, __a.get()); 962 } 963 964 template<typename _Tp1, typename _Tp2> 965 inline bool 966 operator<=(const shared_ptr<_Tp1>& __a, 967 const shared_ptr<_Tp2>& __b) noexcept 968 { return !(__b < __a); } 969 970 template<typename _Tp> 971 inline bool 972 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 973 { return !(nullptr < __a); } 974 975 template<typename _Tp> 976 inline bool 977 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 978 { return !(__a < nullptr); } 979 980 template<typename _Tp1, typename _Tp2> 981 inline bool 982 operator>(const shared_ptr<_Tp1>& __a, 983 const shared_ptr<_Tp2>& __b) noexcept 984 { return (__b < __a); } 985 986 template<typename _Tp> 987 inline bool 988 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 989 { 990 using __elem_t = typename shared_ptr<_Tp>::element_type; 991 return std::less<__elem_t*>()(nullptr, __a.get()); 992 } 993 994 template<typename _Tp> 995 inline bool 996 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 997 { 998 using __elem_t = typename shared_ptr<_Tp>::element_type; 999 return std::less<__elem_t*>()(__a.get(), nullptr); 1000 } 1001 1002 template<typename _Tp1, typename _Tp2> 1003 inline bool 1004 operator>=(const shared_ptr<_Tp1>& __a, 1005 const shared_ptr<_Tp2>& __b) noexcept 1006 { return !(__a < __b); } 1007 1008 template<typename _Tp> 1009 inline bool 1010 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 1011 { return !(__a < nullptr); } 1012 1013 template<typename _Tp> 1014 inline bool 1015 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 1016 { return !(nullptr < __a); } 1017 1018 // C++14 §20.8.2.2.8 1019 template<typename _Tp> 1020 inline void 1021 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 1022 { __a.swap(__b); } 1023 1024 // 8.2.1.3, shared_ptr casts 1025 template<typename _Tp, typename _Tp1> 1026 inline shared_ptr<_Tp> 1027 static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 1028 { 1029 using __elem_t = typename shared_ptr<_Tp>::element_type; 1030 return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get())); 1031 } 1032 1033 template<typename _Tp, typename _Tp1> 1034 inline shared_ptr<_Tp> 1035 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 1036 { 1037 using __elem_t = typename shared_ptr<_Tp>::element_type; 1038 if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get())) 1039 return shared_ptr<_Tp>(__r, __p); 1040 return shared_ptr<_Tp>(); 1041 } 1042 1043 template<typename _Tp, typename _Tp1> 1044 inline shared_ptr<_Tp> 1045 const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 1046 { 1047 using __elem_t = typename shared_ptr<_Tp>::element_type; 1048 return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get())); 1049 } 1050 1051 template<typename _Tp, typename _Tp1> 1052 inline shared_ptr<_Tp> 1053 reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 1054 { 1055 using __elem_t = typename shared_ptr<_Tp>::element_type; 1056 return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get())); 1057 } 1058 1059 // C++14 §20.8.2.3 1060 template<typename _Tp> 1061 class weak_ptr : public __weak_ptr<_Tp> 1062 { 1063 template<typename _Tp1, typename _Res = void> 1064 using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>; 1065 1066 using _Base_type = __weak_ptr<_Tp>; 1067 1068 public: 1069 constexpr weak_ptr() noexcept = default; 1070 1071 template<typename _Tp1, typename = _Compatible<_Tp1>> 1072 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept 1073 : _Base_type(__r) { } 1074 1075 weak_ptr(const weak_ptr&) noexcept = default; 1076 1077 template<typename _Tp1, typename = _Compatible<_Tp1>> 1078 weak_ptr(const weak_ptr<_Tp1>& __r) noexcept 1079 : _Base_type(__r) { } 1080 1081 weak_ptr(weak_ptr&&) noexcept = default; 1082 1083 template<typename _Tp1, typename = _Compatible<_Tp1>> 1084 weak_ptr(weak_ptr<_Tp1>&& __r) noexcept 1085 : _Base_type(std::move(__r)) { } 1086 1087 weak_ptr& 1088 operator=(const weak_ptr& __r) noexcept = default; 1089 1090 template<typename _Tp1> 1091 _Compatible<_Tp1, weak_ptr&> 1092 operator=(const weak_ptr<_Tp1>& __r) noexcept 1093 { 1094 this->_Base_type::operator=(__r); 1095 return *this; 1096 } 1097 1098 template<typename _Tp1> 1099 _Compatible<_Tp1, weak_ptr&> 1100 operator=(const shared_ptr<_Tp1>& __r) noexcept 1101 { 1102 this->_Base_type::operator=(__r); 1103 return *this; 1104 } 1105 1106 weak_ptr& 1107 operator=(weak_ptr&& __r) noexcept = default; 1108 1109 template<typename _Tp1> 1110 _Compatible<_Tp1, weak_ptr&> 1111 operator=(weak_ptr<_Tp1>&& __r) noexcept 1112 { 1113 this->_Base_type::operator=(std::move(__r)); 1114 return *this; 1115 } 1116 1117 shared_ptr<_Tp> 1118 lock() const noexcept 1119 { return shared_ptr<_Tp>(*this, std::nothrow); } 1120 1121 friend class enable_shared_from_this<_Tp>; 1122 }; 1123 1124 // C++14 §20.8.2.3.6 1125 template<typename _Tp> 1126 inline void 1127 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 1128 { __a.swap(__b); } 1129 1130 /// C++14 §20.8.2.2.10 1131 template<typename _Del, typename _Tp, _Lock_policy _Lp> 1132 inline _Del* 1133 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 1134 { return std::get_deleter<_Del>(__p); } 1135 1136 // C++14 §20.8.2.2.11 1137 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 1138 inline std::basic_ostream<_Ch, _Tr>& 1139 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 1140 const __shared_ptr<_Tp, _Lp>& __p) 1141 { 1142 __os << __p.get(); 1143 return __os; 1144 } 1145 1146 // C++14 §20.8.2.4 1147 template<typename _Tp = void> class owner_less; 1148 1149 /// Partial specialization of owner_less for shared_ptr. 1150 template<typename _Tp> 1151 struct owner_less<shared_ptr<_Tp>> 1152 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 1153 { }; 1154 1155 /// Partial specialization of owner_less for weak_ptr. 1156 template<typename _Tp> 1157 struct owner_less<weak_ptr<_Tp>> 1158 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 1159 { }; 1160 1161 template<> 1162 class owner_less<void> 1163 { 1164 template<typename _Tp, typename _Up> 1165 bool 1166 operator()(shared_ptr<_Tp> const& __lhs, 1167 shared_ptr<_Up> const& __rhs) const 1168 { return __lhs.owner_before(__rhs); } 1169 1170 template<typename _Tp, typename _Up> 1171 bool 1172 operator()(shared_ptr<_Tp> const& __lhs, 1173 weak_ptr<_Up> const& __rhs) const 1174 { return __lhs.owner_before(__rhs); } 1175 1176 template<typename _Tp, typename _Up> 1177 bool 1178 operator()(weak_ptr<_Tp> const& __lhs, 1179 shared_ptr<_Up> const& __rhs) const 1180 { return __lhs.owner_before(__rhs); } 1181 1182 template<typename _Tp, typename _Up> 1183 bool 1184 operator()(weak_ptr<_Tp> const& __lhs, 1185 weak_ptr<_Up> const& __rhs) const 1186 { return __lhs.owner_before(__rhs); } 1187 1188 typedef void is_transparent; 1189 }; 1190 1191 // C++14 §20.8.2.6 1192 template<typename _Tp> 1193 inline bool 1194 atomic_is_lock_free(const shared_ptr<_Tp>* __p) 1195 { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); } 1196 1197 template<typename _Tp> 1198 shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) 1199 { return std::atomic_load<_Tp>(__p); } 1200 1201 template<typename _Tp> 1202 shared_ptr<_Tp> 1203 atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo) 1204 { return std::atomic_load_explicit<_Tp>(__p, __mo); } 1205 1206 template<typename _Tp> 1207 void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 1208 { return std::atomic_store<_Tp>(__p, __r); } 1209 1210 template<typename _Tp> 1211 shared_ptr<_Tp> 1212 atomic_store_explicit(const shared_ptr<_Tp>* __p, 1213 shared_ptr<_Tp> __r, 1214 memory_order __mo) 1215 { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); } 1216 1217 template<typename _Tp> 1218 void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 1219 { return std::atomic_exchange<_Tp>(__p, __r); } 1220 1221 template<typename _Tp> 1222 shared_ptr<_Tp> 1223 atomic_exchange_explicit(const shared_ptr<_Tp>* __p, 1224 shared_ptr<_Tp> __r, 1225 memory_order __mo) 1226 { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); } 1227 1228 template<typename _Tp> 1229 bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, 1230 shared_ptr<_Tp>* __v, 1231 shared_ptr<_Tp> __w) 1232 { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); } 1233 1234 template<typename _Tp> 1235 bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, 1236 shared_ptr<_Tp>* __v, 1237 shared_ptr<_Tp> __w) 1238 { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); } 1239 1240 template<typename _Tp> 1241 bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, 1242 shared_ptr<_Tp>* __v, 1243 shared_ptr<_Tp> __w, 1244 memory_order __success, 1245 memory_order __failure) 1246 { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w, 1247 __success, 1248 __failure); } 1249 1250 template<typename _Tp> 1251 bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, 1252 shared_ptr<_Tp>* __v, 1253 shared_ptr<_Tp> __w, 1254 memory_order __success, 1255 memory_order __failure) 1256 { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w, 1257 __success, 1258 __failure); } 1259 1260 //enable_shared_from_this 1261 template<typename _Tp> 1262 class enable_shared_from_this 1263 { 1264 protected: 1265 constexpr enable_shared_from_this() noexcept { } 1266 1267 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 1268 1269 enable_shared_from_this& 1270 operator=(const enable_shared_from_this&) noexcept 1271 { return *this; } 1272 1273 ~enable_shared_from_this() { } 1274 1275 public: 1276 shared_ptr<_Tp> 1277 shared_from_this() 1278 { return shared_ptr<_Tp>(this->_M_weak_this); } 1279 1280 shared_ptr<const _Tp> 1281 shared_from_this() const 1282 { return shared_ptr<const _Tp>(this->_M_weak_this); } 1283 1284 weak_ptr<_Tp> 1285 weak_from_this() noexcept 1286 { return _M_weak_this; } 1287 1288 weak_ptr<const _Tp> 1289 weak_from_this() const noexcept 1290 { return _M_weak_this; } 1291 1292 private: 1293 template<typename _Tp1> 1294 void 1295 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 1296 { _M_weak_this._M_assign(__p, __n); } 1297 1298 // Found by ADL when this is an associated class. 1299 friend const enable_shared_from_this* 1300 __expt_enable_shared_from_this_base(const enable_shared_from_this* __p) 1301 { return __p; } 1302 1303 template<typename> 1304 friend class shared_ptr; 1305 1306 mutable weak_ptr<_Tp> _M_weak_this; 1307 }; 1308 1309 _GLIBCXX_END_NAMESPACE_VERSION 1310 } // namespace fundamentals_v2 1311 } // namespace experimental 1312 1313 _GLIBCXX_BEGIN_NAMESPACE_VERSION 1314 1315 /// std::hash specialization for shared_ptr. 1316 template<typename _Tp> 1317 struct hash<experimental::shared_ptr<_Tp>> 1318 : public __hash_base<size_t, experimental::shared_ptr<_Tp>> 1319 { 1320 size_t 1321 operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept 1322 { return std::hash<_Tp*>()(__s.get()); } 1323 }; 1324 1325 _GLIBCXX_END_NAMESPACE_VERSION 1326 } // namespace std 1327 1328 #endif // __cplusplus <= 201103L 1329 1330 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1331