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-2017 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 
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  template<typename _Tp1, typename = _Compatible<_Tp1>>
143  shared_ptr(std::auto_ptr<_Tp1>&& __r)
144  : _Base_type(std::move(__r))
145  { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); }
146 #endif
147 
148  template<typename _Tp1, typename _Del,
149  typename = _UniqCompatible<_Tp1, _Del>>
150  shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
151  : _Base_type(std::move(__r))
152  {
153  // XXX assume conversion from __r.get() to this->get() to __elem_t*
154  // is a round trip, which might not be true in all cases.
155  using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type;
156  _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get()));
157  }
158 
159  constexpr shared_ptr(nullptr_t __p)
160  : _Base_type(__p) { }
161 
162  // C++14 §20.8.2.2
163  ~shared_ptr() = default;
164 
165  // C++14 §20.8.2.3
166  shared_ptr& operator=(const shared_ptr&) noexcept = default;
167 
168  template <typename _Tp1>
169  _Compatible<_Tp1, shared_ptr&>
170  operator=(const shared_ptr<_Tp1>& __r) noexcept
171  {
172  _Base_type::operator=(__r);
173  return *this;
174  }
175 
176  shared_ptr&
177  operator=(shared_ptr&& __r) noexcept
178  {
179  _Base_type::operator=(std::move(__r));
180  return *this;
181  }
182 
183  template <typename _Tp1>
184  _Compatible<_Tp1, shared_ptr&>
185  operator=(shared_ptr<_Tp1>&& __r) noexcept
186  {
187  _Base_type::operator=(std::move(__r));
188  return *this;
189  }
190 
191 #if _GLIBCXX_USE_DEPRECATED
192  template<typename _Tp1>
193  _Compatible<_Tp1, shared_ptr&>
194  operator=(std::auto_ptr<_Tp1>&& __r)
195  {
196  __shared_ptr<_Tp>::operator=(std::move(__r));
197  return *this;
198  }
199 #endif
200 
201  template <typename _Tp1, typename _Del>
202  _UniqCompatible<_Tp1, _Del, shared_ptr&>
203  operator=(unique_ptr<_Tp1, _Del>&& __r)
204  {
205  _Base_type::operator=(std::move(__r));
206  return *this;
207  }
208 
209  // C++14 §20.8.2.2.4
210  // swap & reset
211  // 8.2.1.2 shared_ptr observers
212  // in __shared_ptr
213 
214  private:
215  template<typename _Alloc, typename... _Args>
216  shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
217  _Args&&... __args)
218  : _Base_type(__tag, __a, std::forward<_Args>(__args)...)
219  { _M_enable_shared_from_this_with(this->get()); }
220 
221  template<typename _Tp1, typename _Alloc, typename... _Args>
222  friend shared_ptr<_Tp1>
223  allocate_shared(const _Alloc& __a, _Args&&... __args);
224 
225  shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
226  : _Base_type(__r, std::nothrow) { }
227 
228  friend class weak_ptr<_Tp>;
229 
230  template<typename _Yp>
231  using __esft_base_t =
232  decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
233 
234  // Detect an accessible and unambiguous enable_shared_from_this base.
235  template<typename _Yp, typename = void>
236  struct __has_esft_base
237  : false_type { };
238 
239  template<typename _Yp>
240  struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
241  : __bool_constant<!is_array_v<_Tp>> { }; // ignore base for arrays
242 
243  template<typename _Yp>
244  typename enable_if<__has_esft_base<_Yp>::value>::type
245  _M_enable_shared_from_this_with(const _Yp* __p) noexcept
246  {
247  if (auto __base = __expt_enable_shared_from_this_base(__p))
248  {
249  __base->_M_weak_this
250  = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p));
251  }
252  }
253 
254  template<typename _Yp>
255  typename enable_if<!__has_esft_base<_Yp>::value>::type
256  _M_enable_shared_from_this_with(const _Yp*) noexcept
257  { }
258  };
259 
260  // C++14 §20.8.2.2.7 //DOING
261  template<typename _Tp1, typename _Tp2>
262  bool operator==(const shared_ptr<_Tp1>& __a,
263  const shared_ptr<_Tp2>& __b) noexcept
264  { return __a.get() == __b.get(); }
265 
266  template<typename _Tp>
267  inline bool
268  operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
269  { return !__a; }
270 
271  template<typename _Tp>
272  inline bool
273  operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
274  { return !__a; }
275 
276  template<typename _Tp1, typename _Tp2>
277  inline bool
278  operator!=(const shared_ptr<_Tp1>& __a,
279  const shared_ptr<_Tp2>& __b) noexcept
280  { return __a.get() != __b.get(); }
281 
282  template<typename _Tp>
283  inline bool
284  operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
285  { return (bool)__a; }
286 
287  template<typename _Tp>
288  inline bool
289  operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
290  { return (bool)__a; }
291 
292  template<typename _Tp1, typename _Tp2>
293  inline bool
294  operator<(const shared_ptr<_Tp1>& __a,
295  const shared_ptr<_Tp2>& __b) noexcept
296  {
297  using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
298  using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
299  using _CT = common_type_t<__elem_t1*, __elem_t2*>;
300  return std::less<_CT>()(__a.get(), __b.get());
301  }
302 
303  template<typename _Tp>
304  inline bool
305  operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
306  {
307  using __elem_t = typename shared_ptr<_Tp>::element_type;
308  return std::less<__elem_t*>()(__a.get(), nullptr);
309  }
310 
311  template<typename _Tp>
312  inline bool
313  operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
314  {
315  using __elem_t = typename shared_ptr<_Tp>::element_type;
316  return std::less<__elem_t*>()(nullptr, __a.get());
317  }
318 
319  template<typename _Tp1, typename _Tp2>
320  inline bool
321  operator<=(const shared_ptr<_Tp1>& __a,
322  const shared_ptr<_Tp2>& __b) noexcept
323  { return !(__b < __a); }
324 
325  template<typename _Tp>
326  inline bool
327  operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
328  { return !(nullptr < __a); }
329 
330  template<typename _Tp>
331  inline bool
332  operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
333  { return !(__a < nullptr); }
334 
335  template<typename _Tp1, typename _Tp2>
336  inline bool
337  operator>(const shared_ptr<_Tp1>& __a,
338  const shared_ptr<_Tp2>& __b) noexcept
339  { return (__b < __a); }
340 
341  template<typename _Tp>
342  inline bool
343  operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
344  {
345  using __elem_t = typename shared_ptr<_Tp>::element_type;
346  return std::less<__elem_t*>()(nullptr, __a.get());
347  }
348 
349  template<typename _Tp>
350  inline bool
351  operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
352  {
353  using __elem_t = typename shared_ptr<_Tp>::element_type;
354  return std::less<__elem_t*>()(__a.get(), nullptr);
355  }
356 
357  template<typename _Tp1, typename _Tp2>
358  inline bool
359  operator>=(const shared_ptr<_Tp1>& __a,
360  const shared_ptr<_Tp2>& __b) noexcept
361  { return !(__a < __b); }
362 
363  template<typename _Tp>
364  inline bool
365  operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
366  { return !(__a < nullptr); }
367 
368  template<typename _Tp>
369  inline bool
370  operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
371  { return !(nullptr < __a); }
372 
373  // C++14 §20.8.2.2.8
374  template<typename _Tp>
375  inline void
376  swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
377  { __a.swap(__b); }
378 
379  // 8.2.1.3, shared_ptr casts
380  template<typename _Tp, typename _Tp1>
381  inline shared_ptr<_Tp>
382  static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
383  {
384  using __elem_t = typename shared_ptr<_Tp>::element_type;
385  return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
386  }
387 
388  template<typename _Tp, typename _Tp1>
389  inline shared_ptr<_Tp>
390  dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
391  {
392  using __elem_t = typename shared_ptr<_Tp>::element_type;
393  if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
394  return shared_ptr<_Tp>(__r, __p);
395  return shared_ptr<_Tp>();
396  }
397 
398  template<typename _Tp, typename _Tp1>
399  inline shared_ptr<_Tp>
400  const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
401  {
402  using __elem_t = typename shared_ptr<_Tp>::element_type;
403  return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
404  }
405 
406  template<typename _Tp, typename _Tp1>
407  inline shared_ptr<_Tp>
408  reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
409  {
410  using __elem_t = typename shared_ptr<_Tp>::element_type;
411  return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
412  }
413 
414  // C++14 §20.8.2.3
415  template<typename _Tp>
416  class weak_ptr : public __weak_ptr<_Tp>
417  {
418  template<typename _Tp1, typename _Res = void>
419  using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
420 
421  using _Base_type = __weak_ptr<_Tp>;
422 
423  public:
424  constexpr weak_ptr() noexcept = default;
425 
426  template<typename _Tp1, typename = _Compatible<_Tp1>>
427  weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
428  : _Base_type(__r) { }
429 
430  weak_ptr(const weak_ptr&) noexcept = default;
431 
432  template<typename _Tp1, typename = _Compatible<_Tp1>>
433  weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
434  : _Base_type(__r) { }
435 
436  weak_ptr(weak_ptr&&) noexcept = default;
437 
438  template<typename _Tp1, typename = _Compatible<_Tp1>>
439  weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
440  : _Base_type(std::move(__r)) { }
441 
442  weak_ptr&
443  operator=(const weak_ptr& __r) noexcept = default;
444 
445  template<typename _Tp1>
446  _Compatible<_Tp1, weak_ptr&>
447  operator=(const weak_ptr<_Tp1>& __r) noexcept
448  {
449  this->_Base_type::operator=(__r);
450  return *this;
451  }
452 
453  template<typename _Tp1>
454  _Compatible<_Tp1, weak_ptr&>
455  operator=(const shared_ptr<_Tp1>& __r) noexcept
456  {
457  this->_Base_type::operator=(__r);
458  return *this;
459  }
460 
461  weak_ptr&
462  operator=(weak_ptr&& __r) noexcept = default;
463 
464  template<typename _Tp1>
465  _Compatible<_Tp1, weak_ptr&>
466  operator=(weak_ptr<_Tp1>&& __r) noexcept
467  {
468  this->_Base_type::operator=(std::move(__r));
469  return *this;
470  }
471 
472  shared_ptr<_Tp>
473  lock() const noexcept
474  { return shared_ptr<_Tp>(*this, std::nothrow); }
475 
476  friend class enable_shared_from_this<_Tp>;
477  };
478 
479  // C++14 §20.8.2.3.6
480  template<typename _Tp>
481  inline void
482  swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
483  { __a.swap(__b); }
484 
485  /// C++14 §20.8.2.2.10
486  template<typename _Del, typename _Tp>
487  inline _Del*
488  get_deleter(const shared_ptr<_Tp>& __p) noexcept
489  { return std::get_deleter<_Del>(__p); }
490 
491  // C++14 §20.8.2.2.11
492  template<typename _Ch, typename _Tr, typename _Tp>
494  operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p)
495  {
496  __os << __p.get();
497  return __os;
498  }
499 
500  // C++14 §20.8.2.4
501  template<typename _Tp = void> class owner_less;
502 
503  /// Partial specialization of owner_less for shared_ptr.
504  template<typename _Tp>
505  struct owner_less<shared_ptr<_Tp>>
506  : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
507  { };
508 
509  /// Partial specialization of owner_less for weak_ptr.
510  template<typename _Tp>
511  struct owner_less<weak_ptr<_Tp>>
512  : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
513  { };
514 
515  template<>
516  class owner_less<void>
517  {
518  template<typename _Tp, typename _Up>
519  bool
520  operator()(shared_ptr<_Tp> const& __lhs,
521  shared_ptr<_Up> const& __rhs) const
522  { return __lhs.owner_before(__rhs); }
523 
524  template<typename _Tp, typename _Up>
525  bool
526  operator()(shared_ptr<_Tp> const& __lhs,
527  weak_ptr<_Up> const& __rhs) const
528  { return __lhs.owner_before(__rhs); }
529 
530  template<typename _Tp, typename _Up>
531  bool
532  operator()(weak_ptr<_Tp> const& __lhs,
533  shared_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  weak_ptr<_Up> const& __rhs) const
540  { return __lhs.owner_before(__rhs); }
541 
542  typedef void is_transparent;
543  };
544 
545  // C++14 §20.8.2.6
546  template<typename _Tp>
547  inline bool
548  atomic_is_lock_free(const shared_ptr<_Tp>* __p)
549  { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
550 
551  template<typename _Tp>
552  shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
553  { return std::atomic_load<_Tp>(__p); }
554 
555  template<typename _Tp>
556  shared_ptr<_Tp>
557  atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
558  { return std::atomic_load_explicit<_Tp>(__p, __mo); }
559 
560  template<typename _Tp>
561  void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
562  { return std::atomic_store<_Tp>(__p, __r); }
563 
564  template<typename _Tp>
565  shared_ptr<_Tp>
566  atomic_store_explicit(const shared_ptr<_Tp>* __p,
567  shared_ptr<_Tp> __r,
568  memory_order __mo)
569  { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
570 
571  template<typename _Tp>
572  void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
573  { return std::atomic_exchange<_Tp>(__p, __r); }
574 
575  template<typename _Tp>
576  shared_ptr<_Tp>
577  atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
578  shared_ptr<_Tp> __r,
579  memory_order __mo)
580  { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
581 
582  template<typename _Tp>
583  bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
584  shared_ptr<_Tp>* __v,
585  shared_ptr<_Tp> __w)
586  { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
587 
588  template<typename _Tp>
589  bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
590  shared_ptr<_Tp>* __v,
591  shared_ptr<_Tp> __w)
592  { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
593 
594  template<typename _Tp>
595  bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
596  shared_ptr<_Tp>* __v,
597  shared_ptr<_Tp> __w,
598  memory_order __success,
599  memory_order __failure)
600  { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
601  __success,
602  __failure); }
603 
604  template<typename _Tp>
605  bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
606  shared_ptr<_Tp>* __v,
607  shared_ptr<_Tp> __w,
608  memory_order __success,
609  memory_order __failure)
610  { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
611  __success,
612  __failure); }
613 
614  //enable_shared_from_this
615  template<typename _Tp>
616  class enable_shared_from_this
617  {
618  protected:
619  constexpr enable_shared_from_this() noexcept { }
620 
621  enable_shared_from_this(const enable_shared_from_this&) noexcept { }
622 
623  enable_shared_from_this&
624  operator=(const enable_shared_from_this&) noexcept
625  { return *this; }
626 
627  ~enable_shared_from_this() { }
628 
629  public:
630  shared_ptr<_Tp>
631  shared_from_this()
632  { return shared_ptr<_Tp>(this->_M_weak_this); }
633 
634  shared_ptr<const _Tp>
635  shared_from_this() const
636  { return shared_ptr<const _Tp>(this->_M_weak_this); }
637 
638  weak_ptr<_Tp>
639  weak_from_this() noexcept
640  { return _M_weak_this; }
641 
642  weak_ptr<const _Tp>
643  weak_from_this() const noexcept
644  { return _M_weak_this; }
645 
646  private:
647  template<typename _Tp1>
648  void
649  _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
650  { _M_weak_this._M_assign(__p, __n); }
651 
652  // Found by ADL when this is an associated class.
653  friend const enable_shared_from_this*
654  __expt_enable_shared_from_this_base(const enable_shared_from_this* __p)
655  { return __p; }
656 
657  template<typename>
658  friend class shared_ptr;
659 
660  mutable weak_ptr<_Tp> _M_weak_this;
661  };
662 
663 _GLIBCXX_END_NAMESPACE_VERSION
664 } // namespace fundamentals_v2
665 } // namespace experimental
666 
667 _GLIBCXX_BEGIN_NAMESPACE_VERSION
668 
669  /// std::hash specialization for shared_ptr.
670  template<typename _Tp>
671  struct hash<experimental::shared_ptr<_Tp>>
672  : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
673  {
674  size_t
675  operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
676  { return std::hash<_Tp*>()(__s.get()); }
677  };
678 
679 _GLIBCXX_END_NAMESPACE_VERSION
680 } // namespace std
681 
682 #endif // __cplusplus <= 201103L
683 
684 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
ISO C++ entities toplevel namespace is std.
Template class basic_ostream.
Definition: iosfwd:86
void lock(_L1 &__l1, _L2 &__l2, _L3 &... __l3)
Generic lock.
Definition: mutex:542
Partial specializations for pointer types.
One of the comparison functors.
Definition: stl_function.h:340
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&... __args)
Create an object that is owned by a shared_ptr.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
Definition: type_traits:90
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:73
Primary class template hash.
Definition: system_error:142
memory_order
Enumeration for memory_order.
Definition: atomic_base.h:55
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:87
_Del * get_deleter(const __shared_ptr< _Tp, _Lp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter