1 // <tr1/boost_shared_ptr.h> -*- C++ -*-
3 // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
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 2, or (at your option)
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
34 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
35 // Copyright (C) 2001, 2002, 2003 Peter Dimov
38 // Copyright (C) 2001, 2002, 2003 Peter Dimov
40 // enable_shared_from_this.hpp
41 // Copyright (C) 2002 Peter Dimov
43 // Distributed under the Boost Software License, Version 1.0. (See
44 // accompanying file LICENSE_1_0.txt or copy at
45 // http://www.boost.org/LICENSE_1_0.txt)
47 // GCC Note: based on version 1.32.0 of the Boost library.
49 /** @file boost_memory.h
50 * This is an internal header file, included by other library headers.
51 * You should not attempt to use it directly.
54 #ifndef _BOOST_SHARED_PTR_H
55 #define _BOOST_SHARED_PTR_H 1
59 _GLIBCXX_BEGIN_NAMESPACE(tr1)
61 class bad_weak_ptr : public std::exception
66 { return "tr1::bad_weak_ptr"; }
69 // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
71 __throw_bad_weak_ptr()
80 using __gnu_cxx::_Lock_policy;
81 using __gnu_cxx::__default_lock_policy;
82 using __gnu_cxx::_S_single;
83 using __gnu_cxx::_S_mutex;
84 using __gnu_cxx::_S_atomic;
86 template<typename _Tp>
89 typedef void result_type;
90 typedef _Tp* argument_type;
93 operator()(_Tp* __p) const
97 // Empty helper class except when the template argument is _S_mutex.
98 template<_Lock_policy _Lp>
103 class _Mutex_base<_S_mutex> : public __gnu_cxx::__mutex
106 template<_Lock_policy _Lp = __default_lock_policy>
107 class _Sp_counted_base : public _Mutex_base<_Lp>
110 _Sp_counted_base() : _M_use_count(1), _M_weak_count(1) { }
113 ~_Sp_counted_base() // nothrow
116 // Called when _M_use_count drops to zero, to release the resources
119 dispose() = 0; // nothrow
121 // Called when _M_weak_count drops to zero.
127 get_deleter(const std::type_info&) = 0;
131 { __gnu_cxx::__atomic_add(&_M_use_count, 1); }
139 if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1)
143 _GLIBCXX_READ_MEM_BARRIER;
144 _GLIBCXX_WRITE_MEM_BARRIER;
146 if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
152 weak_add_ref() // nothrow
153 { __gnu_cxx::__atomic_add(&_M_weak_count, 1); }
156 weak_release() // nothrow
158 if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
161 _GLIBCXX_READ_MEM_BARRIER;
162 _GLIBCXX_WRITE_MEM_BARRIER;
169 use_count() const // nothrow
170 { return _M_use_count; } // XXX is this MT safe?
173 _Sp_counted_base(_Sp_counted_base const&);
174 _Sp_counted_base& operator=(_Sp_counted_base const&);
176 _Atomic_word _M_use_count; // #shared
177 _Atomic_word _M_weak_count; // #weak + (#shared != 0)
182 _Sp_counted_base<_S_single>::add_ref_lock()
184 if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0)
187 __throw_bad_weak_ptr();
194 _Sp_counted_base<_S_mutex>::add_ref_lock()
196 __gnu_cxx::__scoped_lock sentry(*this);
197 if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0)
200 __throw_bad_weak_ptr();
207 _Sp_counted_base<_S_atomic>::add_ref_lock()
209 // Perform lock-free add-if-not-zero operation.
210 _Atomic_word __count;
213 __count = _M_use_count;
215 __throw_bad_weak_ptr();
217 // Replace the current counter value with the old value + 1, as
218 // long as it's not changed meanwhile.
220 while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
224 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
225 class _Sp_counted_base_impl : public _Sp_counted_base<_Lp>
230 * @pre d(p) must not throw.
232 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
233 : _M_ptr(__p), _M_del(__d) { }
240 get_deleter(const std::type_info& __ti)
241 { return __ti == typeid(_Deleter) ? &_M_del : 0; }
244 _Sp_counted_base_impl(const _Sp_counted_base_impl&);
245 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
247 _Ptr _M_ptr; // copy constructor must not throw
248 _Deleter _M_del; // copy constructor must not throw
251 template<_Lock_policy _Lp = __default_lock_policy>
254 template<_Lock_policy _Lp = __default_lock_policy>
258 _Sp_counted_base<_Lp>* _M_pi;
260 friend class weak_count<_Lp>;
263 shared_count() : _M_pi(0) // nothrow
266 template<typename _Ptr, typename _Deleter>
267 shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
271 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
275 __d(__p); // Call _Deleter on __p.
276 __throw_exception_again;
280 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
281 template<typename _Tp>
283 shared_count(std::auto_ptr<_Tp>& __r)
284 : _M_pi(new _Sp_counted_base_impl<_Tp*,
285 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
288 // Throw bad_weak_ptr when __r.use_count() == 0.
289 explicit shared_count(const weak_count<_Lp>& __r);
291 ~shared_count() // nothrow
297 shared_count(const shared_count& __r)
298 : _M_pi(__r._M_pi) // nothrow
301 _M_pi->add_ref_copy();
305 operator=(const shared_count& __r) // nothrow
307 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
311 __tmp->add_ref_copy();
320 swap(shared_count& __r) // nothrow
322 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
328 use_count() const // nothrow
329 { return _M_pi != 0 ? _M_pi->use_count() : 0; }
332 unique() const // nothrow
333 { return this->use_count() == 1; }
336 operator==(const shared_count& __a, const shared_count& __b)
337 { return __a._M_pi == __b._M_pi; }
340 operator<(const shared_count& __a, const shared_count& __b)
341 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
344 get_deleter(const std::type_info& __ti) const
345 { return _M_pi ? _M_pi->get_deleter(__ti) : 0; }
348 template<_Lock_policy _Lp>
352 _Sp_counted_base<_Lp>* _M_pi;
354 friend class shared_count<_Lp>;
358 : _M_pi(0) // nothrow
361 weak_count(const shared_count<_Lp>& __r)
362 : _M_pi(__r._M_pi) // nothrow
365 _M_pi->weak_add_ref();
368 weak_count(const weak_count<_Lp>& __r)
369 : _M_pi(__r._M_pi) // nothrow
372 _M_pi->weak_add_ref();
375 ~weak_count() // nothrow
378 _M_pi->weak_release();
382 operator=(const shared_count<_Lp>& __r) // nothrow
384 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
386 __tmp->weak_add_ref();
388 _M_pi->weak_release();
394 operator=(const weak_count<_Lp>& __r) // nothrow
396 _Sp_counted_base<_Lp> * __tmp = __r._M_pi;
398 __tmp->weak_add_ref();
400 _M_pi->weak_release();
406 swap(weak_count<_Lp>& __r) // nothrow
408 _Sp_counted_base<_Lp> * __tmp = __r._M_pi;
414 use_count() const // nothrow
415 { return _M_pi != 0 ? _M_pi->use_count() : 0; }
418 operator==(const weak_count<_Lp>& __a, const weak_count<_Lp>& __b)
419 { return __a._M_pi == __b._M_pi; }
422 operator<(const weak_count<_Lp>& __a, const weak_count<_Lp>& __b)
423 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
426 template<_Lock_policy _Lp>
429 shared_count(const weak_count<_Lp>& __r)
433 _M_pi->add_ref_lock();
435 __throw_bad_weak_ptr();
440 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
443 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
446 template<typename _Tp, _Lock_policy _Lp>
447 class __enable_shared_from_this;
449 struct __static_cast_tag { };
450 struct __const_cast_tag { };
451 struct __dynamic_cast_tag { };
452 struct __polymorphic_cast_tag { };
455 // Support for enable_shared_from_this.
457 // Friend of __enable_shared_from_this.
458 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
460 __enable_shared_from_this_helper(const shared_count<_Lp>&,
461 const __enable_shared_from_this<_Tp1,
464 template<_Lock_policy _Lp>
466 __enable_shared_from_this_helper(const shared_count<_Lp>&, ...)
471 * @class shared_ptr <tr1/memory>
473 * A smart pointer with reference-counted copy semantics.
474 * The object pointed to is deleted when the last shared_ptr pointing to
475 * it is destroyed or reset.
477 template<typename _Tp, _Lock_policy _Lp>
481 typedef _Tp element_type;
483 /** @brief Construct an empty %__shared_ptr.
484 * @post use_count()==0 && get()==0
487 : _M_ptr(0), _M_refcount() // never throws
490 /** @brief Construct a %__shared_ptr that owns the pointer @a p.
491 * @param p A pointer that is convertible to element_type*.
492 * @post use_count() == 1 && get() == p
493 * @throw std::bad_alloc, in which case @c delete @a p is called.
495 template<typename _Tp1>
497 __shared_ptr(_Tp1* __p)
498 : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
500 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
501 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
502 __enable_shared_from_this_helper( _M_refcount, __p, __p );
506 // Requirements: D's copy constructor and destructor must not throw
508 // __shared_ptr will release p by calling d(p)
510 /** @brief Construct a %__shared_ptr that owns the pointer @a p
511 * and the deleter @a d.
512 * @param p A pointer.
513 * @param d A deleter.
514 * @post use_count() == 1 && get() == p
515 * @throw std::bad_alloc, in which case @a d(p) is called.
517 template<typename _Tp1, typename _Deleter>
518 __shared_ptr(_Tp1* __p, _Deleter __d)
519 : _M_ptr(__p), _M_refcount(__p, __d)
521 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
522 // TODO requires D is CopyConstructible and d(p) well-formed
523 __enable_shared_from_this_helper( _M_refcount, __p, __p );
526 // generated copy constructor, assignment, destructor are fine.
528 /** @brief If @a r is empty, constructs an empty %__shared_ptr;
529 * otherwise construct a %__shared_ptr that shares ownership
531 * @param r A %__shared_ptr.
532 * @post get() == r.get() && use_count() == r.use_count()
533 * @throw std::bad_alloc, in which case
535 template<typename _Tp1>
536 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
537 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
538 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
540 /** @brief Constructs a %__shared_ptr that shares ownership with @a r
541 * and stores a copy of the pointer stored in @a r.
542 * @param r A weak_ptr.
543 * @post use_count() == r.use_count()
544 * @throw bad_weak_ptr when r.expired(),
545 * in which case the constructor has no effect.
547 template<typename _Tp1>
549 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
550 : _M_refcount(__r._M_refcount) // may throw
552 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
553 // It is now safe to copy r__._M_ptr, as _M_refcount(__r._M_refcount)
559 * @post use_count() == 1 and r.get() == 0
561 template<typename _Tp1>
563 __shared_ptr(std::auto_ptr<_Tp1>& __r)
564 : _M_ptr(__r.get()), _M_refcount()
566 // TODO requires r.release() convertible to _Tp*, Tp1 is complete,
567 // delete r.release() well-formed
568 _Tp1 * __tmp = __r.get();
569 _M_refcount = shared_count<_Lp>(__r);
570 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp );
573 template<typename _Tp1>
574 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
575 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
576 _M_refcount(__r._M_refcount)
579 template<typename _Tp1>
580 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
581 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
582 _M_refcount(__r._M_refcount)
585 template<typename _Tp1>
586 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
587 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
588 _M_refcount(__r._M_refcount)
590 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
591 _M_refcount = shared_count<_Lp>();
594 template<typename _Tp1>
596 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
599 _M_refcount = __r._M_refcount; // shared_count::op= doesn't throw
603 template<typename _Tp1>
605 operator=(std::auto_ptr<_Tp1>& __r)
607 __shared_ptr(__r).swap(*this);
612 reset() // never throws
613 { __shared_ptr().swap(*this); }
615 template<typename _Tp1>
617 reset(_Tp1* __p) // _Tp1 must be complete.
619 // Catch self-reset errors.
620 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
621 __shared_ptr(__p).swap(*this);
624 template<typename _Tp1, typename _Deleter>
626 reset(_Tp1 * __p, _Deleter __d)
627 { __shared_ptr(__p, __d).swap(*this); }
629 // Allow instantiation when _Tp is [cv-qual] void.
630 typename add_reference<_Tp>::type
631 operator*() const // never throws
633 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
638 operator->() const // never throws
640 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
645 get() const // never throws
648 // Implicit conversion to "bool"
650 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
653 operator __unspecified_bool_type() const // never throws
654 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
657 unique() const // never throws
658 { return _M_refcount.unique(); }
661 use_count() const // never throws
662 { return _M_refcount.use_count(); }
665 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
667 std::swap(_M_ptr, __other._M_ptr);
668 _M_refcount.swap(__other._M_refcount);
673 _M_get_deleter(const std::type_info& __ti) const
674 { return _M_refcount.get_deleter(__ti); }
676 template<typename _Tp1, _Lock_policy _Lp1>
678 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
679 { return _M_refcount < __rhs._M_refcount; }
681 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
682 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
684 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
685 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
687 // Friends injected into enclosing namespace and found by ADL:
688 template<typename _Tp1>
690 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
691 { return __a.get() == __b.get(); }
693 template<typename _Tp1>
695 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
696 { return __a.get() != __b.get(); }
698 template<typename _Tp1>
700 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
701 { return __a._M_less(__b); }
703 _Tp* _M_ptr; // Contained pointer.
704 shared_count<_Lp> _M_refcount; // Reference counter.
707 // 2.2.3.8 shared_ptr specialized algorithms.
708 template<typename _Tp, _Lock_policy _Lp>
710 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
713 // 2.2.3.9 shared_ptr casts
714 /** @warning The seemingly equivalent
715 * <code>shared_ptr<T>(static_cast<T*>(r.get()))</code>
716 * will eventually result in undefined behaviour,
717 * attempting to delete the same object twice.
719 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
720 __shared_ptr<_Tp, _Lp>
721 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
722 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
724 /** @warning The seemingly equivalent
725 * <code>shared_ptr<T>(const_cast<T*>(r.get()))</code>
726 * will eventually result in undefined behaviour,
727 * attempting to delete the same object twice.
729 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
730 __shared_ptr<_Tp, _Lp>
731 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
732 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
734 /** @warning The seemingly equivalent
735 * <code>shared_ptr<T>(dynamic_cast<T*>(r.get()))</code>
736 * will eventually result in undefined behaviour,
737 * attempting to delete the same object twice.
739 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
740 __shared_ptr<_Tp, _Lp>
741 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
742 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
744 // 2.2.3.7 shared_ptr I/O
745 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
746 std::basic_ostream<_Ch, _Tr>&
747 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
748 const __shared_ptr<_Tp, _Lp>& __p)
754 // 2.2.3.10 shared_ptr get_deleter (experimental)
755 template<typename _Del, typename _Tp, _Lock_policy _Lp>
757 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
758 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
761 template<typename _Tp, _Lock_policy _Lp>
765 typedef _Tp element_type;
767 __weak_ptr() : _M_ptr(0), _M_refcount() // never throws
770 // Generated copy constructor, assignment, destructor are fine.
772 // The "obvious" converting constructor implementation:
775 // __weak_ptr(__weak_ptr<Y> const & r)
776 // : _M_ptr(r._M_ptr), _M_refcount(r._M_refcount) // never throws
779 // has a serious problem.
781 // r._M_ptr may already have been invalidated. The _M_ptr(r._M_ptr)
782 // conversion may require access to *r._M_ptr (virtual inheritance).
784 // It is not possible to avoid spurious access violations since
785 // in multithreaded programs r._M_ptr may be invalidated at any point.
786 template<typename _Tp1>
787 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
788 : _M_refcount(__r._M_refcount) // never throws
790 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
791 _M_ptr = __r.lock().get();
794 template<typename _Tp1>
795 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
796 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
797 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
799 template<typename _Tp1>
801 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
803 _M_ptr = __r.lock().get();
804 _M_refcount = __r._M_refcount;
808 template<typename _Tp1>
810 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
813 _M_refcount = __r._M_refcount;
817 __shared_ptr<_Tp, _Lp>
818 lock() const // never throws
821 // Optimization: avoid throw overhead.
823 return __shared_ptr<element_type, _Lp>();
827 return __shared_ptr<element_type, _Lp>(*this);
829 catch (const bad_weak_ptr&)
831 // Q: How can we get here?
832 // A: Another thread may have invalidated r after the
833 // use_count test above.
834 return __shared_ptr<element_type>();
838 // Optimization: avoid try/catch overhead when single threaded.
839 return expired() ? __shared_ptr<element_type, _Lp>()
840 : __shared_ptr<element_type, _Lp>(*this);
846 use_count() const // never throws
847 { return _M_refcount.use_count(); }
850 expired() const // never throws
851 { return _M_refcount.use_count() == 0; }
854 reset() // never throws
855 { __weak_ptr().swap(*this); }
858 swap(__weak_ptr& __s) // never throws
860 std::swap(_M_ptr, __s._M_ptr);
861 _M_refcount.swap(__s._M_refcount);
865 template<typename _Tp1>
867 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
868 { return _M_refcount < __rhs._M_refcount; }
870 // Used by __enable_shared_from_this.
872 _M_assign(_Tp* __ptr, const shared_count<_Lp>& __refcount)
875 _M_refcount = __refcount;
878 // Friend injected into namespace and found by ADL.
879 template<typename _Tp1>
881 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
882 { return __lhs._M_less(__rhs); }
884 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
885 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
886 friend class __enable_shared_from_this<_Tp, _Lp>;
888 _Tp* _M_ptr; // Contained pointer.
889 weak_count<_Lp> _M_refcount; // Reference counter.
892 // 2.2.4.7 weak_ptr specialized algorithms.
893 template<typename _Tp, _Lock_policy _Lp>
895 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
899 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
900 class __enable_shared_from_this
903 __enable_shared_from_this() { }
905 __enable_shared_from_this(const __enable_shared_from_this&) { }
907 __enable_shared_from_this&
908 operator=(const __enable_shared_from_this&)
911 ~__enable_shared_from_this() { }
914 __shared_ptr<_Tp, _Lp>
917 __shared_ptr<_Tp, _Lp> __p(this->_M_weak_this);
921 __shared_ptr<const _Tp, _Lp>
922 shared_from_this() const
924 __shared_ptr<const _Tp, _Lp> __p(this->_M_weak_this);
929 template<typename _Tp1>
931 _M_weak_assign(_Tp1* __p, const shared_count<_Lp>& __n) const
932 { _M_weak_this._M_assign(__p, __n); }
934 template<typename _Tp1>
936 __enable_shared_from_this_helper(const shared_count<_Lp>& __pn,
937 const __enable_shared_from_this* __pe,
941 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
944 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
947 template<typename _Tp>
950 // The actual TR1 weak_ptr, with forwarding constructors and
951 // assignment operators.
952 template<typename _Tp>
953 class weak_ptr : public __weak_ptr<_Tp>
957 : __weak_ptr<_Tp>() { }
959 template<typename _Tp1>
960 weak_ptr(const __weak_ptr<_Tp1>& __r)
961 : __weak_ptr<_Tp>(__r) { }
963 template<typename _Tp1>
964 weak_ptr(const __shared_ptr<_Tp1>& __r)
965 : __weak_ptr<_Tp>(__r) { }
967 template<typename _Tp1>
969 operator=(const weak_ptr<_Tp1>& __r) // never throws
971 this->__weak_ptr<_Tp>::operator=(__r);
975 template<typename _Tp1>
977 operator=(const shared_ptr<_Tp1>& __r) // never throws
979 this->__weak_ptr<_Tp>::operator=(__r);
984 // The actual TR1 shared_ptr, with forwarding constructors and
985 // assignment operators.
986 template<typename _Tp>
987 class shared_ptr : public __shared_ptr<_Tp>
990 shared_ptr() : __shared_ptr<_Tp>() { }
992 template<typename _Tp1>
994 shared_ptr(_Tp1* __p)
995 : __shared_ptr<_Tp>(__p) { }
997 template<typename _Tp1, typename _Deleter>
998 shared_ptr(_Tp1* __p, _Deleter __d)
999 : __shared_ptr<_Tp>(__p, __d) { }
1001 template<typename _Tp1>
1002 shared_ptr(const __shared_ptr<_Tp1>& __r)
1003 : __shared_ptr<_Tp>(__r) { }
1005 template<typename _Tp1>
1007 shared_ptr(const __weak_ptr<_Tp1>& __r)
1008 : __shared_ptr<_Tp>(__r) { }
1010 template<typename _Tp1>
1012 shared_ptr(std::auto_ptr<_Tp1>& __r)
1013 : __shared_ptr<_Tp>(__r) { }
1015 template<typename _Tp1>
1016 shared_ptr(const __shared_ptr<_Tp1>& __r, __static_cast_tag)
1017 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1019 template<typename _Tp1>
1020 shared_ptr(const __shared_ptr<_Tp1>& __r, __const_cast_tag)
1021 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1023 template<typename _Tp1>
1024 shared_ptr(const __shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1025 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1027 // Additional non-base assignment operators to avoid excessive errors.
1028 template<typename _Tp1>
1030 operator=(std::auto_ptr<_Tp1>& __r)
1032 this->__shared_ptr<_Tp>::operator=(__r);
1036 template<typename _Tp1>
1038 operator=(const shared_ptr<_Tp1>& __r) // never throws
1040 this->__shared_ptr<_Tp>::operator=(__r);
1045 template<typename _Tp>
1046 class enable_shared_from_this : public __enable_shared_from_this<_Tp>
1049 enable_shared_from_this()
1050 : __enable_shared_from_this<_Tp>() { }
1052 enable_shared_from_this(const enable_shared_from_this&)
1053 : __enable_shared_from_this<_Tp>(enable_shared_from_this<_Tp>()) { }
1056 _GLIBCXX_END_NAMESPACE