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  // }
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>
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
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
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&...__args)
Create an object that is owned by a shared_ptr.
Partial specializations for pointer types.
memory_order
Enumeration for memory_order.
Definition: atomic_base.h:55
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:87
One of the comparison functors.
Definition: stl_function.h:340
void lock(_L1 &__l1, _L2 &__l2, _L3 &...__l3)
Generic lock.
Definition: mutex:540
_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.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:87
Primary class template hash.
Definition: system_error:134