• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-armeabi-2011.09/arm-none-eabi/include/c++/4.6.1/tr1/
1// <tr1/shared_ptr.h> -*- C++ -*-
2
3// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25//  shared_count.hpp
26//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
27
28//  shared_ptr.hpp
29//  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
30//  Copyright (C) 2001, 2002, 2003 Peter Dimov
31
32//  weak_ptr.hpp
33//  Copyright (C) 2001, 2002, 2003 Peter Dimov
34
35//  enable_shared_from_this.hpp
36//  Copyright (C) 2002 Peter Dimov
37
38// Distributed under the Boost Software License, Version 1.0. (See
39// accompanying file LICENSE_1_0.txt or copy at
40// http://www.boost.org/LICENSE_1_0.txt)
41
42// GCC Note:  based on version 1.32.0 of the Boost library.
43
44/** @file tr1/shared_ptr.h
45 *  This is an internal header file, included by other library headers.
46 *  Do not attempt to use it directly. @headername{tr1/memory}
47 */
48
49#ifndef _TR1_SHARED_PTR_H
50#define _TR1_SHARED_PTR_H 1
51
52namespace std _GLIBCXX_VISIBILITY(default)
53{
54namespace tr1
55{
56_GLIBCXX_BEGIN_NAMESPACE_VERSION
57
58 /**
59   *  @brief  Exception possibly thrown by @c shared_ptr.
60   *  @ingroup exceptions
61   */
62  class bad_weak_ptr : public std::exception
63  {
64  public:
65    virtual char const*
66    what() const throw()
67    { return "tr1::bad_weak_ptr"; }
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()
113      : _M_use_count(1), _M_weak_count(1) { }
114
115      virtual
116      ~_Sp_counted_base() // nothrow
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() = 0; // nothrow
123
124      // Called when _M_weak_count drops to zero.
125      virtual void
126      _M_destroy() // nothrow
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() // nothrow
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() // nothrow
171      { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
172
173      void
174      _M_weak_release() // nothrow
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 // nothrow
194      {
195        // No memory barrier is used here so there is no synchronization
196        // with other threads.
197        return const_cast<const volatile _Atomic_word&>(_M_use_count);
198      }
199
200    private:
201      _Sp_counted_base(_Sp_counted_base const&);
202      _Sp_counted_base& operator=(_Sp_counted_base const&);
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 (!__sync_bool_compare_and_swap(&_M_use_count, __count,
250					   __count + 1));
251    }
252
253  template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
254    class _Sp_counted_base_impl
255    : public _Sp_counted_base<_Lp>
256    {
257    public:
258      // Precondition: __d(__p) must not throw.
259      _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
260      : _M_ptr(__p), _M_del(__d) { }
261
262      virtual void
263      _M_dispose() // nothrow
264      { _M_del(_M_ptr); }
265
266      virtual void*
267      _M_get_deleter(const std::type_info& __ti)
268      {
269#ifdef __GXX_RTTI
270        return __ti == typeid(_Deleter) ? &_M_del : 0;
271#else
272        return 0;
273#endif
274      }
275
276    private:
277      _Sp_counted_base_impl(const _Sp_counted_base_impl&);
278      _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
279
280      _Ptr      _M_ptr;  // copy constructor must not throw
281      _Deleter  _M_del;  // copy constructor must not throw
282    };
283
284  template<_Lock_policy _Lp = __default_lock_policy>
285    class __weak_count;
286
287  template<typename _Tp>
288    struct _Sp_deleter
289    {
290      typedef void result_type;
291      typedef _Tp* argument_type;
292      void operator()(_Tp* __p) const { delete __p; }
293    };
294
295  template<_Lock_policy _Lp = __default_lock_policy>
296    class __shared_count
297    {
298    public:
299      __shared_count()
300      : _M_pi(0) // nothrow
301      { }
302
303      template<typename _Ptr>
304        __shared_count(_Ptr __p) : _M_pi(0)
305        {
306	  __try
307	    {
308	      typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
309	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
310	          __p, _Sp_deleter<_Tp>());
311	    }
312	  __catch(...)
313	    {
314	      delete __p;
315	      __throw_exception_again;
316	    }
317	}
318
319      template<typename _Ptr, typename _Deleter>
320        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
321        {
322	  __try
323	    {
324	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
325	    }
326	  __catch(...)
327	    {
328	      __d(__p); // Call _Deleter on __p.
329	      __throw_exception_again;
330	    }
331	}
332
333      // Special case for auto_ptr<_Tp> to provide the strong guarantee.
334      template<typename _Tp>
335        explicit
336        __shared_count(std::auto_ptr<_Tp>& __r)
337	: _M_pi(new _Sp_counted_base_impl<_Tp*,
338		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
339        { __r.release(); }
340
341      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
342      explicit
343      __shared_count(const __weak_count<_Lp>& __r);
344
345      ~__shared_count() // nothrow
346      {
347	if (_M_pi != 0)
348	  _M_pi->_M_release();
349      }
350
351      __shared_count(const __shared_count& __r)
352      : _M_pi(__r._M_pi) // nothrow
353      {
354	if (_M_pi != 0)
355	  _M_pi->_M_add_ref_copy();
356      }
357
358      __shared_count&
359      operator=(const __shared_count& __r) // nothrow
360      {
361	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
362	if (__tmp != _M_pi)
363	  {
364	    if (__tmp != 0)
365	      __tmp->_M_add_ref_copy();
366	    if (_M_pi != 0)
367	      _M_pi->_M_release();
368	    _M_pi = __tmp;
369	  }
370	return *this;
371      }
372
373      void
374      _M_swap(__shared_count& __r) // nothrow
375      {
376	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
377	__r._M_pi = _M_pi;
378	_M_pi = __tmp;
379      }
380
381      long
382      _M_get_use_count() const // nothrow
383      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
384
385      bool
386      _M_unique() const // nothrow
387      { return this->_M_get_use_count() == 1; }
388
389      friend inline bool
390      operator==(const __shared_count& __a, const __shared_count& __b)
391      { return __a._M_pi == __b._M_pi; }
392
393      friend inline bool
394      operator<(const __shared_count& __a, const __shared_count& __b)
395      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
396
397      void*
398      _M_get_deleter(const std::type_info& __ti) const
399      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
400
401    private:
402      friend class __weak_count<_Lp>;
403
404      _Sp_counted_base<_Lp>*  _M_pi;
405    };
406
407
408  template<_Lock_policy _Lp>
409    class __weak_count
410    {
411    public:
412      __weak_count()
413      : _M_pi(0) // nothrow
414      { }
415
416      __weak_count(const __shared_count<_Lp>& __r)
417      : _M_pi(__r._M_pi) // nothrow
418      {
419	if (_M_pi != 0)
420	  _M_pi->_M_weak_add_ref();
421      }
422
423      __weak_count(const __weak_count<_Lp>& __r)
424      : _M_pi(__r._M_pi) // nothrow
425      {
426	if (_M_pi != 0)
427	  _M_pi->_M_weak_add_ref();
428      }
429
430      ~__weak_count() // nothrow
431      {
432	if (_M_pi != 0)
433	  _M_pi->_M_weak_release();
434      }
435
436      __weak_count<_Lp>&
437      operator=(const __shared_count<_Lp>& __r) // nothrow
438      {
439	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
440	if (__tmp != 0)
441	  __tmp->_M_weak_add_ref();
442	if (_M_pi != 0)
443	  _M_pi->_M_weak_release();
444	_M_pi = __tmp;
445	return *this;
446      }
447
448      __weak_count<_Lp>&
449      operator=(const __weak_count<_Lp>& __r) // nothrow
450      {
451	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
452	if (__tmp != 0)
453	  __tmp->_M_weak_add_ref();
454	if (_M_pi != 0)
455	  _M_pi->_M_weak_release();
456	_M_pi = __tmp;
457	return *this;
458      }
459
460      void
461      _M_swap(__weak_count<_Lp>& __r) // nothrow
462      {
463	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
464	__r._M_pi = _M_pi;
465	_M_pi = __tmp;
466      }
467
468      long
469      _M_get_use_count() const // nothrow
470      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
471
472      friend inline bool
473      operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
474      { return __a._M_pi == __b._M_pi; }
475
476      friend inline bool
477      operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
478      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
479
480    private:
481      friend class __shared_count<_Lp>;
482
483      _Sp_counted_base<_Lp>*  _M_pi;
484    };
485
486  // now that __weak_count is defined we can define this constructor:
487  template<_Lock_policy _Lp>
488    inline
489    __shared_count<_Lp>::
490    __shared_count(const __weak_count<_Lp>& __r)
491    : _M_pi(__r._M_pi)
492    {
493      if (_M_pi != 0)
494	_M_pi->_M_add_ref_lock();
495      else
496	__throw_bad_weak_ptr();
497    }
498
499  // Forward declarations.
500  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
501    class __shared_ptr;
502
503  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
504    class __weak_ptr;
505
506  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
507    class __enable_shared_from_this;
508
509  template<typename _Tp>
510    class shared_ptr;
511
512  template<typename _Tp>
513    class weak_ptr;
514
515  template<typename _Tp>
516    class enable_shared_from_this;
517
518  // Support for enable_shared_from_this.
519
520  // Friend of __enable_shared_from_this.
521  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
522    void
523    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
524				     const __enable_shared_from_this<_Tp1,
525				     _Lp>*, const _Tp2*);
526
527  // Friend of enable_shared_from_this.
528  template<typename _Tp1, typename _Tp2>
529    void
530    __enable_shared_from_this_helper(const __shared_count<>&,
531				     const enable_shared_from_this<_Tp1>*,
532				     const _Tp2*);
533
534  template<_Lock_policy _Lp>
535    inline void
536    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
537    { }
538
539
540  struct __static_cast_tag { };
541  struct __const_cast_tag { };
542  struct __dynamic_cast_tag { };
543
544  // A smart pointer with reference-counted copy semantics.  The
545  // object pointed to is deleted when the last shared_ptr pointing to
546  // it is destroyed or reset.
547  template<typename _Tp, _Lock_policy _Lp>
548    class __shared_ptr
549    {
550    public:
551      typedef _Tp   element_type;
552
553      __shared_ptr()
554      : _M_ptr(0), _M_refcount() // never throws
555      { }
556
557      template<typename _Tp1>
558        explicit
559        __shared_ptr(_Tp1* __p)
560	: _M_ptr(__p), _M_refcount(__p)
561        {
562	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
563	  typedef int _IsComplete[sizeof(_Tp1)];
564	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
565	}
566
567      template<typename _Tp1, typename _Deleter>
568        __shared_ptr(_Tp1* __p, _Deleter __d)
569        : _M_ptr(__p), _M_refcount(__p, __d)
570        {
571	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
572	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
573	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
574	}
575
576      //  generated copy constructor, assignment, destructor are fine.
577
578      template<typename _Tp1>
579        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
580	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
581        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
582
583      template<typename _Tp1>
584        explicit
585        __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
586	: _M_refcount(__r._M_refcount) // may throw
587        {
588	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
589	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
590	  // did not throw.
591	  _M_ptr = __r._M_ptr;
592	}
593
594#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
595      // Postcondition: use_count() == 1 and __r.get() == 0
596      template<typename _Tp1>
597        explicit
598        __shared_ptr(std::auto_ptr<_Tp1>& __r)
599	: _M_ptr(__r.get()), _M_refcount()
600        { // TODO requries delete __r.release() well-formed
601	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
602	  typedef int _IsComplete[sizeof(_Tp1)];
603	  _Tp1* __tmp = __r.get();
604	  _M_refcount = __shared_count<_Lp>(__r);
605	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
606	}
607
608#endif
609
610      template<typename _Tp1>
611        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
612	: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
613	  _M_refcount(__r._M_refcount)
614        { }
615
616      template<typename _Tp1>
617        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
618	: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
619	  _M_refcount(__r._M_refcount)
620        { }
621
622      template<typename _Tp1>
623        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
624	: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
625	  _M_refcount(__r._M_refcount)
626        {
627	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
628	    _M_refcount = __shared_count<_Lp>();
629	}
630
631      template<typename _Tp1>
632        __shared_ptr&
633        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
634        {
635	  _M_ptr = __r._M_ptr;
636	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
637	  return *this;
638	}
639
640#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
641      template<typename _Tp1>
642        __shared_ptr&
643        operator=(std::auto_ptr<_Tp1>& __r)
644        {
645	  __shared_ptr(__r).swap(*this);
646	  return *this;
647	}
648#endif
649
650      void
651      reset() // never throws
652      { __shared_ptr().swap(*this); }
653
654      template<typename _Tp1>
655        void
656        reset(_Tp1* __p) // _Tp1 must be complete.
657        {
658	  // Catch self-reset errors.
659	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
660	  __shared_ptr(__p).swap(*this);
661	}
662
663      template<typename _Tp1, typename _Deleter>
664        void
665        reset(_Tp1* __p, _Deleter __d)
666        { __shared_ptr(__p, __d).swap(*this); }
667
668      // Allow class instantiation when _Tp is [cv-qual] void.
669      typename std::tr1::add_reference<_Tp>::type
670      operator*() const // never throws
671      {
672	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
673	return *_M_ptr;
674      }
675
676      _Tp*
677      operator->() const // never throws
678      {
679	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
680	return _M_ptr;
681      }
682
683      _Tp*
684      get() const // never throws
685      { return _M_ptr; }
686
687      // Implicit conversion to "bool"
688    private:
689      typedef _Tp* __shared_ptr::*__unspecified_bool_type;
690
691    public:
692      operator __unspecified_bool_type() const // never throws
693      { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
694
695      bool
696      unique() const // never throws
697      { return _M_refcount._M_unique(); }
698
699      long
700      use_count() const // never throws
701      { return _M_refcount._M_get_use_count(); }
702
703      void
704      swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
705      {
706	std::swap(_M_ptr, __other._M_ptr);
707	_M_refcount._M_swap(__other._M_refcount);
708      }
709
710    private:
711      void*
712      _M_get_deleter(const std::type_info& __ti) const
713      { return _M_refcount._M_get_deleter(__ti); }
714
715      template<typename _Tp1, _Lock_policy _Lp1>
716        bool
717        _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
718        { return _M_refcount < __rhs._M_refcount; }
719
720      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
721      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
722
723      template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
724        friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
725
726      // Friends injected into enclosing namespace and found by ADL:
727      template<typename _Tp1>
728        friend inline bool
729        operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
730        { return __a.get() == __b.get(); }
731
732      template<typename _Tp1>
733        friend inline bool
734        operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
735        { return __a.get() != __b.get(); }
736
737      template<typename _Tp1>
738        friend inline bool
739        operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
740        { return __a._M_less(__b); }
741
742      _Tp*         	   _M_ptr;         // Contained pointer.
743      __shared_count<_Lp>  _M_refcount;    // Reference counter.
744    };
745
746  // 2.2.3.8 shared_ptr specialized algorithms.
747  template<typename _Tp, _Lock_policy _Lp>
748    inline void
749    swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
750    { __a.swap(__b); }
751
752  // 2.2.3.9 shared_ptr casts
753  /*  The seemingly equivalent
754   *           shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
755   *  will eventually result in undefined behaviour,
756   *  attempting to delete the same object twice.
757   */
758  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
759    inline __shared_ptr<_Tp, _Lp>
760    static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
761    { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
762
763  /*  The seemingly equivalent
764   *           shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
765   *  will eventually result in undefined behaviour,
766   *  attempting to delete the same object twice.
767   */
768  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
769    inline __shared_ptr<_Tp, _Lp>
770    const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
771    { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
772
773  /*  The seemingly equivalent
774   *           shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
775   *  will eventually result in undefined behaviour,
776   *  attempting to delete the same object twice.
777   */
778  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
779    inline __shared_ptr<_Tp, _Lp>
780    dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
781    { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
782
783  // 2.2.3.7 shared_ptr I/O
784  template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
785    std::basic_ostream<_Ch, _Tr>&
786    operator<<(std::basic_ostream<_Ch, _Tr>& __os,
787	       const __shared_ptr<_Tp, _Lp>& __p)
788    {
789      __os << __p.get();
790      return __os;
791    }
792
793  // 2.2.3.10 shared_ptr get_deleter (experimental)
794  template<typename _Del, typename _Tp, _Lock_policy _Lp>
795    inline _Del*
796    get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
797    {
798#ifdef __GXX_RTTI
799      return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
800#else
801      return 0;
802#endif
803    }
804
805
806  template<typename _Tp, _Lock_policy _Lp>
807    class __weak_ptr
808    {
809    public:
810      typedef _Tp element_type;
811
812      __weak_ptr()
813      : _M_ptr(0), _M_refcount() // never throws
814      { }
815
816      // Generated copy constructor, assignment, destructor are fine.
817
818      // The "obvious" converting constructor implementation:
819      //
820      //  template<typename _Tp1>
821      //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
822      //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
823      //    { }
824      //
825      // has a serious problem.
826      //
827      //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
828      //  conversion may require access to *__r._M_ptr (virtual inheritance).
829      //
830      // It is not possible to avoid spurious access violations since
831      // in multithreaded programs __r._M_ptr may be invalidated at any point.
832      template<typename _Tp1>
833        __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
834	: _M_refcount(__r._M_refcount) // never throws
835        {
836	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
837	  _M_ptr = __r.lock().get();
838	}
839
840      template<typename _Tp1>
841        __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
842	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
843        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
844
845      template<typename _Tp1>
846        __weak_ptr&
847        operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
848        {
849	  _M_ptr = __r.lock().get();
850	  _M_refcount = __r._M_refcount;
851	  return *this;
852	}
853
854      template<typename _Tp1>
855        __weak_ptr&
856        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
857        {
858	  _M_ptr = __r._M_ptr;
859	  _M_refcount = __r._M_refcount;
860	  return *this;
861	}
862
863      __shared_ptr<_Tp, _Lp>
864      lock() const // never throws
865      {
866#ifdef __GTHREADS
867	// Optimization: avoid throw overhead.
868	if (expired())
869	  return __shared_ptr<element_type, _Lp>();
870
871	__try
872	  {
873	    return __shared_ptr<element_type, _Lp>(*this);
874	  }
875	__catch(const bad_weak_ptr&)
876	  {
877	    // Q: How can we get here?
878	    // A: Another thread may have invalidated r after the
879	    //    use_count test above.
880	    return __shared_ptr<element_type, _Lp>();
881	  }
882
883#else
884	// Optimization: avoid try/catch overhead when single threaded.
885	return expired() ? __shared_ptr<element_type, _Lp>()
886	                 : __shared_ptr<element_type, _Lp>(*this);
887
888#endif
889      } // XXX MT
890
891      long
892      use_count() const // never throws
893      { return _M_refcount._M_get_use_count(); }
894
895      bool
896      expired() const // never throws
897      { return _M_refcount._M_get_use_count() == 0; }
898
899      void
900      reset() // never throws
901      { __weak_ptr().swap(*this); }
902
903      void
904      swap(__weak_ptr& __s) // never throws
905      {
906	std::swap(_M_ptr, __s._M_ptr);
907	_M_refcount._M_swap(__s._M_refcount);
908      }
909
910    private:
911      // Used by __enable_shared_from_this.
912      void
913      _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
914      {
915	_M_ptr = __ptr;
916	_M_refcount = __refcount;
917      }
918
919      template<typename _Tp1>
920        bool
921        _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
922        { return _M_refcount < __rhs._M_refcount; }
923
924      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
925      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
926      friend class __enable_shared_from_this<_Tp, _Lp>;
927      friend class enable_shared_from_this<_Tp>;
928
929      // Friend injected into namespace and found by ADL.
930      template<typename _Tp1>
931        friend inline bool
932        operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
933        { return __lhs._M_less(__rhs); }
934
935      _Tp*       	 _M_ptr;         // Contained pointer.
936      __weak_count<_Lp>  _M_refcount;    // Reference counter.
937    };
938
939  // 2.2.4.7 weak_ptr specialized algorithms.
940  template<typename _Tp, _Lock_policy _Lp>
941    inline void
942    swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
943    { __a.swap(__b); }
944
945
946  template<typename _Tp, _Lock_policy _Lp>
947    class __enable_shared_from_this
948    {
949    protected:
950      __enable_shared_from_this() { }
951
952      __enable_shared_from_this(const __enable_shared_from_this&) { }
953
954      __enable_shared_from_this&
955      operator=(const __enable_shared_from_this&)
956      { return *this; }
957
958      ~__enable_shared_from_this() { }
959
960    public:
961      __shared_ptr<_Tp, _Lp>
962      shared_from_this()
963      { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
964
965      __shared_ptr<const _Tp, _Lp>
966      shared_from_this() const
967      { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
968
969    private:
970      template<typename _Tp1>
971        void
972        _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
973        { _M_weak_this._M_assign(__p, __n); }
974
975      template<typename _Tp1>
976        friend void
977        __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
978					 const __enable_shared_from_this* __pe,
979					 const _Tp1* __px)
980        {
981	  if (__pe != 0)
982	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
983	}
984
985      mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
986    };
987
988
989  // The actual shared_ptr, with forwarding constructors and
990  // assignment operators.
991  template<typename _Tp>
992    class shared_ptr
993    : public __shared_ptr<_Tp>
994    {
995    public:
996      shared_ptr()
997      : __shared_ptr<_Tp>() { }
998
999      template<typename _Tp1>
1000        explicit
1001        shared_ptr(_Tp1* __p)
1002	: __shared_ptr<_Tp>(__p) { }
1003
1004      template<typename _Tp1, typename _Deleter>
1005        shared_ptr(_Tp1* __p, _Deleter __d)
1006	: __shared_ptr<_Tp>(__p, __d) { }
1007
1008      template<typename _Tp1>
1009        shared_ptr(const shared_ptr<_Tp1>& __r)
1010	: __shared_ptr<_Tp>(__r) { }
1011
1012      template<typename _Tp1>
1013        explicit
1014        shared_ptr(const weak_ptr<_Tp1>& __r)
1015	: __shared_ptr<_Tp>(__r) { }
1016
1017#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
1018      template<typename _Tp1>
1019        explicit
1020        shared_ptr(std::auto_ptr<_Tp1>& __r)
1021	: __shared_ptr<_Tp>(__r) { }
1022#endif
1023
1024      template<typename _Tp1>
1025        shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1026	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1027
1028      template<typename _Tp1>
1029        shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1030	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1031
1032      template<typename _Tp1>
1033        shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1034	: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1035
1036      template<typename _Tp1>
1037        shared_ptr&
1038        operator=(const shared_ptr<_Tp1>& __r) // never throws
1039        {
1040	  this->__shared_ptr<_Tp>::operator=(__r);
1041	  return *this;
1042	}
1043
1044#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
1045      template<typename _Tp1>
1046        shared_ptr&
1047        operator=(std::auto_ptr<_Tp1>& __r)
1048        {
1049	  this->__shared_ptr<_Tp>::operator=(__r);
1050	  return *this;
1051	}
1052#endif
1053    };
1054
1055  // 2.2.3.8 shared_ptr specialized algorithms.
1056  template<typename _Tp>
1057    inline void
1058    swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
1059    { __a.swap(__b); }
1060
1061  template<typename _Tp, typename _Tp1>
1062    inline shared_ptr<_Tp>
1063    static_pointer_cast(const shared_ptr<_Tp1>& __r)
1064    { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1065
1066  template<typename _Tp, typename _Tp1>
1067    inline shared_ptr<_Tp>
1068    const_pointer_cast(const shared_ptr<_Tp1>& __r)
1069    { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1070
1071  template<typename _Tp, typename _Tp1>
1072    inline shared_ptr<_Tp>
1073    dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1074    { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1075
1076
1077  // The actual weak_ptr, with forwarding constructors and
1078  // assignment operators.
1079  template<typename _Tp>
1080    class weak_ptr
1081    : public __weak_ptr<_Tp>
1082    {
1083    public:
1084      weak_ptr()
1085      : __weak_ptr<_Tp>() { }
1086
1087      template<typename _Tp1>
1088        weak_ptr(const weak_ptr<_Tp1>& __r)
1089	: __weak_ptr<_Tp>(__r) { }
1090
1091      template<typename _Tp1>
1092        weak_ptr(const shared_ptr<_Tp1>& __r)
1093	: __weak_ptr<_Tp>(__r) { }
1094
1095      template<typename _Tp1>
1096        weak_ptr&
1097        operator=(const weak_ptr<_Tp1>& __r) // never throws
1098        {
1099	  this->__weak_ptr<_Tp>::operator=(__r);
1100	  return *this;
1101	}
1102
1103      template<typename _Tp1>
1104        weak_ptr&
1105        operator=(const shared_ptr<_Tp1>& __r) // never throws
1106        {
1107	  this->__weak_ptr<_Tp>::operator=(__r);
1108	  return *this;
1109	}
1110
1111      shared_ptr<_Tp>
1112      lock() const // never throws
1113      {
1114#ifdef __GTHREADS
1115	if (this->expired())
1116	  return shared_ptr<_Tp>();
1117
1118	__try
1119	  {
1120	    return shared_ptr<_Tp>(*this);
1121	  }
1122	__catch(const bad_weak_ptr&)
1123	  {
1124	    return shared_ptr<_Tp>();
1125	  }
1126#else
1127	return this->expired() ? shared_ptr<_Tp>()
1128	                       : shared_ptr<_Tp>(*this);
1129#endif
1130      }
1131    };
1132
1133  template<typename _Tp>
1134    class enable_shared_from_this
1135    {
1136    protected:
1137      enable_shared_from_this() { }
1138
1139      enable_shared_from_this(const enable_shared_from_this&) { }
1140
1141      enable_shared_from_this&
1142      operator=(const enable_shared_from_this&)
1143      { return *this; }
1144
1145      ~enable_shared_from_this() { }
1146
1147    public:
1148      shared_ptr<_Tp>
1149      shared_from_this()
1150      { return shared_ptr<_Tp>(this->_M_weak_this); }
1151
1152      shared_ptr<const _Tp>
1153      shared_from_this() const
1154      { return shared_ptr<const _Tp>(this->_M_weak_this); }
1155
1156    private:
1157      template<typename _Tp1>
1158        void
1159        _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1160        { _M_weak_this._M_assign(__p, __n); }
1161
1162      template<typename _Tp1>
1163        friend void
1164        __enable_shared_from_this_helper(const __shared_count<>& __pn,
1165					 const enable_shared_from_this* __pe,
1166					 const _Tp1* __px)
1167        {
1168	  if (__pe != 0)
1169	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1170	}
1171
1172      mutable weak_ptr<_Tp>  _M_weak_this;
1173    };
1174
1175_GLIBCXX_END_NAMESPACE_VERSION
1176}
1177}
1178
1179#endif // _TR1_SHARED_PTR_H
1180