OSDN Git Service

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