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 tr1/boost_shared_ptr.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>
104 : public __gnu_cxx::__mutex
107 template<_Lock_policy _Lp = __default_lock_policy>
108 class _Sp_counted_base
109 : public _Mutex_base<_Lp>
113 : _M_use_count(1), _M_weak_count(1) { }
116 ~_Sp_counted_base() // nothrow
119 // Called when _M_use_count drops to zero, to release the resources
122 _M_dispose() = 0; // nothrow
124 // Called when _M_weak_count drops to zero.
126 _M_destroy() // nothrow
130 _M_get_deleter(const std::type_info&) = 0;
134 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
140 _M_release() // nothrow
142 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
147 _GLIBCXX_READ_MEM_BARRIER;
148 _GLIBCXX_WRITE_MEM_BARRIER;
150 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
157 _M_weak_add_ref() // nothrow
158 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
161 _M_weak_release() // nothrow
163 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
166 _GLIBCXX_READ_MEM_BARRIER;
167 _GLIBCXX_WRITE_MEM_BARRIER;
174 _M_get_use_count() const // nothrow
175 { return _M_use_count; } // XXX is this MT safe?
178 _Sp_counted_base(_Sp_counted_base const&);
179 _Sp_counted_base& operator=(_Sp_counted_base const&);
181 _Atomic_word _M_use_count; // #shared
182 _Atomic_word _M_weak_count; // #weak + (#shared != 0)
187 _Sp_counted_base<_S_single>::
190 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
193 __throw_bad_weak_ptr();
200 _Sp_counted_base<_S_mutex>::
203 __gnu_cxx::__scoped_lock sentry(*this);
204 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
207 __throw_bad_weak_ptr();
214 _Sp_counted_base<_S_atomic>::
217 // Perform lock-free add-if-not-zero operation.
218 _Atomic_word __count;
221 __count = _M_use_count;
223 __throw_bad_weak_ptr();
225 // Replace the current counter value with the old value + 1, as
226 // long as it's not changed meanwhile.
228 while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
232 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
233 class _Sp_counted_base_impl
234 : public _Sp_counted_base<_Lp>
239 * @pre __d(__p) must not throw.
241 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
242 : _M_ptr(__p), _M_del(__d) { }
245 _M_dispose() // nothrow
249 _M_get_deleter(const std::type_info& __ti)
250 { return __ti == typeid(_Deleter) ? &_M_del : 0; }
253 _Sp_counted_base_impl(const _Sp_counted_base_impl&);
254 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
256 _Ptr _M_ptr; // copy constructor must not throw
257 _Deleter _M_del; // copy constructor must not throw
260 template<_Lock_policy _Lp = __default_lock_policy>
263 template<_Lock_policy _Lp = __default_lock_policy>
268 : _M_pi(0) // nothrow
271 template<typename _Ptr, typename _Deleter>
272 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
276 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
280 __d(__p); // Call _Deleter on __p.
281 __throw_exception_again;
285 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
286 template<typename _Tp>
288 __shared_count(std::auto_ptr<_Tp>& __r)
289 : _M_pi(new _Sp_counted_base_impl<_Tp*,
290 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
293 // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
295 __shared_count(const __weak_count<_Lp>& __r);
297 ~__shared_count() // nothrow
303 __shared_count(const __shared_count& __r)
304 : _M_pi(__r._M_pi) // nothrow
307 _M_pi->_M_add_ref_copy();
311 operator=(const __shared_count& __r) // nothrow
313 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
317 __tmp->_M_add_ref_copy();
326 _M_swap(__shared_count& __r) // nothrow
328 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
334 _M_get_use_count() const // nothrow
335 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
338 _M_unique() const // nothrow
339 { return this->_M_get_use_count() == 1; }
342 operator==(const __shared_count& __a, const __shared_count& __b)
343 { return __a._M_pi == __b._M_pi; }
346 operator<(const __shared_count& __a, const __shared_count& __b)
347 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
350 _M_get_deleter(const std::type_info& __ti) const
351 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
354 friend class __weak_count<_Lp>;
356 _Sp_counted_base<_Lp>* _M_pi;
359 template<_Lock_policy _Lp>
364 : _M_pi(0) // nothrow
367 __weak_count(const __shared_count<_Lp>& __r)
368 : _M_pi(__r._M_pi) // nothrow
371 _M_pi->_M_weak_add_ref();
374 __weak_count(const __weak_count<_Lp>& __r)
375 : _M_pi(__r._M_pi) // nothrow
378 _M_pi->_M_weak_add_ref();
381 ~__weak_count() // nothrow
384 _M_pi->_M_weak_release();
388 operator=(const __shared_count<_Lp>& __r) // nothrow
390 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
392 __tmp->_M_weak_add_ref();
394 _M_pi->_M_weak_release();
400 operator=(const __weak_count<_Lp>& __r) // nothrow
402 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
404 __tmp->_M_weak_add_ref();
406 _M_pi->_M_weak_release();
412 _M_swap(__weak_count<_Lp>& __r) // nothrow
414 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
420 _M_get_use_count() const // nothrow
421 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
424 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
425 { return __a._M_pi == __b._M_pi; }
428 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
429 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
432 friend class __shared_count<_Lp>;
434 _Sp_counted_base<_Lp>* _M_pi;
437 template<_Lock_policy _Lp>
439 __shared_count<_Lp>::
440 __shared_count(const __weak_count<_Lp>& __r)
444 _M_pi->_M_add_ref_lock();
446 __throw_bad_weak_ptr();
450 // Forward declarations.
451 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
454 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
457 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
458 class __enable_shared_from_this;
460 template<typename _Tp>
463 template<typename _Tp>
466 template<typename _Tp>
467 class enable_shared_from_this;
469 // Support for enable_shared_from_this.
471 // Friend of __enable_shared_from_this.
472 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
474 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
475 const __enable_shared_from_this<_Tp1,
478 // Friend of enable_shared_from_this.
479 template<typename _Tp1, typename _Tp2>
481 __enable_shared_from_this_helper(const __shared_count<>&,
482 const enable_shared_from_this<_Tp1>*,
485 template<_Lock_policy _Lp>
487 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
491 struct __static_cast_tag { };
492 struct __const_cast_tag { };
493 struct __dynamic_cast_tag { };
496 * @class shared_ptr <tr1/memory>
498 * A smart pointer with reference-counted copy semantics.
499 * The object pointed to is deleted when the last shared_ptr pointing to
500 * it is destroyed or reset.
502 template<typename _Tp, _Lock_policy _Lp>
506 typedef _Tp element_type;
508 /** @brief Construct an empty %__shared_ptr.
509 * @post use_count()==0 && get()==0
512 : _M_ptr(0), _M_refcount() // never throws
515 /** @brief Construct a %__shared_ptr that owns the pointer @a __p.
516 * @param __p A pointer that is convertible to element_type*.
517 * @post use_count() == 1 && get() == __p
518 * @throw std::bad_alloc, in which case @c delete @a __p is called.
520 template<typename _Tp1>
522 __shared_ptr(_Tp1* __p)
523 : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
525 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
526 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
527 __enable_shared_from_this_helper(_M_refcount, __p, __p);
531 // Requirements: _Deleter' copy constructor and destructor must not throw
533 // __shared_ptr will release __p by calling __d(__p)
535 /** @brief Construct a %__shared_ptr that owns the pointer @a __p
536 * and the deleter @a __d.
537 * @param __p A pointer.
538 * @param __d A deleter.
539 * @post use_count() == 1 && get() == __p
540 * @throw std::bad_alloc, in which case @a __d(__p) is called.
542 template<typename _Tp1, typename _Deleter>
543 __shared_ptr(_Tp1* __p, _Deleter __d)
544 : _M_ptr(__p), _M_refcount(__p, __d)
546 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
547 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
548 __enable_shared_from_this_helper(_M_refcount, __p, __p);
551 // generated copy constructor, assignment, destructor are fine.
553 /** @brief If @a __r is empty, constructs an empty %__shared_ptr;
554 * otherwise construct a %__shared_ptr that shares ownership
556 * @param __r A %__shared_ptr.
557 * @post get() == __r.get() && use_count() == __r.use_count()
558 * @throw std::bad_alloc, in which case
560 template<typename _Tp1>
561 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
562 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
563 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
565 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r
566 * and stores a copy of the pointer stored in @a __r.
567 * @param __r A weak_ptr.
568 * @post use_count() == __r.use_count()
569 * @throw bad_weak_ptr when __r.expired(),
570 * in which case the constructor has no effect.
572 template<typename _Tp1>
574 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
575 : _M_refcount(__r._M_refcount) // may throw
577 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
578 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
584 * @post use_count() == 1 and __r.get() == 0
586 template<typename _Tp1>
588 __shared_ptr(std::auto_ptr<_Tp1>& __r)
589 : _M_ptr(__r.get()), _M_refcount()
591 // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
592 // delete __r.release() well-formed
593 _Tp1* __tmp = __r.get();
594 _M_refcount = __shared_count<_Lp>(__r);
595 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
598 template<typename _Tp1>
599 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
600 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
601 _M_refcount(__r._M_refcount)
604 template<typename _Tp1>
605 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
606 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
607 _M_refcount(__r._M_refcount)
610 template<typename _Tp1>
611 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
612 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
613 _M_refcount(__r._M_refcount)
615 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
616 _M_refcount = __shared_count<_Lp>();
619 template<typename _Tp1>
621 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
624 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
628 template<typename _Tp1>
630 operator=(std::auto_ptr<_Tp1>& __r)
632 __shared_ptr(__r).swap(*this);
637 reset() // never throws
638 { __shared_ptr().swap(*this); }
640 template<typename _Tp1>
642 reset(_Tp1* __p) // _Tp1 must be complete.
644 // Catch self-reset errors.
645 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
646 __shared_ptr(__p).swap(*this);
649 template<typename _Tp1, typename _Deleter>
651 reset(_Tp1* __p, _Deleter __d)
652 { __shared_ptr(__p, __d).swap(*this); }
654 // Allow class instantiation when _Tp is [cv-qual] void.
655 typename add_reference<_Tp>::type
656 operator*() const // never throws
658 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
663 operator->() const // never throws
665 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
670 get() const // never throws
673 // Implicit conversion to "bool"
675 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
678 operator __unspecified_bool_type() const // never throws
679 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
682 unique() const // never throws
683 { return _M_refcount._M_unique(); }
686 use_count() const // never throws
687 { return _M_refcount._M_get_use_count(); }
690 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
692 std::swap(_M_ptr, __other._M_ptr);
693 _M_refcount._M_swap(__other._M_refcount);
698 _M_get_deleter(const std::type_info& __ti) const
699 { return _M_refcount._M_get_deleter(__ti); }
701 template<typename _Tp1, _Lock_policy _Lp1>
703 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
704 { return _M_refcount < __rhs._M_refcount; }
706 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
707 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
709 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
710 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
712 // Friends injected into enclosing namespace and found by ADL:
713 template<typename _Tp1>
715 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
716 { return __a.get() == __b.get(); }
718 template<typename _Tp1>
720 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
721 { return __a.get() != __b.get(); }
723 template<typename _Tp1>
725 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
726 { return __a._M_less(__b); }
728 _Tp* _M_ptr; // Contained pointer.
729 __shared_count<_Lp> _M_refcount; // Reference counter.
732 // 2.2.3.8 shared_ptr specialized algorithms.
733 template<typename _Tp, _Lock_policy _Lp>
735 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
738 // 2.2.3.9 shared_ptr casts
739 /** @warning The seemingly equivalent
740 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
741 * will eventually result in undefined behaviour,
742 * attempting to delete the same object twice.
744 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
745 __shared_ptr<_Tp, _Lp>
746 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
747 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
749 /** @warning The seemingly equivalent
750 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
751 * will eventually result in undefined behaviour,
752 * attempting to delete the same object twice.
754 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
755 __shared_ptr<_Tp, _Lp>
756 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
757 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
759 /** @warning The seemingly equivalent
760 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
761 * will eventually result in undefined behaviour,
762 * attempting to delete the same object twice.
764 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
765 __shared_ptr<_Tp, _Lp>
766 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
767 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
769 // 2.2.3.7 shared_ptr I/O
770 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
771 std::basic_ostream<_Ch, _Tr>&
772 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
773 const __shared_ptr<_Tp, _Lp>& __p)
779 // 2.2.3.10 shared_ptr get_deleter (experimental)
780 template<typename _Del, typename _Tp, _Lock_policy _Lp>
782 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
783 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
786 template<typename _Tp, _Lock_policy _Lp>
790 typedef _Tp element_type;
793 : _M_ptr(0), _M_refcount() // never throws
796 // Generated copy constructor, assignment, destructor are fine.
798 // The "obvious" converting constructor implementation:
800 // template<typename _Tp1>
801 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
802 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
805 // has a serious problem.
807 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
808 // conversion may require access to *__r._M_ptr (virtual inheritance).
810 // It is not possible to avoid spurious access violations since
811 // in multithreaded programs __r._M_ptr may be invalidated at any point.
812 template<typename _Tp1>
813 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
814 : _M_refcount(__r._M_refcount) // never throws
816 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
817 _M_ptr = __r.lock().get();
820 template<typename _Tp1>
821 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
822 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
823 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
825 template<typename _Tp1>
827 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
829 _M_ptr = __r.lock().get();
830 _M_refcount = __r._M_refcount;
834 template<typename _Tp1>
836 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
839 _M_refcount = __r._M_refcount;
843 __shared_ptr<_Tp, _Lp>
844 lock() const // never throws
847 // Optimization: avoid throw overhead.
849 return __shared_ptr<element_type, _Lp>();
853 return __shared_ptr<element_type, _Lp>(*this);
855 catch(const bad_weak_ptr&)
857 // Q: How can we get here?
858 // A: Another thread may have invalidated r after the
859 // use_count test above.
860 return __shared_ptr<element_type>();
864 // Optimization: avoid try/catch overhead when single threaded.
865 return expired() ? __shared_ptr<element_type, _Lp>()
866 : __shared_ptr<element_type, _Lp>(*this);
872 use_count() const // never throws
873 { return _M_refcount._M_get_use_count(); }
876 expired() const // never throws
877 { return _M_refcount._M_get_use_count() == 0; }
880 reset() // never throws
881 { __weak_ptr().swap(*this); }
884 swap(__weak_ptr& __s) // never throws
886 std::swap(_M_ptr, __s._M_ptr);
887 _M_refcount._M_swap(__s._M_refcount);
891 // Used by __enable_shared_from_this.
893 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
896 _M_refcount = __refcount;
899 template<typename _Tp1>
901 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
902 { return _M_refcount < __rhs._M_refcount; }
904 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
905 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
906 friend class __enable_shared_from_this<_Tp, _Lp>;
907 friend class enable_shared_from_this<_Tp>;
909 // Friend injected into namespace and found by ADL.
910 template<typename _Tp1>
912 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
913 { return __lhs._M_less(__rhs); }
915 _Tp* _M_ptr; // Contained pointer.
916 __weak_count<_Lp> _M_refcount; // Reference counter.
919 // 2.2.4.7 weak_ptr specialized algorithms.
920 template<typename _Tp, _Lock_policy _Lp>
922 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
926 template<typename _Tp, _Lock_policy _Lp>
927 class __enable_shared_from_this
930 __enable_shared_from_this() { }
932 __enable_shared_from_this(const __enable_shared_from_this&) { }
934 __enable_shared_from_this&
935 operator=(const __enable_shared_from_this&)
938 ~__enable_shared_from_this() { }
941 __shared_ptr<_Tp, _Lp>
943 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
945 __shared_ptr<const _Tp, _Lp>
946 shared_from_this() const
947 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
950 template<typename _Tp1>
952 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
953 { _M_weak_this._M_assign(__p, __n); }
955 template<typename _Tp1>
957 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
958 const __enable_shared_from_this* __pe,
962 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
965 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
969 // The actual TR1 shared_ptr, with forwarding constructors and
970 // assignment operators.
971 template<typename _Tp>
973 : public __shared_ptr<_Tp>
977 : __shared_ptr<_Tp>() { }
979 template<typename _Tp1>
981 shared_ptr(_Tp1* __p)
982 : __shared_ptr<_Tp>(__p) { }
984 template<typename _Tp1, typename _Deleter>
985 shared_ptr(_Tp1* __p, _Deleter __d)
986 : __shared_ptr<_Tp>(__p, __d) { }
988 template<typename _Tp1>
989 shared_ptr(const shared_ptr<_Tp1>& __r)
990 : __shared_ptr<_Tp>(__r) { }
992 template<typename _Tp1>
994 shared_ptr(const weak_ptr<_Tp1>& __r)
995 : __shared_ptr<_Tp>(__r) { }
997 template<typename _Tp1>
999 shared_ptr(std::auto_ptr<_Tp1>& __r)
1000 : __shared_ptr<_Tp>(__r) { }
1002 template<typename _Tp1>
1003 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1004 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1006 template<typename _Tp1>
1007 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1008 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1010 template<typename _Tp1>
1011 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1012 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1014 template<typename _Tp1>
1016 operator=(const shared_ptr<_Tp1>& __r) // never throws
1018 this->__shared_ptr<_Tp>::operator=(__r);
1022 template<typename _Tp1>
1024 operator=(std::auto_ptr<_Tp1>& __r)
1026 this->__shared_ptr<_Tp>::operator=(__r);
1031 template<typename _Tp, typename _Tp1>
1033 static_pointer_cast(const shared_ptr<_Tp1>& __r)
1034 { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1036 template<typename _Tp, typename _Tp1>
1038 const_pointer_cast(const shared_ptr<_Tp1>& __r)
1039 { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1041 template<typename _Tp, typename _Tp1>
1043 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1044 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1047 // The actual TR1 weak_ptr, with forwarding constructors and
1048 // assignment operators.
1049 template<typename _Tp>
1051 : public __weak_ptr<_Tp>
1055 : __weak_ptr<_Tp>() { }
1057 template<typename _Tp1>
1058 weak_ptr(const weak_ptr<_Tp1>& __r)
1059 : __weak_ptr<_Tp>(__r) { }
1061 template<typename _Tp1>
1062 weak_ptr(const shared_ptr<_Tp1>& __r)
1063 : __weak_ptr<_Tp>(__r) { }
1065 template<typename _Tp1>
1067 operator=(const weak_ptr<_Tp1>& __r) // never throws
1069 this->__weak_ptr<_Tp>::operator=(__r);
1073 template<typename _Tp1>
1075 operator=(const shared_ptr<_Tp1>& __r) // never throws
1077 this->__weak_ptr<_Tp>::operator=(__r);
1082 lock() const // never throws
1085 if (this->expired())
1086 return shared_ptr<_Tp>();
1090 return shared_ptr<_Tp>(*this);
1092 catch(const bad_weak_ptr&)
1094 return shared_ptr<_Tp>();
1097 return this->expired() ? shared_ptr<_Tp>()
1098 : shared_ptr<_Tp>(*this);
1104 template<typename _Tp>
1105 class enable_shared_from_this
1108 enable_shared_from_this() { }
1110 enable_shared_from_this(const enable_shared_from_this&) { }
1112 enable_shared_from_this&
1113 operator=(const enable_shared_from_this&)
1116 ~enable_shared_from_this() { }
1121 { return shared_ptr<_Tp>(this->_M_weak_this); }
1123 shared_ptr<const _Tp>
1124 shared_from_this() const
1125 { return shared_ptr<const _Tp>(this->_M_weak_this); }
1128 template<typename _Tp1>
1130 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1131 { _M_weak_this._M_assign(__p, __n); }
1133 template<typename _Tp1>
1135 __enable_shared_from_this_helper(const __shared_count<>& __pn,
1136 const enable_shared_from_this* __pe,
1140 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1143 mutable weak_ptr<_Tp> _M_weak_this;
1146 _GLIBCXX_END_NAMESPACE