File Coverage

/usr/include/c++/5/bits/shared_ptr_base.h
Criterion Covered Total %
statement 38 82 46.3
branch 4 28 14.2
condition n/a
subroutine n/a
pod n/a
total 42 110 38.1


line stmt bran cond sub pod time code
1             // shared_ptr and weak_ptr implementation details -*- C++ -*-
2              
3             // Copyright (C) 2007-2015 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             // .
24              
25             // GCC Note: Based on files from version 1.32.0 of the Boost library.
26              
27             // shared_count.hpp
28             // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29              
30             // shared_ptr.hpp
31             // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32             // Copyright (C) 2001, 2002, 2003 Peter Dimov
33              
34             // weak_ptr.hpp
35             // Copyright (C) 2001, 2002, 2003 Peter Dimov
36              
37             // enable_shared_from_this.hpp
38             // Copyright (C) 2002 Peter Dimov
39              
40             // Distributed under the Boost Software License, Version 1.0. (See
41             // accompanying file LICENSE_1_0.txt or copy at
42             // http://www.boost.org/LICENSE_1_0.txt)
43              
44             /** @file bits/shared_ptr_base.h
45             * This is an internal header file, included by other library headers.
46             * Do not attempt to use it directly. @headername{memory}
47             */
48              
49             #ifndef _SHARED_PTR_BASE_H
50             #define _SHARED_PTR_BASE_H 1
51              
52             #include
53             #include
54              
55             namespace std _GLIBCXX_VISIBILITY(default)
56             {
57             _GLIBCXX_BEGIN_NAMESPACE_VERSION
58              
59             #if _GLIBCXX_USE_DEPRECATED
60             template class auto_ptr;
61             #endif
62              
63             /**
64             * @brief Exception possibly thrown by @c shared_ptr.
65             * @ingroup exceptions
66             */
67             class bad_weak_ptr : public std::exception
68             {
69             public:
70             virtual char const*
71             what() const noexcept;
72              
73             virtual ~bad_weak_ptr() noexcept;
74             };
75              
76             // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
77             inline void
78             __throw_bad_weak_ptr()
79             { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
80              
81             using __gnu_cxx::_Lock_policy;
82             using __gnu_cxx::__default_lock_policy;
83             using __gnu_cxx::_S_single;
84             using __gnu_cxx::_S_mutex;
85             using __gnu_cxx::_S_atomic;
86              
87             // Empty helper class except when the template argument is _S_mutex.
88             template<_Lock_policy _Lp>
89 0           class _Mutex_base
90             {
91             protected:
92             // The atomic policy uses fully-fenced builtins, single doesn't care.
93             enum { _S_need_barriers = 0 };
94             };
95              
96             template<>
97             class _Mutex_base<_S_mutex>
98             : public __gnu_cxx::__mutex
99             {
100             protected:
101             // This policy is used when atomic builtins are not available.
102             // The replacement atomic operations might not have the necessary
103             // memory barriers.
104             enum { _S_need_barriers = 1 };
105             };
106              
107             template<_Lock_policy _Lp = __default_lock_policy>
108             class _Sp_counted_base
109             : public _Mutex_base<_Lp>
110             {
111             public:
112 0           _Sp_counted_base() noexcept
113 0           : _M_use_count(1), _M_weak_count(1) { }
114            
115             virtual
116 0           ~_Sp_counted_base() noexcept
117 0 0         { }
118            
119             // Called when _M_use_count drops to zero, to release the resources
120             // managed by *this.
121             virtual void
122             _M_dispose() noexcept = 0;
123            
124             // Called when _M_weak_count drops to zero.
125             virtual void
126 0           _M_destroy() noexcept
127 0 0         { delete this; }
128            
129             virtual void*
130             _M_get_deleter(const std::type_info&) noexcept = 0;
131              
132             void
133 0           _M_add_ref_copy()
134 0           { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
135            
136             void
137             _M_add_ref_lock();
138              
139             bool
140             _M_add_ref_lock_nothrow();
141              
142             void
143 0           _M_release() noexcept
144             {
145             // Be race-detector-friendly. For more info see bits/c++config.
146             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
147 0 0         if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
148             {
149             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
150 0           _M_dispose();
151             // There must be a memory barrier between dispose() and destroy()
152             // to ensure that the effects of dispose() are observed in the
153             // thread that runs destroy().
154             // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
155             if (_Mutex_base<_Lp>::_S_need_barriers)
156             {
157             _GLIBCXX_READ_MEM_BARRIER;
158             _GLIBCXX_WRITE_MEM_BARRIER;
159             }
160              
161             // Be race-detector-friendly. For more info see bits/c++config.
162             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
163 0 0         if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
164             -1) == 1)
165             {
166             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
167 0           _M_destroy();
168             }
169             }
170 0           }
171            
172             void
173             _M_weak_add_ref() noexcept
174             { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
175              
176             void
177             _M_weak_release() noexcept
178             {
179             // Be race-detector-friendly. For more info see bits/c++config.
180             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
181             if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
182             {
183             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
184             if (_Mutex_base<_Lp>::_S_need_barriers)
185             {
186             // See _M_release(),
187             // destroy() must observe results of dispose()
188             _GLIBCXX_READ_MEM_BARRIER;
189             _GLIBCXX_WRITE_MEM_BARRIER;
190             }
191             _M_destroy();
192             }
193             }
194            
195             long
196             _M_get_use_count() const noexcept
197             {
198             // No memory barrier is used here so there is no synchronization
199             // with other threads.
200             return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
201             }
202              
203             private:
204             _Sp_counted_base(_Sp_counted_base const&) = delete;
205             _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
206              
207             _Atomic_word _M_use_count; // #shared
208             _Atomic_word _M_weak_count; // #weak + (#shared != 0)
209             };
210              
211             template<>
212             inline void
213             _Sp_counted_base<_S_single>::
214             _M_add_ref_lock()
215             {
216             if (_M_use_count == 0)
217             __throw_bad_weak_ptr();
218             ++_M_use_count;
219             }
220              
221             template<>
222             inline void
223             _Sp_counted_base<_S_mutex>::
224             _M_add_ref_lock()
225             {
226             __gnu_cxx::__scoped_lock sentry(*this);
227             if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
228             {
229             _M_use_count = 0;
230             __throw_bad_weak_ptr();
231             }
232             }
233              
234             template<>
235             inline void
236             _Sp_counted_base<_S_atomic>::
237             _M_add_ref_lock()
238             {
239             // Perform lock-free add-if-not-zero operation.
240             _Atomic_word __count = _M_get_use_count();
241             do
242             {
243             if (__count == 0)
244             __throw_bad_weak_ptr();
245             // Replace the current counter value with the old value + 1, as
246             // long as it's not changed meanwhile.
247             }
248             while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
249             true, __ATOMIC_ACQ_REL,
250             __ATOMIC_RELAXED));
251             }
252              
253             template<>
254             inline bool
255             _Sp_counted_base<_S_single>::
256             _M_add_ref_lock_nothrow()
257             {
258             if (_M_use_count == 0)
259             return false;
260             ++_M_use_count;
261             return true;
262             }
263              
264             template<>
265             inline bool
266             _Sp_counted_base<_S_mutex>::
267             _M_add_ref_lock_nothrow()
268             {
269             __gnu_cxx::__scoped_lock sentry(*this);
270             if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
271             {
272             _M_use_count = 0;
273             return false;
274             }
275             return true;
276             }
277              
278             template<>
279             inline bool
280             _Sp_counted_base<_S_atomic>::
281             _M_add_ref_lock_nothrow()
282             {
283             // Perform lock-free add-if-not-zero operation.
284             _Atomic_word __count = _M_get_use_count();
285             do
286             {
287             if (__count == 0)
288             return false;
289             // Replace the current counter value with the old value + 1, as
290             // long as it's not changed meanwhile.
291             }
292             while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
293             true, __ATOMIC_ACQ_REL,
294             __ATOMIC_RELAXED));
295             return true;
296             }
297              
298             template<>
299             inline void
300             _Sp_counted_base<_S_single>::_M_add_ref_copy()
301             { ++_M_use_count; }
302              
303             template<>
304             inline void
305             _Sp_counted_base<_S_single>::_M_release() noexcept
306             {
307             if (--_M_use_count == 0)
308             {
309             _M_dispose();
310             if (--_M_weak_count == 0)
311             _M_destroy();
312             }
313             }
314              
315             template<>
316             inline void
317             _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
318             { ++_M_weak_count; }
319              
320             template<>
321             inline void
322             _Sp_counted_base<_S_single>::_M_weak_release() noexcept
323             {
324             if (--_M_weak_count == 0)
325             _M_destroy();
326             }
327              
328             template<>
329             inline long
330             _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
331             { return _M_use_count; }
332              
333              
334             // Forward declarations.
335             template
336             class __shared_ptr;
337              
338             template
339             class __weak_ptr;
340              
341             template
342             class __enable_shared_from_this;
343              
344             template
345             class shared_ptr;
346              
347             template
348             class weak_ptr;
349              
350             template
351             struct owner_less;
352              
353             template
354             class enable_shared_from_this;
355              
356             template<_Lock_policy _Lp = __default_lock_policy>
357             class __weak_count;
358              
359             template<_Lock_policy _Lp = __default_lock_policy>
360             class __shared_count;
361              
362              
363             // Counted ptr with no deleter or allocator support
364             template
365 560 50         class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
366             {
367             public:
368             explicit
369 140           _Sp_counted_ptr(_Ptr __p) noexcept
370 140           : _M_ptr(__p) { }
371              
372             virtual void
373 140           _M_dispose() noexcept
374 140 50         { delete _M_ptr; }
375              
376             virtual void
377 140           _M_destroy() noexcept
378 140 50         { delete this; }
379              
380             virtual void*
381 0           _M_get_deleter(const std::type_info&) noexcept
382 0           { return nullptr; }
383              
384             _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
385             _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
386              
387             private:
388             _Ptr _M_ptr;
389             };
390              
391             template<>
392             inline void
393             _Sp_counted_ptr::_M_dispose() noexcept { }
394              
395             template<>
396             inline void
397             _Sp_counted_ptr::_M_dispose() noexcept { }
398              
399             template<>
400             inline void
401             _Sp_counted_ptr::_M_dispose() noexcept { }
402              
403             template
404             bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
405             struct _Sp_ebo_helper;
406              
407             /// Specialization using EBO.
408             template
409             struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
410             {
411             explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
412              
413             static _Tp&
414             _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
415             };
416              
417             /// Specialization not using EBO.
418             template
419             struct _Sp_ebo_helper<_Nm, _Tp, false>
420             {
421             explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
422              
423             static _Tp&
424             _S_get(_Sp_ebo_helper& __eboh)
425             { return __eboh._M_tp; }
426              
427             private:
428             _Tp _M_tp;
429             };
430              
431             // Support for custom deleter and/or allocator
432             template
433             class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
434             {
435             class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
436             {
437             typedef _Sp_ebo_helper<0, _Deleter> _Del_base;
438             typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base;
439              
440             public:
441             _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
442             : _M_ptr(__p), _Del_base(__d), _Alloc_base(__a)
443             { }
444              
445             _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
446             _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
447              
448             _Ptr _M_ptr;
449             };
450              
451             public:
452             using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
453              
454             // __d(__p) must not throw.
455             _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
456             : _M_impl(__p, __d, _Alloc()) { }
457              
458             // __d(__p) must not throw.
459             _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
460             : _M_impl(__p, __d, __a) { }
461              
462             ~_Sp_counted_deleter() noexcept { }
463              
464             virtual void
465             _M_dispose() noexcept
466             { _M_impl._M_del()(_M_impl._M_ptr); }
467              
468             virtual void
469             _M_destroy() noexcept
470             {
471             __allocator_type __a(_M_impl._M_alloc());
472             __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
473             this->~_Sp_counted_deleter();
474             }
475              
476             virtual void*
477             _M_get_deleter(const std::type_info& __ti) noexcept
478             {
479             #if __cpp_rtti
480             // _GLIBCXX_RESOLVE_LIB_DEFECTS
481             // 2400. shared_ptr's get_deleter() should use addressof()
482             return __ti == typeid(_Deleter)
483             ? std::__addressof(_M_impl._M_del())
484             : nullptr;
485             #else
486             return nullptr;
487             #endif
488             }
489              
490             private:
491             _Impl _M_impl;
492             };
493              
494             // helpers for make_shared / allocate_shared
495              
496             struct _Sp_make_shared_tag { };
497              
498             template
499             class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
500             {
501             class _Impl : _Sp_ebo_helper<0, _Alloc>
502             {
503             typedef _Sp_ebo_helper<0, _Alloc> _A_base;
504              
505             public:
506             explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
507              
508             _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
509              
510             __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
511             };
512              
513             public:
514             using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
515              
516             template
517             _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
518             : _M_impl(__a)
519             {
520             // _GLIBCXX_RESOLVE_LIB_DEFECTS
521             // 2070. allocate_shared should use allocator_traits::construct
522             allocator_traits<_Alloc>::construct(__a, _M_ptr(),
523             std::forward<_Args>(__args)...); // might throw
524             }
525              
526             ~_Sp_counted_ptr_inplace() noexcept { }
527              
528             virtual void
529             _M_dispose() noexcept
530             {
531             allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
532             }
533              
534             // Override because the allocator needs to know the dynamic type
535             virtual void
536             _M_destroy() noexcept
537             {
538             __allocator_type __a(_M_impl._M_alloc());
539             __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
540             this->~_Sp_counted_ptr_inplace();
541             }
542              
543             // Sneaky trick so __shared_ptr can get the managed pointer
544             virtual void*
545             _M_get_deleter(const std::type_info& __ti) noexcept
546             {
547             #if __cpp_rtti
548             if (__ti == typeid(_Sp_make_shared_tag))
549             return const_cast::type*>(_M_ptr());
550             #endif
551             return nullptr;
552             }
553              
554             private:
555             _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
556              
557             _Impl _M_impl;
558             };
559              
560              
561             template<_Lock_policy _Lp>
562             class __shared_count
563             {
564             public:
565 0           constexpr __shared_count() noexcept : _M_pi(0)
566 0           { }
567              
568             template
569             explicit
570 140           __shared_count(_Ptr __p) : _M_pi(0)
571             {
572             __try
573             {
574 140 50         _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
575             }
576             __catch(...)
577   0         {
578             delete __p;
579             __throw_exception_again;
580             }
581 140           }
582              
583             template
584             __shared_count(_Ptr __p, _Deleter __d)
585             : __shared_count(__p, std::move(__d), allocator())
586             { }
587              
588             template
589             __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
590             {
591             typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
592             __try
593             {
594             typename _Sp_cd_type::__allocator_type __a2(__a);
595             auto __guard = std::__allocate_guarded(__a2);
596             _Sp_cd_type* __mem = __guard.get();
597             ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
598             _M_pi = __mem;
599             __guard = nullptr;
600             }
601             __catch(...)
602             {
603             __d(__p); // Call _Deleter on __p.
604             __throw_exception_again;
605             }
606             }
607              
608             template
609             __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
610             _Args&&... __args)
611             : _M_pi(0)
612             {
613             typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
614             typename _Sp_cp_type::__allocator_type __a2(__a);
615             auto __guard = std::__allocate_guarded(__a2);
616             _Sp_cp_type* __mem = __guard.get();
617             ::new (__mem) _Sp_cp_type(std::move(__a),
618             std::forward<_Args>(__args)...);
619             _M_pi = __mem;
620             __guard = nullptr;
621             }
622              
623             #if _GLIBCXX_USE_DEPRECATED
624             // Special case for auto_ptr<_Tp> to provide the strong guarantee.
625             template
626             explicit
627             __shared_count(std::auto_ptr<_Tp>&& __r);
628             #endif
629              
630             // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
631             template
632             explicit
633             __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
634             {
635             using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
636             using _Del2 = typename conditional::value,
637             reference_wrapper::type>,
638             _Del>::type;
639             using _Sp_cd_type
640             = _Sp_counted_deleter<_Ptr, _Del2, allocator, _Lp>;
641             using _Alloc = allocator<_Sp_cd_type>;
642             using _Alloc_traits = allocator_traits<_Alloc>;
643             _Alloc __a;
644             _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
645             _Alloc_traits::construct(__a, __mem, __r.release(),
646             __r.get_deleter()); // non-throwing
647             _M_pi = __mem;
648             }
649              
650             // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
651             explicit __shared_count(const __weak_count<_Lp>& __r);
652              
653             // Does not throw if __r._M_get_use_count() == 0, caller must check.
654             explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t);
655              
656 0           ~__shared_count() noexcept
657             {
658 0 0         if (_M_pi != nullptr)
659 0           _M_pi->_M_release();
660 0           }
661              
662 0           __shared_count(const __shared_count& __r) noexcept
663 0           : _M_pi(__r._M_pi)
664             {
665 0 0         if (_M_pi != 0)
666 0           _M_pi->_M_add_ref_copy();
667 0           }
668              
669             __shared_count&
670 0           operator=(const __shared_count& __r) noexcept
671             {
672 0           _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
673 0 0         if (__tmp != _M_pi)
674             {
675 0 0         if (__tmp != 0)
676 0           __tmp->_M_add_ref_copy();
677 0 0         if (_M_pi != 0)
678 0           _M_pi->_M_release();
679 0           _M_pi = __tmp;
680             }
681 0           return *this;
682             }
683              
684             void
685 0           _M_swap(__shared_count& __r) noexcept
686             {
687 0           _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
688 0           __r._M_pi = _M_pi;
689 0           _M_pi = __tmp;
690 0           }
691              
692             long
693             _M_get_use_count() const noexcept
694             { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
695              
696             bool
697             _M_unique() const noexcept
698             { return this->_M_get_use_count() == 1; }
699              
700             void*
701             _M_get_deleter(const std::type_info& __ti) const noexcept
702             { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
703              
704             bool
705             _M_less(const __shared_count& __rhs) const noexcept
706             { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
707              
708             bool
709             _M_less(const __weak_count<_Lp>& __rhs) const noexcept
710             { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
711              
712             // Friend function injected into enclosing namespace and found by ADL
713             friend inline bool
714             operator==(const __shared_count& __a, const __shared_count& __b) noexcept
715             { return __a._M_pi == __b._M_pi; }
716              
717             private:
718             friend class __weak_count<_Lp>;
719              
720             _Sp_counted_base<_Lp>* _M_pi;
721             };
722              
723              
724             template<_Lock_policy _Lp>
725             class __weak_count
726             {
727             public:
728             constexpr __weak_count() noexcept : _M_pi(nullptr)
729             { }
730              
731             __weak_count(const __shared_count<_Lp>& __r) noexcept
732             : _M_pi(__r._M_pi)
733             {
734             if (_M_pi != nullptr)
735             _M_pi->_M_weak_add_ref();
736             }
737              
738             __weak_count(const __weak_count& __r) noexcept
739             : _M_pi(__r._M_pi)
740             {
741             if (_M_pi != nullptr)
742             _M_pi->_M_weak_add_ref();
743             }
744              
745             __weak_count(__weak_count&& __r) noexcept
746             : _M_pi(__r._M_pi)
747             { __r._M_pi = nullptr; }
748              
749             ~__weak_count() noexcept
750             {
751             if (_M_pi != nullptr)
752             _M_pi->_M_weak_release();
753             }
754              
755             __weak_count&
756             operator=(const __shared_count<_Lp>& __r) noexcept
757             {
758             _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
759             if (__tmp != nullptr)
760             __tmp->_M_weak_add_ref();
761             if (_M_pi != nullptr)
762             _M_pi->_M_weak_release();
763             _M_pi = __tmp;
764             return *this;
765             }
766              
767             __weak_count&
768             operator=(const __weak_count& __r) noexcept
769             {
770             _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
771             if (__tmp != nullptr)
772             __tmp->_M_weak_add_ref();
773             if (_M_pi != nullptr)
774             _M_pi->_M_weak_release();
775             _M_pi = __tmp;
776             return *this;
777             }
778              
779             __weak_count&
780             operator=(__weak_count&& __r) noexcept
781             {
782             if (_M_pi != nullptr)
783             _M_pi->_M_weak_release();
784             _M_pi = __r._M_pi;
785             __r._M_pi = nullptr;
786             return *this;
787             }
788              
789             void
790             _M_swap(__weak_count& __r) noexcept
791             {
792             _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
793             __r._M_pi = _M_pi;
794             _M_pi = __tmp;
795             }
796              
797             long
798             _M_get_use_count() const noexcept
799             { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
800              
801             bool
802             _M_less(const __weak_count& __rhs) const noexcept
803             { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
804              
805             bool
806             _M_less(const __shared_count<_Lp>& __rhs) const noexcept
807             { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
808              
809             // Friend function injected into enclosing namespace and found by ADL
810             friend inline bool
811             operator==(const __weak_count& __a, const __weak_count& __b) noexcept
812             { return __a._M_pi == __b._M_pi; }
813              
814             private:
815             friend class __shared_count<_Lp>;
816              
817             _Sp_counted_base<_Lp>* _M_pi;
818             };
819              
820             // Now that __weak_count is defined we can define this constructor:
821             template<_Lock_policy _Lp>
822             inline
823             __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
824             : _M_pi(__r._M_pi)
825             {
826             if (_M_pi != nullptr)
827             _M_pi->_M_add_ref_lock();
828             else
829             __throw_bad_weak_ptr();
830             }
831              
832             // Now that __weak_count is defined we can define this constructor:
833             template<_Lock_policy _Lp>
834             inline
835             __shared_count<_Lp>::
836             __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
837             : _M_pi(__r._M_pi)
838             {
839             if (_M_pi != nullptr)
840             if (!_M_pi->_M_add_ref_lock_nothrow())
841             _M_pi = nullptr;
842             }
843              
844             // Support for enable_shared_from_this.
845              
846             // Friend of __enable_shared_from_this.
847             template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
848             void
849             __enable_shared_from_this_helper(const __shared_count<_Lp>&,
850             const __enable_shared_from_this<_Tp1,
851             _Lp>*, const _Tp2*) noexcept;
852              
853             // Friend of enable_shared_from_this.
854             template
855             void
856             __enable_shared_from_this_helper(const __shared_count<>&,
857             const enable_shared_from_this<_Tp1>*,
858             const _Tp2*) noexcept;
859              
860             template<_Lock_policy _Lp>
861             inline void
862 0           __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
863 0           { }
864              
865              
866             template
867 658           class __shared_ptr
868             {
869             template
870             using _Convertible
871             = typename enable_if::value>::type;
872              
873             public:
874             typedef _Tp element_type;
875              
876 501           constexpr __shared_ptr() noexcept
877 501           : _M_ptr(0), _M_refcount()
878 501           { }
879              
880             template
881 140           explicit __shared_ptr(_Tp1* __p)
882 140           : _M_ptr(__p), _M_refcount(__p)
883             {
884             __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
885             static_assert( !is_void<_Tp1>::value, "incomplete type" );
886             static_assert( sizeof(_Tp1) > 0, "incomplete type" );
887 140           __enable_shared_from_this_helper(_M_refcount, __p, __p);
888 140           }
889              
890             template
891             __shared_ptr(_Tp1* __p, _Deleter __d)
892             : _M_ptr(__p), _M_refcount(__p, __d)
893             {
894             __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
895             // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
896             __enable_shared_from_this_helper(_M_refcount, __p, __p);
897             }
898              
899             template
900             __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
901             : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
902             {
903             __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
904             // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
905             __enable_shared_from_this_helper(_M_refcount, __p, __p);
906             }
907              
908             template
909             __shared_ptr(nullptr_t __p, _Deleter __d)
910             : _M_ptr(0), _M_refcount(__p, __d)
911             { }
912              
913             template
914             __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
915             : _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
916             { }
917              
918             template
919             __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
920             : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
921             { }
922              
923 1540           __shared_ptr(const __shared_ptr&) noexcept = default;
924             __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
925 3602           ~__shared_ptr() = default;
926              
927             template>
928             __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
929             : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
930             { }
931              
932 250           __shared_ptr(__shared_ptr&& __r) noexcept
933 250           : _M_ptr(__r._M_ptr), _M_refcount()
934             {
935 250           _M_refcount._M_swap(__r._M_refcount);
936 250           __r._M_ptr = 0;
937 250           }
938              
939             template>
940             __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
941             : _M_ptr(__r._M_ptr), _M_refcount()
942             {
943             _M_refcount._M_swap(__r._M_refcount);
944             __r._M_ptr = 0;
945             }
946              
947             template
948             explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
949             : _M_refcount(__r._M_refcount) // may throw
950             {
951             __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
952              
953             // It is now safe to copy __r._M_ptr, as
954             // _M_refcount(__r._M_refcount) did not throw.
955             _M_ptr = __r._M_ptr;
956             }
957              
958             // If an exception is thrown this constructor has no effect.
959             template
960             = _Convertible::pointer>>
961             __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
962             : _M_ptr(__r.get()), _M_refcount()
963             {
964             __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
965             auto __raw = _S_raw_ptr(__r.get());
966             _M_refcount = __shared_count<_Lp>(std::move(__r));
967             __enable_shared_from_this_helper(_M_refcount, __raw, __raw);
968             }
969              
970             #if _GLIBCXX_USE_DEPRECATED
971             // Postcondition: use_count() == 1 and __r.get() == 0
972             template
973             __shared_ptr(std::auto_ptr<_Tp1>&& __r);
974             #endif
975              
976             constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
977              
978             template
979             __shared_ptr&
980             operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
981             {
982             _M_ptr = __r._M_ptr;
983             _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
984             return *this;
985             }
986              
987             #if _GLIBCXX_USE_DEPRECATED
988             template
989             __shared_ptr&
990             operator=(std::auto_ptr<_Tp1>&& __r)
991             {
992             __shared_ptr(std::move(__r)).swap(*this);
993             return *this;
994             }
995             #endif
996              
997             __shared_ptr&
998 250           operator=(__shared_ptr&& __r) noexcept
999             {
1000 250           __shared_ptr(std::move(__r)).swap(*this);
1001 250           return *this;
1002             }
1003              
1004             template
1005             __shared_ptr&
1006             operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
1007             {
1008             __shared_ptr(std::move(__r)).swap(*this);
1009             return *this;
1010             }
1011              
1012             template
1013             __shared_ptr&
1014             operator=(std::unique_ptr<_Tp1, _Del>&& __r)
1015             {
1016             __shared_ptr(std::move(__r)).swap(*this);
1017             return *this;
1018             }
1019              
1020             void
1021             reset() noexcept
1022             { __shared_ptr().swap(*this); }
1023              
1024             template
1025             void
1026             reset(_Tp1* __p) // _Tp1 must be complete.
1027             {
1028             // Catch self-reset errors.
1029             _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
1030             __shared_ptr(__p).swap(*this);
1031             }
1032              
1033             template
1034             void
1035             reset(_Tp1* __p, _Deleter __d)
1036             { __shared_ptr(__p, __d).swap(*this); }
1037              
1038             template
1039             void
1040             reset(_Tp1* __p, _Deleter __d, _Alloc __a)
1041             { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
1042              
1043             // Allow class instantiation when _Tp is [cv-qual] void.
1044             typename std::add_lvalue_reference<_Tp>::type
1045             operator*() const noexcept
1046             {
1047             _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
1048             return *_M_ptr;
1049             }
1050              
1051             _Tp*
1052 396           operator->() const noexcept
1053             {
1054             _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
1055 396           return _M_ptr;
1056             }
1057              
1058             _Tp*
1059 638           get() const noexcept
1060 638           { return _M_ptr; }
1061              
1062 144           explicit operator bool() const // never throws
1063 144           { return _M_ptr == 0 ? false : true; }
1064              
1065             bool
1066             unique() const noexcept
1067             { return _M_refcount._M_unique(); }
1068              
1069             long
1070             use_count() const noexcept
1071             { return _M_refcount._M_get_use_count(); }
1072              
1073             void
1074 250           swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1075             {
1076 250           std::swap(_M_ptr, __other._M_ptr);
1077 250           _M_refcount._M_swap(__other._M_refcount);
1078 250           }
1079              
1080             template
1081             bool
1082             owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
1083             { return _M_refcount._M_less(__rhs._M_refcount); }
1084              
1085             template
1086             bool
1087             owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
1088             { return _M_refcount._M_less(__rhs._M_refcount); }
1089              
1090             #if __cpp_rtti
1091             protected:
1092             // This constructor is non-standard, it is used by allocate_shared.
1093             template
1094             __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
1095             _Args&&... __args)
1096             : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
1097             std::forward<_Args>(__args)...)
1098             {
1099             // _M_ptr needs to point to the newly constructed object.
1100             // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
1101             void* __p = _M_refcount._M_get_deleter(typeid(__tag));
1102             _M_ptr = static_cast<_Tp*>(__p);
1103             __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
1104             }
1105             #else
1106             template
1107             struct _Deleter
1108             {
1109             void operator()(typename _Alloc::value_type* __ptr)
1110             {
1111             __allocated_ptr<_Alloc> __guard{ _M_alloc, __ptr };
1112             allocator_traits<_Alloc>::destroy(_M_alloc, __guard.get());
1113             }
1114             _Alloc _M_alloc;
1115             };
1116              
1117             template
1118             __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
1119             _Args&&... __args)
1120             : _M_ptr(), _M_refcount()
1121             {
1122             typedef typename allocator_traits<_Alloc>::template
1123             rebind_traits::type> __traits;
1124             _Deleter __del = { __a };
1125             auto __guard = std::__allocate_guarded(__del._M_alloc);
1126             auto __ptr = __guard.get();
1127             // _GLIBCXX_RESOLVE_LIB_DEFECTS
1128             // 2070. allocate_shared should use allocator_traits::construct
1129             __traits::construct(__del._M_alloc, __ptr,
1130             std::forward<_Args>(__args)...);
1131             __guard = nullptr;
1132             __shared_count<_Lp> __count(__ptr, __del, __del._M_alloc);
1133             _M_refcount._M_swap(__count);
1134             _M_ptr = __ptr;
1135             __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
1136             }
1137             #endif
1138              
1139             template
1140             typename... _Args>
1141             friend __shared_ptr<_Tp1, _Lp1>
1142             __allocate_shared(const _Alloc& __a, _Args&&... __args);
1143              
1144             // This constructor is used by __weak_ptr::lock() and
1145             // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1146             __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
1147             : _M_refcount(__r._M_refcount, std::nothrow)
1148             {
1149             _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1150             }
1151              
1152             friend class __weak_ptr<_Tp, _Lp>;
1153              
1154             private:
1155             void*
1156             _M_get_deleter(const std::type_info& __ti) const noexcept
1157             { return _M_refcount._M_get_deleter(__ti); }
1158              
1159             template
1160             static _Tp1*
1161             _S_raw_ptr(_Tp1* __ptr)
1162             { return __ptr; }
1163              
1164             template
1165             static auto
1166             _S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr))
1167             { return std::__addressof(*__ptr); }
1168              
1169             template friend class __shared_ptr;
1170             template friend class __weak_ptr;
1171              
1172             template
1173             friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1174              
1175             _Tp* _M_ptr; // Contained pointer.
1176             __shared_count<_Lp> _M_refcount; // Reference counter.
1177             };
1178              
1179              
1180             // 20.7.2.2.7 shared_ptr comparisons
1181             template
1182             inline bool
1183             operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1184             const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1185             { return __a.get() == __b.get(); }
1186              
1187             template
1188             inline bool
1189             operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1190             { return !__a; }
1191              
1192             template
1193             inline bool
1194             operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1195             { return !__a; }
1196              
1197             template
1198             inline bool
1199             operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1200             const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1201             { return __a.get() != __b.get(); }
1202              
1203             template
1204             inline bool
1205             operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1206             { return (bool)__a; }
1207              
1208             template
1209             inline bool
1210             operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1211             { return (bool)__a; }
1212              
1213             template
1214             inline bool
1215             operator<(const __shared_ptr<_Tp1, _Lp>& __a,
1216             const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1217             {
1218             typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
1219             return std::less<_CT>()(__a.get(), __b.get());
1220             }
1221              
1222             template
1223             inline bool
1224             operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1225             { return std::less<_Tp*>()(__a.get(), nullptr); }
1226              
1227             template
1228             inline bool
1229             operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1230             { return std::less<_Tp*>()(nullptr, __a.get()); }
1231              
1232             template
1233             inline bool
1234             operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1235             const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1236             { return !(__b < __a); }
1237              
1238             template
1239             inline bool
1240             operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1241             { return !(nullptr < __a); }
1242              
1243             template
1244             inline bool
1245             operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1246             { return !(__a < nullptr); }
1247              
1248             template
1249             inline bool
1250             operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1251             const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1252             { return (__b < __a); }
1253              
1254             template
1255             inline bool
1256             operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1257             { return std::less<_Tp*>()(nullptr, __a.get()); }
1258              
1259             template
1260             inline bool
1261             operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1262             { return std::less<_Tp*>()(__a.get(), nullptr); }
1263              
1264             template
1265             inline bool
1266             operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1267             const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1268             { return !(__a < __b); }
1269              
1270             template
1271             inline bool
1272             operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1273             { return !(__a < nullptr); }
1274              
1275             template
1276             inline bool
1277             operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1278             { return !(nullptr < __a); }
1279              
1280             template
1281             struct _Sp_less : public binary_function<_Sp, _Sp, bool>
1282             {
1283             bool
1284             operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
1285             {
1286             typedef typename _Sp::element_type element_type;
1287             return std::less()(__lhs.get(), __rhs.get());
1288             }
1289             };
1290              
1291             template
1292             struct less<__shared_ptr<_Tp, _Lp>>
1293             : public _Sp_less<__shared_ptr<_Tp, _Lp>>
1294             { };
1295              
1296             // 20.7.2.2.8 shared_ptr specialized algorithms.
1297             template
1298             inline void
1299             swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1300             { __a.swap(__b); }
1301              
1302             // 20.7.2.2.9 shared_ptr casts
1303              
1304             // The seemingly equivalent code:
1305             // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1306             // will eventually result in undefined behaviour, attempting to
1307             // delete the same object twice.
1308             /// static_pointer_cast
1309             template
1310             inline __shared_ptr<_Tp, _Lp>
1311             static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1312             { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
1313              
1314             // The seemingly equivalent code:
1315             // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1316             // will eventually result in undefined behaviour, attempting to
1317             // delete the same object twice.
1318             /// const_pointer_cast
1319             template
1320             inline __shared_ptr<_Tp, _Lp>
1321             const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1322             { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
1323              
1324             // The seemingly equivalent code:
1325             // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1326             // will eventually result in undefined behaviour, attempting to
1327             // delete the same object twice.
1328             /// dynamic_pointer_cast
1329             template
1330             inline __shared_ptr<_Tp, _Lp>
1331             dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1332             {
1333             if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
1334             return __shared_ptr<_Tp, _Lp>(__r, __p);
1335             return __shared_ptr<_Tp, _Lp>();
1336             }
1337              
1338              
1339             template
1340             class __weak_ptr
1341             {
1342             template
1343             using _Convertible
1344             = typename enable_if::value>::type;
1345              
1346             public:
1347             typedef _Tp element_type;
1348              
1349             constexpr __weak_ptr() noexcept
1350             : _M_ptr(nullptr), _M_refcount()
1351             { }
1352              
1353             __weak_ptr(const __weak_ptr&) noexcept = default;
1354              
1355             ~__weak_ptr() = default;
1356              
1357             // The "obvious" converting constructor implementation:
1358             //
1359             // template
1360             // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1361             // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1362             // { }
1363             //
1364             // has a serious problem.
1365             //
1366             // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1367             // conversion may require access to *__r._M_ptr (virtual inheritance).
1368             //
1369             // It is not possible to avoid spurious access violations since
1370             // in multithreaded programs __r._M_ptr may be invalidated at any point.
1371             template>
1372             __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
1373             : _M_refcount(__r._M_refcount)
1374             { _M_ptr = __r.lock().get(); }
1375              
1376             template>
1377             __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1378             : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1379             { }
1380              
1381             __weak_ptr(__weak_ptr&& __r) noexcept
1382             : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
1383             { __r._M_ptr = nullptr; }
1384              
1385             template>
1386             __weak_ptr(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
1387             : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
1388             { __r._M_ptr = nullptr; }
1389              
1390             __weak_ptr&
1391             operator=(const __weak_ptr& __r) noexcept = default;
1392              
1393             template
1394             __weak_ptr&
1395             operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
1396             {
1397             _M_ptr = __r.lock().get();
1398             _M_refcount = __r._M_refcount;
1399             return *this;
1400             }
1401              
1402             template
1403             __weak_ptr&
1404             operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1405             {
1406             _M_ptr = __r._M_ptr;
1407             _M_refcount = __r._M_refcount;
1408             return *this;
1409             }
1410              
1411             __weak_ptr&
1412             operator=(__weak_ptr&& __r) noexcept
1413             {
1414             _M_ptr = __r._M_ptr;
1415             _M_refcount = std::move(__r._M_refcount);
1416             __r._M_ptr = nullptr;
1417             return *this;
1418             }
1419              
1420             template
1421             __weak_ptr&
1422             operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
1423             {
1424             _M_ptr = __r.lock().get();
1425             _M_refcount = std::move(__r._M_refcount);
1426             __r._M_ptr = nullptr;
1427             return *this;
1428             }
1429              
1430             __shared_ptr<_Tp, _Lp>
1431             lock() const noexcept
1432             { return __shared_ptr(*this, std::nothrow); }
1433              
1434             long
1435             use_count() const noexcept
1436             { return _M_refcount._M_get_use_count(); }
1437              
1438             bool
1439             expired() const noexcept
1440             { return _M_refcount._M_get_use_count() == 0; }
1441              
1442             template
1443             bool
1444             owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
1445             { return _M_refcount._M_less(__rhs._M_refcount); }
1446              
1447             template
1448             bool
1449             owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
1450             { return _M_refcount._M_less(__rhs._M_refcount); }
1451              
1452             void
1453             reset() noexcept
1454             { __weak_ptr().swap(*this); }
1455              
1456             void
1457             swap(__weak_ptr& __s) noexcept
1458             {
1459             std::swap(_M_ptr, __s._M_ptr);
1460             _M_refcount._M_swap(__s._M_refcount);
1461             }
1462              
1463             private:
1464             // Used by __enable_shared_from_this.
1465             void
1466             _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1467             {
1468             _M_ptr = __ptr;
1469             _M_refcount = __refcount;
1470             }
1471              
1472             template friend class __shared_ptr;
1473             template friend class __weak_ptr;
1474             friend class __enable_shared_from_this<_Tp, _Lp>;
1475             friend class enable_shared_from_this<_Tp>;
1476              
1477             _Tp* _M_ptr; // Contained pointer.
1478             __weak_count<_Lp> _M_refcount; // Reference counter.
1479             };
1480              
1481             // 20.7.2.3.6 weak_ptr specialized algorithms.
1482             template
1483             inline void
1484             swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1485             { __a.swap(__b); }
1486              
1487             template
1488             struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
1489             {
1490             bool
1491             operator()(const _Tp& __lhs, const _Tp& __rhs) const
1492             { return __lhs.owner_before(__rhs); }
1493              
1494             bool
1495             operator()(const _Tp& __lhs, const _Tp1& __rhs) const
1496             { return __lhs.owner_before(__rhs); }
1497              
1498             bool
1499             operator()(const _Tp1& __lhs, const _Tp& __rhs) const
1500             { return __lhs.owner_before(__rhs); }
1501             };
1502              
1503             template
1504             struct owner_less<__shared_ptr<_Tp, _Lp>>
1505             : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1506             { };
1507              
1508             template
1509             struct owner_less<__weak_ptr<_Tp, _Lp>>
1510             : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1511             { };
1512              
1513              
1514             template
1515             class __enable_shared_from_this
1516             {
1517             protected:
1518             constexpr __enable_shared_from_this() noexcept { }
1519              
1520             __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
1521              
1522             __enable_shared_from_this&
1523             operator=(const __enable_shared_from_this&) noexcept
1524             { return *this; }
1525              
1526             ~__enable_shared_from_this() { }
1527              
1528             public:
1529             __shared_ptr<_Tp, _Lp>
1530             shared_from_this()
1531             { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1532              
1533             __shared_ptr
1534             shared_from_this() const
1535             { return __shared_ptr(this->_M_weak_this); }
1536              
1537             private:
1538             template
1539             void
1540             _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
1541             { _M_weak_this._M_assign(__p, __n); }
1542              
1543             template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
1544             friend void
1545             __enable_shared_from_this_helper(const __shared_count<_Lp1>&,
1546             const __enable_shared_from_this<_Tp1,
1547             _Lp1>*, const _Tp2*) noexcept;
1548              
1549             mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
1550             };
1551              
1552             template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
1553             inline void
1554             __enable_shared_from_this_helper(const __shared_count<_Lp1>& __pn,
1555             const __enable_shared_from_this<_Tp1,
1556             _Lp1>* __pe,
1557             const _Tp2* __px) noexcept
1558             {
1559             if (__pe != nullptr)
1560             __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
1561             }
1562              
1563             template
1564             inline __shared_ptr<_Tp, _Lp>
1565             __allocate_shared(const _Alloc& __a, _Args&&... __args)
1566             {
1567             return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
1568             std::forward<_Args>(__args)...);
1569             }
1570              
1571             template
1572             inline __shared_ptr<_Tp, _Lp>
1573             __make_shared(_Args&&... __args)
1574             {
1575             typedef typename std::remove_const<_Tp>::type _Tp_nc;
1576             return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1577             std::forward<_Args>(__args)...);
1578             }
1579              
1580             /// std::hash specialization for __shared_ptr.
1581             template
1582             struct hash<__shared_ptr<_Tp, _Lp>>
1583             : public __hash_base>
1584             {
1585             size_t
1586             operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
1587             { return std::hash<_Tp*>()(__s.get()); }
1588             };
1589              
1590             _GLIBCXX_END_NAMESPACE_VERSION
1591             } // namespace
1592              
1593             #endif // _SHARED_PTR_BASE_H