libstdc++
experimental/bits/shared_ptr.h
Go to the documentation of this file.
1 // Experimental shared_ptr with array support -*- C++ -*-
2 
3 // Copyright (C) 2015-2025 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 #ifdef _GLIBCXX_SYSHDR
34 #pragma GCC system_header
35 #endif
36 
37 #if __cplusplus >= 201402L
38 
39 #include <memory>
40 #include <experimental/type_traits>
41 
42 namespace std _GLIBCXX_VISIBILITY(default)
43 {
44 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 
46 namespace experimental
47 {
48 inline namespace fundamentals_v2
49 {
50  // 8.2.1
51 
52  template<typename _Tp> class shared_ptr;
53  template<typename _Tp> class weak_ptr;
54  template<typename _Tp> class enable_shared_from_this;
55 
56  template<typename _Yp, typename _Tp>
57  constexpr bool __sp_compatible_v
58  = std::__sp_compatible_with<_Yp*, _Tp*>::value;
59 
60  template<typename _Tp, typename _Yp>
61  constexpr bool __sp_is_constructible_v
62  = std::__sp_is_constructible<_Tp, _Yp>::value;
63 
64  template<typename _Tp>
65  class shared_ptr : public __shared_ptr<_Tp>
66  {
67  using _Base_type = __shared_ptr<_Tp>;
68 
69  public:
70  using element_type = typename _Base_type::element_type;
71 
72  private:
73  // Constraint for construction from a pointer of type _Yp*:
74  template<typename _Yp>
75  using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
76 
77  template<typename _Tp1, typename _Res = void>
78  using _Compatible
79  = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
80 
81  template<typename _Tp1, typename _Del,
82  typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
83  typename _Res = void>
84  using _UniqCompatible = enable_if_t<
85  __sp_compatible_v<_Tp1, _Tp>
86  && experimental::is_convertible_v<_Ptr, element_type*>,
87  _Res>;
88 
89  public:
90 
91  // 8.2.1.1, shared_ptr constructors
92  constexpr shared_ptr() noexcept = default;
93 
94  template<typename _Tp1, typename = _SafeConv<_Tp1>>
95  explicit
96  shared_ptr(_Tp1* __p) : _Base_type(__p)
97  { _M_enable_shared_from_this_with(__p); }
98 
99  template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
100  shared_ptr(_Tp1* __p, _Deleter __d)
101  : _Base_type(__p, __d)
102  { _M_enable_shared_from_this_with(__p); }
103 
104  template<typename _Tp1, typename _Deleter, typename _Alloc,
105  typename = _SafeConv<_Tp1>>
106  shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
107  : _Base_type(__p, __d, __a)
108  { _M_enable_shared_from_this_with(__p); }
109 
110  template<typename _Deleter>
111  shared_ptr(nullptr_t __p, _Deleter __d)
112  : _Base_type(__p, __d) { }
113 
114  template<typename _Deleter, typename _Alloc>
115  shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
116  : _Base_type(__p, __d, __a) { }
117 
118  template<typename _Tp1>
119  shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
120  : _Base_type(__r, __p) { }
121 
122  shared_ptr(const shared_ptr& __r) noexcept
123  : _Base_type(__r) { }
124 
125  template<typename _Tp1, typename = _Compatible<_Tp1>>
126  shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
127  : _Base_type(__r) { }
128 
129  shared_ptr(shared_ptr&& __r) noexcept
130  : _Base_type(std::move(__r)) { }
131 
132  template<typename _Tp1, typename = _Compatible<_Tp1>>
133  shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
134  : _Base_type(std::move(__r)) { }
135 
136  template<typename _Tp1, typename = _Compatible<_Tp1>>
137  explicit
138  shared_ptr(const weak_ptr<_Tp1>& __r)
139  : _Base_type(__r) { }
140 
141 #if _GLIBCXX_USE_DEPRECATED
142 #pragma GCC diagnostic push
143 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
144  template<typename _Tp1, typename = _Compatible<_Tp1>>
145  shared_ptr(std::auto_ptr<_Tp1>&& __r)
146  : _Base_type(std::move(__r))
147  { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); }
148 #pragma GCC diagnostic pop
149 #endif
150 
151  template<typename _Tp1, typename _Del,
152  typename = _UniqCompatible<_Tp1, _Del>>
153  shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
154  : _Base_type(std::move(__r))
155  {
156  // XXX assume conversion from __r.get() to this->get() to __elem_t*
157  // is a round trip, which might not be true in all cases.
158  using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type;
159  _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get()));
160  }
161 
162  constexpr shared_ptr(nullptr_t __p)
163  : _Base_type(__p) { }
164 
165  // C++14 20.8.2.2
166  ~shared_ptr() = default;
167 
168  // C++14 20.8.2.3
169  shared_ptr& operator=(const shared_ptr&) noexcept = default;
170 
171  template <typename _Tp1>
172  _Compatible<_Tp1, shared_ptr&>
173  operator=(const shared_ptr<_Tp1>& __r) noexcept
174  {
175  _Base_type::operator=(__r);
176  return *this;
177  }
178 
179  shared_ptr&
180  operator=(shared_ptr&& __r) noexcept
181  {
182  _Base_type::operator=(std::move(__r));
183  return *this;
184  }
185 
186  template <typename _Tp1>
187  _Compatible<_Tp1, shared_ptr&>
188  operator=(shared_ptr<_Tp1>&& __r) noexcept
189  {
190  _Base_type::operator=(std::move(__r));
191  return *this;
192  }
193 
194 #if _GLIBCXX_USE_DEPRECATED
195 #pragma GCC diagnostic push
196 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
197  template<typename _Tp1>
198  _Compatible<_Tp1, shared_ptr&>
199  operator=(std::auto_ptr<_Tp1>&& __r)
200  {
201  __shared_ptr<_Tp>::operator=(std::move(__r));
202  return *this;
203  }
204 #pragma GCC diagnostic pop
205 #endif
206 
207  template <typename _Tp1, typename _Del>
208  _UniqCompatible<_Tp1, _Del, shared_ptr&>
209  operator=(unique_ptr<_Tp1, _Del>&& __r)
210  {
211  _Base_type::operator=(std::move(__r));
212  return *this;
213  }
214 
215  // C++14 20.8.2.2.4
216  // swap & reset
217  // 8.2.1.2 shared_ptr observers
218  // in __shared_ptr
219 
220  private:
221  template<typename _Alloc, typename... _Args>
222  shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
223  _Args&&... __args)
224  : _Base_type(__tag, __a, std::forward<_Args>(__args)...)
225  { _M_enable_shared_from_this_with(this->get()); }
226 
227  template<typename _Tp1, typename _Alloc, typename... _Args>
228  friend shared_ptr<_Tp1>
229  allocate_shared(const _Alloc& __a, _Args&&... __args);
230 
231  shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
232  : _Base_type(__r, std::nothrow) { }
233 
234  friend class weak_ptr<_Tp>;
235 
236  template<typename _Yp>
237  using __esft_base_t =
238  decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
239 
240  // Detect an accessible and unambiguous enable_shared_from_this base.
241  template<typename _Yp, typename = void>
242  struct __has_esft_base
243  : false_type { };
244 
245  template<typename _Yp>
246  struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
247  : __bool_constant<!is_array_v<_Tp>> { }; // ignore base for arrays
248 
249  template<typename _Yp>
250  typename enable_if<__has_esft_base<_Yp>::value>::type
251  _M_enable_shared_from_this_with(const _Yp* __p) noexcept
252  {
253  if (auto __base = __expt_enable_shared_from_this_base(__p))
254  {
255  __base->_M_weak_this
256  = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p));
257  }
258  }
259 
260  template<typename _Yp>
261  typename enable_if<!__has_esft_base<_Yp>::value>::type
262  _M_enable_shared_from_this_with(const _Yp*) noexcept
263  { }
264  };
265 
266  // C++14 20.8.2.2.7
267  template<typename _Tp1, typename _Tp2>
268  bool operator==(const shared_ptr<_Tp1>& __a,
269  const shared_ptr<_Tp2>& __b) noexcept
270  { return __a.get() == __b.get(); }
271 
272  template<typename _Tp>
273  inline bool
274  operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
275  { return !__a; }
276 
277  template<typename _Tp>
278  inline bool
279  operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
280  { return !__a; }
281 
282  template<typename _Tp1, typename _Tp2>
283  inline bool
284  operator!=(const shared_ptr<_Tp1>& __a,
285  const shared_ptr<_Tp2>& __b) noexcept
286  { return __a.get() != __b.get(); }
287 
288  template<typename _Tp>
289  inline bool
290  operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
291  { return (bool)__a; }
292 
293  template<typename _Tp>
294  inline bool
295  operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
296  { return (bool)__a; }
297 
298  template<typename _Tp1, typename _Tp2>
299  inline bool
300  operator<(const shared_ptr<_Tp1>& __a,
301  const shared_ptr<_Tp2>& __b) noexcept
302  {
303  using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
304  using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
305  using _CT = common_type_t<__elem_t1*, __elem_t2*>;
306  return std::less<_CT>()(__a.get(), __b.get());
307  }
308 
309  template<typename _Tp>
310  inline bool
311  operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
312  {
313  using __elem_t = typename shared_ptr<_Tp>::element_type;
314  return std::less<__elem_t*>()(__a.get(), nullptr);
315  }
316 
317  template<typename _Tp>
318  inline bool
319  operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
320  {
321  using __elem_t = typename shared_ptr<_Tp>::element_type;
322  return std::less<__elem_t*>()(nullptr, __a.get());
323  }
324 
325  template<typename _Tp1, typename _Tp2>
326  inline bool
327  operator<=(const shared_ptr<_Tp1>& __a,
328  const shared_ptr<_Tp2>& __b) noexcept
329  { return !(__b < __a); }
330 
331  template<typename _Tp>
332  inline bool
333  operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
334  { return !(nullptr < __a); }
335 
336  template<typename _Tp>
337  inline bool
338  operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
339  { return !(__a < nullptr); }
340 
341  template<typename _Tp1, typename _Tp2>
342  inline bool
343  operator>(const shared_ptr<_Tp1>& __a,
344  const shared_ptr<_Tp2>& __b) noexcept
345  { return (__b < __a); }
346 
347  template<typename _Tp>
348  inline bool
349  operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
350  {
351  using __elem_t = typename shared_ptr<_Tp>::element_type;
352  return std::less<__elem_t*>()(nullptr, __a.get());
353  }
354 
355  template<typename _Tp>
356  inline bool
357  operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
358  {
359  using __elem_t = typename shared_ptr<_Tp>::element_type;
360  return std::less<__elem_t*>()(__a.get(), nullptr);
361  }
362 
363  template<typename _Tp1, typename _Tp2>
364  inline bool
365  operator>=(const shared_ptr<_Tp1>& __a,
366  const shared_ptr<_Tp2>& __b) noexcept
367  { return !(__a < __b); }
368 
369  template<typename _Tp>
370  inline bool
371  operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
372  { return !(__a < nullptr); }
373 
374  template<typename _Tp>
375  inline bool
376  operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
377  { return !(nullptr < __a); }
378 
379  // C++14 20.8.2.2.8
380  template<typename _Tp>
381  inline void
382  swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
383  { __a.swap(__b); }
384 
385  // 8.2.1.3, shared_ptr casts
386  template<typename _Tp, typename _Tp1>
387  inline shared_ptr<_Tp>
388  static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
389  {
390  using __elem_t = typename shared_ptr<_Tp>::element_type;
391  return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
392  }
393 
394  template<typename _Tp, typename _Tp1>
395  inline shared_ptr<_Tp>
396  dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
397  {
398  using __elem_t = typename shared_ptr<_Tp>::element_type;
399  if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
400  return shared_ptr<_Tp>(__r, __p);
401  return shared_ptr<_Tp>();
402  }
403 
404  template<typename _Tp, typename _Tp1>
405  inline shared_ptr<_Tp>
406  const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
407  {
408  using __elem_t = typename shared_ptr<_Tp>::element_type;
409  return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
410  }
411 
412  template<typename _Tp, typename _Tp1>
413  inline shared_ptr<_Tp>
414  reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
415  {
416  using __elem_t = typename shared_ptr<_Tp>::element_type;
417  return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
418  }
419 
420  // C++14 20.8.2.3
421  template<typename _Tp>
422  class weak_ptr : public __weak_ptr<_Tp>
423  {
424  template<typename _Tp1, typename _Res = void>
425  using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
426 
427  using _Base_type = __weak_ptr<_Tp>;
428 
429  public:
430  constexpr weak_ptr() noexcept = default;
431 
432  template<typename _Tp1, typename = _Compatible<_Tp1>>
433  weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
434  : _Base_type(__r) { }
435 
436  weak_ptr(const weak_ptr&) noexcept = default;
437 
438  template<typename _Tp1, typename = _Compatible<_Tp1>>
439  weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
440  : _Base_type(__r) { }
441 
442  weak_ptr(weak_ptr&&) noexcept = default;
443 
444  template<typename _Tp1, typename = _Compatible<_Tp1>>
445  weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
446  : _Base_type(std::move(__r)) { }
447 
448  weak_ptr&
449  operator=(const weak_ptr& __r) noexcept = default;
450 
451  template<typename _Tp1>
452  _Compatible<_Tp1, weak_ptr&>
453  operator=(const weak_ptr<_Tp1>& __r) noexcept
454  {
455  this->_Base_type::operator=(__r);
456  return *this;
457  }
458 
459  template<typename _Tp1>
460  _Compatible<_Tp1, weak_ptr&>
461  operator=(const shared_ptr<_Tp1>& __r) noexcept
462  {
463  this->_Base_type::operator=(__r);
464  return *this;
465  }
466 
467  weak_ptr&
468  operator=(weak_ptr&& __r) noexcept = default;
469 
470  template<typename _Tp1>
471  _Compatible<_Tp1, weak_ptr&>
472  operator=(weak_ptr<_Tp1>&& __r) noexcept
473  {
474  this->_Base_type::operator=(std::move(__r));
475  return *this;
476  }
477 
478  shared_ptr<_Tp>
479  lock() const noexcept
480  { return shared_ptr<_Tp>(*this, std::nothrow); }
481 
482  friend class enable_shared_from_this<_Tp>;
483  };
484 
485  // C++14 20.8.2.3.6
486  template<typename _Tp>
487  inline void
488  swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
489  { __a.swap(__b); }
490 
491  /// C++14 20.8.2.2.10
492  template<typename _Del, typename _Tp>
493  inline _Del*
494  get_deleter(const shared_ptr<_Tp>& __p) noexcept
495  { return std::get_deleter<_Del>(__p); }
496 
497  // C++14 20.8.2.2.11
498  template<typename _Ch, typename _Tr, typename _Tp>
500  operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p)
501  {
502  __os << __p.get();
503  return __os;
504  }
505 
506  // C++14 20.8.2.4
507  template<typename _Tp = void> class owner_less;
508 
509  /// Partial specialization of owner_less for shared_ptr.
510  template<typename _Tp>
511  struct owner_less<shared_ptr<_Tp>>
512  : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
513  { };
514 
515  /// Partial specialization of owner_less for weak_ptr.
516  template<typename _Tp>
517  struct owner_less<weak_ptr<_Tp>>
518  : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
519  { };
520 
521  template<>
522  class owner_less<void>
523  {
524  template<typename _Tp, typename _Up>
525  bool
526  operator()(shared_ptr<_Tp> const& __lhs,
527  shared_ptr<_Up> const& __rhs) const
528  { return __lhs.owner_before(__rhs); }
529 
530  template<typename _Tp, typename _Up>
531  bool
532  operator()(shared_ptr<_Tp> const& __lhs,
533  weak_ptr<_Up> const& __rhs) const
534  { return __lhs.owner_before(__rhs); }
535 
536  template<typename _Tp, typename _Up>
537  bool
538  operator()(weak_ptr<_Tp> const& __lhs,
539  shared_ptr<_Up> const& __rhs) const
540  { return __lhs.owner_before(__rhs); }
541 
542  template<typename _Tp, typename _Up>
543  bool
544  operator()(weak_ptr<_Tp> const& __lhs,
545  weak_ptr<_Up> const& __rhs) const
546  { return __lhs.owner_before(__rhs); }
547 
548  typedef void is_transparent;
549  };
550 
551  // C++14 20.8.2.6
552  template<typename _Tp>
553  inline bool
554  atomic_is_lock_free(const shared_ptr<_Tp>* __p)
555  { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
556 
557  template<typename _Tp>
558  shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
559  { return std::atomic_load<_Tp>(__p); }
560 
561  template<typename _Tp>
562  shared_ptr<_Tp>
563  atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
564  { return std::atomic_load_explicit<_Tp>(__p, __mo); }
565 
566  template<typename _Tp>
567  void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
568  { return std::atomic_store<_Tp>(__p, __r); }
569 
570  template<typename _Tp>
571  shared_ptr<_Tp>
572  atomic_store_explicit(const shared_ptr<_Tp>* __p,
573  shared_ptr<_Tp> __r,
574  memory_order __mo)
575  { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
576 
577  template<typename _Tp>
578  void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
579  { return std::atomic_exchange<_Tp>(__p, __r); }
580 
581  template<typename _Tp>
582  shared_ptr<_Tp>
583  atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
584  shared_ptr<_Tp> __r,
585  memory_order __mo)
586  { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
587 
588  template<typename _Tp>
589  bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
590  shared_ptr<_Tp>* __v,
591  shared_ptr<_Tp> __w)
592  { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
593 
594  template<typename _Tp>
595  bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
596  shared_ptr<_Tp>* __v,
597  shared_ptr<_Tp> __w)
598  { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
599 
600  template<typename _Tp>
601  bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
602  shared_ptr<_Tp>* __v,
603  shared_ptr<_Tp> __w,
604  memory_order __success,
605  memory_order __failure)
606  { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
607  __success,
608  __failure); }
609 
610  template<typename _Tp>
611  bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
612  shared_ptr<_Tp>* __v,
613  shared_ptr<_Tp> __w,
614  memory_order __success,
615  memory_order __failure)
616  { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
617  __success,
618  __failure); }
619 
620  //enable_shared_from_this
621  template<typename _Tp>
622  class enable_shared_from_this
623  {
624  protected:
625  constexpr enable_shared_from_this() noexcept { }
626 
627  enable_shared_from_this(const enable_shared_from_this&) noexcept { }
628 
629  enable_shared_from_this&
630  operator=(const enable_shared_from_this&) noexcept
631  { return *this; }
632 
633  ~enable_shared_from_this() { }
634 
635  public:
636  shared_ptr<_Tp>
637  shared_from_this()
638  { return shared_ptr<_Tp>(this->_M_weak_this); }
639 
640  shared_ptr<const _Tp>
641  shared_from_this() const
642  { return shared_ptr<const _Tp>(this->_M_weak_this); }
643 
644  weak_ptr<_Tp>
645  weak_from_this() noexcept
646  { return _M_weak_this; }
647 
648  weak_ptr<const _Tp>
649  weak_from_this() const noexcept
650  { return _M_weak_this; }
651 
652  private:
653  template<typename _Tp1>
654  void
655  _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
656  { _M_weak_this._M_assign(__p, __n); }
657 
658  // Found by ADL when this is an associated class.
659  friend const enable_shared_from_this*
660  __expt_enable_shared_from_this_base(const enable_shared_from_this* __p)
661  { return __p; }
662 
663  template<typename>
664  friend class shared_ptr;
665 
666  mutable weak_ptr<_Tp> _M_weak_this;
667  };
668 } // namespace fundamentals_v2
669 } // namespace experimental
670 
671  /// std::hash specialization for shared_ptr.
672  template<typename _Tp>
673  struct hash<experimental::shared_ptr<_Tp>>
674  : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
675  {
676  size_t
677  operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
678  { return std::hash<_Tp*>()(__s.get()); }
679  };
680 
681 _GLIBCXX_END_NAMESPACE_VERSION
682 } // namespace std
683 
684 #endif // __cplusplus <= 201103L
685 
686 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:873
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:866
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
Definition: type_traits:119
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition: type_traits:2837
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:72
memory_order
Enumeration for memory_order.
Definition: atomic_base.h:66
void lock(_L1 &__l1, _L2 &__l2, _L3 &... __l3)
Generic lock.
Definition: mutex:700
ISO C++ entities toplevel namespace is std.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1692
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
static_pointer_cast
__shared_ptr< _Tp, _Lp > const_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
const_pointer_cast
__shared_ptr< _Tp, _Lp > dynamic_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
dynamic_pointer_cast
constexpr _Iterator __base(_Iterator __it)
Template class basic_ostream.
Definition: ostream.h:67
Primary class template hash.
Partial specializations for pointer types.
A smart pointer with reference-counted copy semantics.
typename __shared_ptr< _Tp >::element_type element_type
The type pointed to by the stored pointer, remove_extent_t<_Tp>
A non-owning observer for a pointer owned by a shared_ptr.
Primary template owner_less.
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:94
One of the comparison functors.
Definition: stl_function.h:401