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-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  // __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
263  // }
264 
265  // __weak_ptr::lock()
266  __shared_ptr(const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r,
267  std::nothrow_t)
268  : _Base_type(__r._M_get_base(), std::nothrow)
269  { }
270 
271  private:
272  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
273  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
274 
275  // TODO
276  template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
277  friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
278  };
279 
280  // Helper traits for shared_ptr of array:
281 
282  // Trait that tests if Y* is compatible with T*, for shared_ptr purposes.
283  template<typename _Yp, typename _Tp>
284  struct __sp_compatible
285  : is_convertible<_Yp*, _Tp*>::type
286  { };
287 
288  template<size_t _Nm, typename _Tp>
289  struct __sp_compatible<_Tp[_Nm], _Tp[]>
290  : true_type
291  { };
292 
293  template<size_t _Nm, typename _Tp>
294  struct __sp_compatible<_Tp[_Nm], const _Tp[]>
295  : true_type
296  { };
297 
298  template<typename _Yp, typename _Tp>
299  constexpr bool __sp_compatible_v
300  = __sp_compatible<_Yp, _Tp>::value;
301 
302  // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
303  template<typename _Up, size_t _Nm, typename _Yp, typename = void>
304  struct __sp_is_constructible_arrN
305  : false_type
306  { };
307 
308  template<typename _Up, size_t _Nm, typename _Yp>
309  struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
310  : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
311  { };
312 
313  // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
314  template<typename _Up, typename _Yp, typename = void>
315  struct __sp_is_constructible_arr
316  : false_type
317  { };
318 
319  template<typename _Up, typename _Yp>
320  struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
321  : is_convertible<_Yp(*)[], _Up(*)[]>::type
322  { };
323 
324  // Trait to check if shared_ptr<T> can be constructed from Y*.
325  template<typename _Tp, typename _Yp>
326  struct __sp_is_constructible;
327 
328  // When T is U[N], Y(*)[N] shall be convertible to T*;
329  template<typename _Up, size_t _Nm, typename _Yp>
330  struct __sp_is_constructible<_Up[_Nm], _Yp>
331  : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
332  { };
333 
334  // when T is U[], Y(*)[] shall be convertible to T*;
335  template<typename _Up, typename _Yp>
336  struct __sp_is_constructible<_Up[], _Yp>
337  : __sp_is_constructible_arr<_Up, _Yp>::type
338  { };
339 
340  // otherwise, Y* shall be convertible to T*.
341  template<typename _Tp, typename _Yp>
342  struct __sp_is_constructible
343  : is_convertible<_Yp*, _Tp*>::type
344  { };
345 
346  template<typename _Tp, typename _Yp>
347  constexpr bool __sp_is_constructible_v
348  = __sp_is_constructible<_Tp, _Yp>::value;
349 
350 
351  // Partial specialization for base class of experimental::shared_ptr<T[N]>
352  // and experimental::shared_ptr<T[]> (i.e. the array forms).
353  template<typename _Tp, _Lock_policy _Lp>
354  class __shared_ptr<__libfund_v1<_Tp, true>, _Lp>
355  : private __shared_ptr<remove_extent_t<_Tp>, _Lp>
356  {
357  public:
358  using element_type = remove_extent_t<_Tp>;
359 
360  private:
361  struct _Array_deleter
362  {
363  void
364  operator()(element_type const *__p) const
365  { delete [] __p; }
366  };
367 
368  // Constraint for constructing/resetting with a pointer of type _Yp*:
369  template<typename _Yp>
370  using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
371 
372  // Constraint for constructing/assigning from smart_pointer<_Tp1>:
373  template<typename _Tp1, typename _Res = void>
374  using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
375 
376  // Constraint for constructing/assigning from unique_ptr<_Tp1, _Del>:
377  template<typename _Tp1, typename _Del,
378  typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
379  typename _Res = void>
380  using _UniqCompatible = enable_if_t<
381  __sp_compatible_v<_Tp1, _Tp>
382  && experimental::is_convertible_v<_Ptr, element_type*>,
383  _Res>;
384 
385  using _Base_type = __shared_ptr<element_type>;
386 
387  _Base_type& _M_get_base() { return *this; }
388  const _Base_type& _M_get_base() const { return *this; }
389 
390  public:
391  constexpr __shared_ptr() noexcept
392  : _Base_type()
393  { }
394 
395  template<typename _Tp1, typename = _SafeConv<_Tp1>>
396  explicit
397  __shared_ptr(_Tp1* __p)
398  : _Base_type(__p, _Array_deleter())
399  { }
400 
401  template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
402  __shared_ptr(_Tp1* __p, _Deleter __d)
403  : _Base_type(__p, __d)
404  { }
405 
406  template<typename _Tp1, typename _Deleter, typename _Alloc,
407  typename = _SafeConv<_Tp1>>
408  __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
409  : _Base_type(__p, __d, __a)
410  { }
411 
412  template<typename _Deleter>
413  __shared_ptr(nullptr_t __p, _Deleter __d)
414  : _Base_type(__p, __d)
415  { }
416 
417  template<typename _Deleter, typename _Alloc>
418  __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
419  : _Base_type(__p, __d, __a)
420  { }
421 
422  template<typename _Tp1>
423  __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r,
424  element_type* __p) noexcept
425  : _Base_type(__r._M_get_base(), __p)
426  { }
427 
428  __shared_ptr(const __shared_ptr&) noexcept = default;
429  __shared_ptr(__shared_ptr&&) noexcept = default;
430  __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
431  __shared_ptr& operator=(__shared_ptr&&) noexcept = default;
432  ~__shared_ptr() = default;
433 
434  template<typename _Tp1, typename = _Compatible<_Tp1>>
435  __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
436  : _Base_type(__r._M_get_base())
437  { }
438 
439  template<typename _Tp1, typename = _Compatible<_Tp1>>
440  __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
441  : _Base_type(std::move((__r._M_get_base())))
442  { }
443 
444  template<typename _Tp1, typename = _Compatible<_Tp1>>
445  explicit
446  __shared_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r)
447  : _Base_type(__r._M_get_base())
448  { }
449 
450  template<typename _Tp1, typename _Del,
451  typename = _UniqCompatible<_Tp1, _Del>>
452  __shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
453  : _Base_type(std::move(__r))
454  { }
455 
456 #if _GLIBCXX_USE_DEPRECATED
457  // Postcondition: use_count() == 1 and __r.get() == 0
458  template<typename _Tp1, typename = _Compatible<_Tp1>>
459  __shared_ptr(auto_ptr<_Tp1>&& __r)
460  : _Base_type(std::move(__r))
461  { }
462 #endif
463 
464  constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
465 
466  // reset
467  void
468  reset() noexcept
469  { __shared_ptr(nullptr).swap(*this); }
470 
471  template<typename _Tp1>
472  _SafeConv<_Tp1>
473  reset(_Tp1* __p)
474  {
475  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != get());
476  __shared_ptr(__p, _Array_deleter()).swap(*this);
477  }
478 
479  template<typename _Tp1, typename _Deleter>
480  _SafeConv<_Tp1>
481  reset(_Tp1* __p, _Deleter __d)
482  { __shared_ptr(__p, __d).swap(*this); }
483 
484  template<typename _Tp1, typename _Deleter, typename _Alloc>
485  _SafeConv<_Tp1>
486  reset(_Tp1* __p, _Deleter __d, _Alloc __a)
487  { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
488 
489  element_type&
490  operator[](ptrdiff_t i) const noexcept
491  {
492  _GLIBCXX_DEBUG_ASSERT(get() != 0 && i >= 0);
493  return get()[i];
494  }
495 
496  template<typename _Tp1>
497  _Compatible<_Tp1, __shared_ptr&>
498  operator=(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
499  {
500  _Base_type::operator=(__r._M_get_base());
501  return *this;
502  }
503 
504  template<class _Tp1>
505  _Compatible<_Tp1, __shared_ptr&>
506  operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
507  {
508  _Base_type::operator=(std::move(__r._M_get_base()));
509  return *this;
510  }
511 
512  template<typename _Tp1, typename _Del>
513  _UniqCompatible<_Tp1, _Del, __shared_ptr&>
514  operator=(unique_ptr<_Tp1, _Del>&& __r)
515  {
516  _Base_type::operator=(std::move(__r));
517  return *this;
518  }
519 
520 #if _GLIBCXX_USE_DEPRECATED
521  template<typename _Tp1>
522  _Compatible<_Tp1, __shared_ptr&>
523  operator=(auto_ptr<_Tp1>&& __r)
524  {
525  _Base_type::operator=(std::move(__r));
526  return *this;
527  }
528 #endif
529 
530  void
531  swap(__shared_ptr& __other) noexcept
532  { _Base_type::swap(__other); }
533 
534  template<typename _Tp1>
535  bool
536  owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const
537  { return _Base_type::owner_before(__rhs._M_get_base()); }
538 
539  template<typename _Tp1>
540  bool
541  owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const
542  { return _Base_type::owner_before(__rhs._M_get_base()); }
543 
544  using _Base_type::operator bool;
545  using _Base_type::get;
546  using _Base_type::unique;
547  using _Base_type::use_count;
548 
549  protected:
550 
551  // make_shared not yet support for shared_ptr_arrays
552  //template<typename _Alloc, typename... _Args>
553  // __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
554  // _Args&&... __args)
555  // : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
556  // std::forward<_Args>(__args)...)
557  // {
558  // void* __p = _M_refcount._M_get_deleter(typeid(__tag));
559  // _M_ptr = static_cast<_Tp*>(__p);
560  // __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
561  // }
562 
563  // __weak_ptr::lock()
564  __shared_ptr(const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r,
565  std::nothrow_t)
566  : _Base_type(__r._M_get_base(), std::nothrow)
567  { }
568 
569  private:
570  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
571  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
572 
573  // TODO
574  template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
575  friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
576  };
577 
578  // weak_ptr specialization for __shared_ptr array
579  template<typename _Tp, _Lock_policy _Lp>
580  class __weak_ptr<__libfund_v1<_Tp>, _Lp>
581  : __weak_ptr<remove_extent_t<_Tp>, _Lp>
582  {
583  template<typename _Tp1, typename _Res = void>
584  using _Compatible
585  = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
586 
587  using _Base_type = __weak_ptr<remove_extent_t<_Tp>>;
588 
589  _Base_type& _M_get_base() { return *this; }
590  const _Base_type& _M_get_base() const { return *this; }
591 
592  public:
593  using element_type = remove_extent_t<_Tp>;
594 
595  constexpr __weak_ptr() noexcept
596  : _Base_type()
597  { }
598 
599  __weak_ptr(const __weak_ptr&) noexcept = default;
600 
601  ~__weak_ptr() = default;
602 
603  template<typename _Tp1, typename = _Compatible<_Tp1>>
604  __weak_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
605  : _Base_type(__r._M_get_base())
606  { }
607 
608  template<typename _Tp1, typename = _Compatible<_Tp1>>
609  __weak_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
610  : _Base_type(__r._M_get_base())
611  { }
612 
613  __weak_ptr(__weak_ptr&& __r) noexcept
614  : _Base_type(std::move(__r))
615  { }
616 
617  template<typename _Tp1, typename = _Compatible<_Tp1>>
618  __weak_ptr(__weak_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
619  : _Base_type(std::move(__r._M_get_base()))
620  { }
621 
622  __weak_ptr&
623  operator=(const __weak_ptr& __r) noexcept = default;
624 
625  template<typename _Tp1>
626  _Compatible<_Tp1, __weak_ptr&>
627  operator=(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
628  {
629  this->_Base_type::operator=(__r._M_get_base());
630  return *this;
631  }
632 
633  template<typename _Tp1>
634  _Compatible<_Tp1, __weak_ptr&>
635  operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
636  {
637  this->_Base_type::operator=(__r._M_get_base());
638  return *this;
639  }
640 
641  __weak_ptr&
642  operator=(__weak_ptr&& __r) noexcept
643  {
644  this->_Base_type::operator=(std::move(__r));
645  return *this;
646  }
647 
648  template<typename _Tp1>
649  _Compatible<_Tp1, __weak_ptr&>
650  operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
651  {
652  this->_Base_type::operator=(std::move(__r._M_get_base()));
653  return *this;
654  }
655 
656  void
657  swap(__weak_ptr& __other) noexcept
658  { this->_Base_type::swap(__other); }
659 
660  template<typename _Tp1>
661  bool
662  owner_before(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs) const
663  { return _Base_type::owner_before(__rhs._M_get_base()); }
664 
665  template<typename _Tp1>
666  bool
667  owner_before(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs) const
668  { return _Base_type::owner_before(__rhs._M_get_base()); }
669 
670  __shared_ptr<__libfund_v1<_Tp>, _Lp>
671  lock() const noexcept // should not be element_type
672  { return __shared_ptr<__libfund_v1<_Tp>, _Lp>(*this, std::nothrow); }
673 
674  using _Base_type::use_count;
675  using _Base_type::expired;
676  using _Base_type::reset;
677 
678  private:
679  // Used by __enable_shared_from_this.
680  void
681  _M_assign(element_type* __ptr,
682  const __shared_count<_Lp>& __refcount) noexcept
683  { this->_Base_type::_M_assign(__ptr, __refcount); }
684 
685  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
686  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
687  friend class __enable_shared_from_this<_Tp, _Lp>;
688  friend class experimental::enable_shared_from_this<_Tp>;
689  friend class enable_shared_from_this<_Tp>;
690  };
691 
692 _GLIBCXX_END_NAMESPACE_VERSION
693 
694 namespace experimental
695 {
696 inline namespace fundamentals_v2
697 {
698 _GLIBCXX_BEGIN_NAMESPACE_VERSION
699 
700  // 8.2.1
701 
702  template<typename _Tp> class shared_ptr;
703  template<typename _Tp> class weak_ptr;
704 
705  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
706  using __shared_ptr = std::__shared_ptr<__libfund_v1<_Tp>, _Lp>;
707 
708  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
709  using __weak_ptr = std::__weak_ptr<__libfund_v1<_Tp>, _Lp>;
710 
711  template<typename _Tp>
712  class shared_ptr : public __shared_ptr<_Tp>
713  {
714  using _Base_type = __shared_ptr<_Tp>;
715 
716  public:
717  using element_type = typename _Base_type::element_type;
718 
719  private:
720  // Constraint for construction from a pointer of type _Yp*:
721  template<typename _Yp>
722  using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
723 
724  template<typename _Tp1, typename _Res = void>
725  using _Compatible
726  = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
727 
728  template<typename _Tp1, typename _Del,
729  typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
730  typename _Res = void>
731  using _UniqCompatible = enable_if_t<
732  __sp_compatible_v<_Tp1, _Tp>
733  && experimental::is_convertible_v<_Ptr, element_type*>,
734  _Res>;
735 
736  public:
737 
738  // 8.2.1.1, shared_ptr constructors
739  constexpr shared_ptr() noexcept = default;
740 
741  template<typename _Tp1, typename = _SafeConv<_Tp1>>
742  explicit
743  shared_ptr(_Tp1* __p) : _Base_type(__p) { }
744 
745  template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
746  shared_ptr(_Tp1* __p, _Deleter __d)
747  : _Base_type(__p, __d) { }
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 
754  template<typename _Deleter>
755  shared_ptr(nullptr_t __p, _Deleter __d)
756  : _Base_type(__p, __d) { }
757 
758  template<typename _Deleter, typename _Alloc>
759  shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
760  : _Base_type(__p, __d, __a) { }
761 
762  template<typename _Tp1>
763  shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
764  : _Base_type(__r, __p) { }
765 
766  shared_ptr(const shared_ptr& __r) noexcept
767  : _Base_type(__r) { }
768 
769  template<typename _Tp1, typename = _Compatible<_Tp1>>
770  shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
771  : _Base_type(__r) { }
772 
773  shared_ptr(shared_ptr&& __r) noexcept
774  : _Base_type(std::move(__r)) { }
775 
776  template<typename _Tp1, typename = _Compatible<_Tp1>>
777  shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
778  : _Base_type(std::move(__r)) { }
779 
780  template<typename _Tp1, typename = _Compatible<_Tp1>>
781  explicit
782  shared_ptr(const weak_ptr<_Tp1>& __r)
783  : _Base_type(__r) { }
784 
785 #if _GLIBCXX_USE_DEPRECATED
786  template<typename _Tp1, typename = _Compatible<_Tp1>>
787  shared_ptr(std::auto_ptr<_Tp1>&& __r)
788  : _Base_type(std::move(__r)) { }
789 #endif
790 
791  template<typename _Tp1, typename _Del,
792  typename = _UniqCompatible<_Tp1, _Del>>
793  shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
794  : _Base_type(std::move(__r)) { }
795 
796  constexpr shared_ptr(nullptr_t __p)
797  : _Base_type(__p) { }
798 
799  // C++14 §20.8.2.2
800  ~shared_ptr() = default;
801 
802  // C++14 §20.8.2.3
803  shared_ptr& operator=(const shared_ptr&) noexcept = default;
804 
805  template <typename _Tp1>
806  _Compatible<_Tp1, shared_ptr&>
807  operator=(const shared_ptr<_Tp1>& __r) noexcept
808  {
809  _Base_type::operator=(__r);
810  return *this;
811  }
812 
813  shared_ptr&
814  operator=(shared_ptr&& __r) noexcept
815  {
816  _Base_type::operator=(std::move(__r));
817  return *this;
818  }
819 
820  template <typename _Tp1>
821  _Compatible<_Tp1, shared_ptr&>
822  operator=(shared_ptr<_Tp1>&& __r) noexcept
823  {
824  _Base_type::operator=(std::move(__r));
825  return *this;
826  }
827 
828 #if _GLIBCXX_USE_DEPRECATED
829  template<typename _Tp1>
830  _Compatible<_Tp1, shared_ptr&>
831  operator=(std::auto_ptr<_Tp1>&& __r)
832  {
833  __shared_ptr<_Tp>::operator=(std::move(__r));
834  return *this;
835  }
836 #endif
837 
838  template <typename _Tp1, typename _Del>
839  _UniqCompatible<_Tp1, _Del, shared_ptr&>
840  operator=(unique_ptr<_Tp1, _Del>&& __r)
841  {
842  _Base_type::operator=(std::move(__r));
843  return *this;
844  }
845 
846  // C++14 §20.8.2.2.4
847  // swap & reset
848  // 8.2.1.2 shared_ptr observers
849  // in __shared_ptr
850 
851  private:
852  template<typename _Alloc, typename... _Args>
853  shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
854  _Args&&... __args)
855  : _Base_type(__tag, __a, std::forward<_Args>(__args)...)
856  { }
857 
858  template<typename _Tp1, typename _Alloc, typename... _Args>
859  friend shared_ptr<_Tp1>
860  allocate_shared(const _Alloc& __a, _Args&&... __args);
861 
862  shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
863  : _Base_type(__r, std::nothrow) { }
864 
865  friend class weak_ptr<_Tp>;
866  };
867 
868  // C++14 §20.8.2.2.7 //DOING
869  template<typename _Tp1, typename _Tp2>
870  bool operator==(const shared_ptr<_Tp1>& __a,
871  const shared_ptr<_Tp2>& __b) noexcept
872  { return __a.get() == __b.get(); }
873 
874  template<typename _Tp>
875  inline bool
876  operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
877  { return !__a; }
878 
879  template<typename _Tp>
880  inline bool
881  operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
882  { return !__a; }
883 
884  template<typename _Tp1, typename _Tp2>
885  inline bool
886  operator!=(const shared_ptr<_Tp1>& __a,
887  const shared_ptr<_Tp2>& __b) noexcept
888  { return __a.get() != __b.get(); }
889 
890  template<typename _Tp>
891  inline bool
892  operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
893  { return (bool)__a; }
894 
895  template<typename _Tp>
896  inline bool
897  operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
898  { return (bool)__a; }
899 
900  template<typename _Tp1, typename _Tp2>
901  inline bool
902  operator<(const shared_ptr<_Tp1>& __a,
903  const shared_ptr<_Tp2>& __b) noexcept
904  {
905  using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
906  using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
907  using _CT = common_type_t<__elem_t1*, __elem_t2*>;
908  return std::less<_CT>()(__a.get(), __b.get());
909  }
910 
911  template<typename _Tp>
912  inline bool
913  operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
914  {
915  using __elem_t = typename shared_ptr<_Tp>::element_type;
916  return std::less<__elem_t*>()(__a.get(), nullptr);
917  }
918 
919  template<typename _Tp>
920  inline bool
921  operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
922  {
923  using __elem_t = typename shared_ptr<_Tp>::element_type;
924  return std::less<__elem_t*>()(nullptr, __a.get());
925  }
926 
927  template<typename _Tp1, typename _Tp2>
928  inline bool
929  operator<=(const shared_ptr<_Tp1>& __a,
930  const shared_ptr<_Tp2>& __b) noexcept
931  { return !(__b < __a); }
932 
933  template<typename _Tp>
934  inline bool
935  operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
936  { return !(nullptr < __a); }
937 
938  template<typename _Tp>
939  inline bool
940  operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
941  { return !(__a < nullptr); }
942 
943  template<typename _Tp1, typename _Tp2>
944  inline bool
945  operator>(const shared_ptr<_Tp1>& __a,
946  const shared_ptr<_Tp2>& __b) noexcept
947  { return (__b < __a); }
948 
949  template<typename _Tp>
950  inline bool
951  operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
952  {
953  using __elem_t = typename shared_ptr<_Tp>::element_type;
954  return std::less<__elem_t*>()(nullptr, __a.get());
955  }
956 
957  template<typename _Tp>
958  inline bool
959  operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
960  {
961  using __elem_t = typename shared_ptr<_Tp>::element_type;
962  return std::less<__elem_t*>()(__a.get(), nullptr);
963  }
964 
965  template<typename _Tp1, typename _Tp2>
966  inline bool
967  operator>=(const shared_ptr<_Tp1>& __a,
968  const shared_ptr<_Tp2>& __b) noexcept
969  { return !(__a < __b); }
970 
971  template<typename _Tp>
972  inline bool
973  operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
974  { return !(__a < nullptr); }
975 
976  template<typename _Tp>
977  inline bool
978  operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
979  { return !(nullptr < __a); }
980 
981  // C++14 §20.8.2.2.8
982  template<typename _Tp>
983  inline void
984  swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
985  { __a.swap(__b); }
986 
987  // 8.2.1.3, shared_ptr casts
988  template<typename _Tp, typename _Tp1>
989  inline shared_ptr<_Tp>
990  static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
991  {
992  using __elem_t = typename shared_ptr<_Tp>::element_type;
993  return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
994  }
995 
996  template<typename _Tp, typename _Tp1>
997  inline shared_ptr<_Tp>
998  dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
999  {
1000  using __elem_t = typename shared_ptr<_Tp>::element_type;
1001  if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
1002  return shared_ptr<_Tp>(__r, __p);
1003  return shared_ptr<_Tp>();
1004  }
1005 
1006  template<typename _Tp, typename _Tp1>
1007  inline shared_ptr<_Tp>
1008  const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
1009  {
1010  using __elem_t = typename shared_ptr<_Tp>::element_type;
1011  return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
1012  }
1013 
1014  template<typename _Tp, typename _Tp1>
1015  inline shared_ptr<_Tp>
1016  reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
1017  {
1018  using __elem_t = typename shared_ptr<_Tp>::element_type;
1019  return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
1020  }
1021 
1022  // C++14 §20.8.2.3
1023  template<typename _Tp>
1024  class weak_ptr : public __weak_ptr<_Tp>
1025  {
1026  template<typename _Tp1, typename _Res = void>
1027  using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
1028 
1029  using _Base_type = __weak_ptr<_Tp>;
1030 
1031  public:
1032  constexpr weak_ptr() noexcept = default;
1033 
1034  template<typename _Tp1, typename = _Compatible<_Tp1>>
1035  weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
1036  : _Base_type(__r) { }
1037 
1038  weak_ptr(const weak_ptr&) noexcept = default;
1039 
1040  template<typename _Tp1, typename = _Compatible<_Tp1>>
1041  weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
1042  : _Base_type(__r) { }
1043 
1044  weak_ptr(weak_ptr&&) noexcept = default;
1045 
1046  template<typename _Tp1, typename = _Compatible<_Tp1>>
1047  weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
1048  : _Base_type(std::move(__r)) { }
1049 
1050  weak_ptr&
1051  operator=(const weak_ptr& __r) noexcept = default;
1052 
1053  template<typename _Tp1>
1054  _Compatible<_Tp1, weak_ptr&>
1055  operator=(const weak_ptr<_Tp1>& __r) noexcept
1056  {
1057  this->_Base_type::operator=(__r);
1058  return *this;
1059  }
1060 
1061  template<typename _Tp1>
1062  _Compatible<_Tp1, weak_ptr&>
1063  operator=(const shared_ptr<_Tp1>& __r) noexcept
1064  {
1065  this->_Base_type::operator=(__r);
1066  return *this;
1067  }
1068 
1069  weak_ptr&
1070  operator=(weak_ptr&& __r) noexcept = default;
1071 
1072  template<typename _Tp1>
1073  _Compatible<_Tp1, weak_ptr&>
1074  operator=(weak_ptr<_Tp1>&& __r) noexcept
1075  {
1076  this->_Base_type::operator=(std::move(__r));
1077  return *this;
1078  }
1079 
1080  shared_ptr<_Tp>
1081  lock() const noexcept
1082  { return shared_ptr<_Tp>(*this, std::nothrow); }
1083 
1084  friend class enable_shared_from_this<_Tp>;
1085  };
1086 
1087  // C++14 §20.8.2.3.6
1088  template<typename _Tp>
1089  inline void
1090  swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
1091  { __a.swap(__b); }
1092 
1093  /// C++14 §20.8.2.2.10
1094  template<typename _Del, typename _Tp, _Lock_policy _Lp>
1095  inline _Del*
1096  get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
1097  { return std::get_deleter<_Del>(__p); }
1098 
1099  // C++14 §20.8.2.2.11
1100  template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
1102  operator<<(std::basic_ostream<_Ch, _Tr>& __os,
1103  const __shared_ptr<_Tp, _Lp>& __p)
1104  {
1105  __os << __p.get();
1106  return __os;
1107  }
1108 
1109  // C++14 §20.8.2.4
1110  template<typename _Tp = void> class owner_less;
1111 
1112  /// Partial specialization of owner_less for shared_ptr.
1113  template<typename _Tp>
1114  struct owner_less<shared_ptr<_Tp>>
1115  : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
1116  { };
1117 
1118  /// Partial specialization of owner_less for weak_ptr.
1119  template<typename _Tp>
1120  struct owner_less<weak_ptr<_Tp>>
1121  : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
1122  { };
1123 
1124  template<>
1125  class owner_less<void>
1126  {
1127  template<typename _Tp, typename _Up>
1128  bool
1129  operator()(shared_ptr<_Tp> const& __lhs,
1130  shared_ptr<_Up> const& __rhs) const
1131  { return __lhs.owner_before(__rhs); }
1132 
1133  template<typename _Tp, typename _Up>
1134  bool
1135  operator()(shared_ptr<_Tp> const& __lhs,
1136  weak_ptr<_Up> const& __rhs) const
1137  { return __lhs.owner_before(__rhs); }
1138 
1139  template<typename _Tp, typename _Up>
1140  bool
1141  operator()(weak_ptr<_Tp> const& __lhs,
1142  shared_ptr<_Up> const& __rhs) const
1143  { return __lhs.owner_before(__rhs); }
1144 
1145  template<typename _Tp, typename _Up>
1146  bool
1147  operator()(weak_ptr<_Tp> const& __lhs,
1148  weak_ptr<_Up> const& __rhs) const
1149  { return __lhs.owner_before(__rhs); }
1150 
1151  typedef void is_transparent;
1152  };
1153 
1154  // C++14 §20.8.2.6
1155  template<typename _Tp>
1156  inline bool
1157  atomic_is_lock_free(const shared_ptr<_Tp>* __p)
1158  { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
1159 
1160  template<typename _Tp>
1161  shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
1162  { return std::atomic_load<_Tp>(__p); }
1163 
1164  template<typename _Tp>
1165  shared_ptr<_Tp>
1166  atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
1167  { return std::atomic_load_explicit<_Tp>(__p, __mo); }
1168 
1169  template<typename _Tp>
1170  void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1171  { return std::atomic_store<_Tp>(__p, __r); }
1172 
1173  template<typename _Tp>
1174  shared_ptr<_Tp>
1175  atomic_store_explicit(const shared_ptr<_Tp>* __p,
1176  shared_ptr<_Tp> __r,
1177  memory_order __mo)
1178  { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
1179 
1180  template<typename _Tp>
1181  void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1182  { return std::atomic_exchange<_Tp>(__p, __r); }
1183 
1184  template<typename _Tp>
1185  shared_ptr<_Tp>
1186  atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
1187  shared_ptr<_Tp> __r,
1188  memory_order __mo)
1189  { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
1190 
1191  template<typename _Tp>
1192  bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
1193  shared_ptr<_Tp>* __v,
1194  shared_ptr<_Tp> __w)
1195  { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
1196 
1197  template<typename _Tp>
1198  bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
1199  shared_ptr<_Tp>* __v,
1200  shared_ptr<_Tp> __w)
1201  { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
1202 
1203  template<typename _Tp>
1204  bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
1205  shared_ptr<_Tp>* __v,
1206  shared_ptr<_Tp> __w,
1207  memory_order __success,
1208  memory_order __failure)
1209  { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
1210  __success,
1211  __failure); }
1212 
1213  template<typename _Tp>
1214  bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
1215  shared_ptr<_Tp>* __v,
1216  shared_ptr<_Tp> __w,
1217  memory_order __success,
1218  memory_order __failure)
1219  { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
1220  __success,
1221  __failure); }
1222 
1223  //enable_shared_from_this
1224  template<typename _Tp>
1225  class enable_shared_from_this
1226  {
1227  protected:
1228  constexpr enable_shared_from_this() noexcept { }
1229 
1230  enable_shared_from_this(const enable_shared_from_this&) noexcept { }
1231 
1232  enable_shared_from_this&
1233  operator=(const enable_shared_from_this&) noexcept
1234  { return *this; }
1235 
1236  ~enable_shared_from_this() { }
1237 
1238  public:
1239  shared_ptr<_Tp>
1240  shared_from_this()
1241  { return shared_ptr<_Tp>(this->_M_weak_this); }
1242 
1243  shared_ptr<const _Tp>
1244  shared_from_this() const
1245  { return shared_ptr<const _Tp>(this->_M_weak_this); }
1246 
1247  weak_ptr<_Tp>
1248  weak_from_this() noexcept
1249  { return _M_weak_this; }
1250 
1251  weak_ptr<const _Tp>
1252  weak_from_this() const noexcept
1253  { return _M_weak_this; }
1254 
1255  private:
1256  template<typename _Tp1>
1257  void
1258  _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
1259  { _M_weak_this._M_assign(__p, __n); }
1260 
1261  template<typename _Tp1>
1262  friend void
1263  __enable_shared_from_this_helper(const __shared_count<>& __pn,
1264  const enable_shared_from_this* __pe,
1265  const _Tp1* __px) noexcept
1266  {
1267  if(__pe != 0)
1268  __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1269  }
1270 
1271  mutable weak_ptr<_Tp> _M_weak_this;
1272  };
1273 
1274 _GLIBCXX_END_NAMESPACE_VERSION
1275 } // namespace fundamentals_v2
1276 } // namespace experimental
1277 
1278 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1279 
1280  /// std::hash specialization for shared_ptr.
1281  template<typename _Tp>
1282  struct hash<experimental::shared_ptr<_Tp>>
1283  : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
1284  {
1285  size_t
1286  operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
1287  { return std::hash<_Tp*>()(__s.get()); }
1288  };
1289 
1290 _GLIBCXX_END_NAMESPACE_VERSION
1291 } // namespace std
1292 
1293 #endif // __cplusplus <= 201103L
1294 
1295 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
memory_order
Enumeration for memory_order.
Definition: atomic_base.h:55
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
Definition: type_traits:90
Template class basic_ostream.
Definition: iosfwd:86
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:76
One of the comparison functors.
Definition: stl_function.h:340
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:87
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&... __args)
Create an object that is owned by a shared_ptr.
_Del * get_deleter(const __shared_ptr< _Tp, _Lp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter
ISO C++ entities toplevel namespace is std.
void lock(_L1 &__l1, _L2 &__l2, _L3 &... __l3)
Generic lock.
Definition: mutex:540
Primary class template hash.
Definition: system_error:134
Partial specializations for pointer types.
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:87
A smart pointer with reference-counted copy semantics.