1 // <tr1_impl/boost_shared_ptr.h> -*- C++ -*-
3 // Copyright (C) 2007 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_impl/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.
56 _GLIBCXX_BEGIN_NAMESPACE_TR1
58 class bad_weak_ptr : public std::exception
63 { return "tr1::bad_weak_ptr"; }
66 // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
68 __throw_bad_weak_ptr()
77 using __gnu_cxx::_Lock_policy;
78 using __gnu_cxx::__default_lock_policy;
79 using __gnu_cxx::_S_single;
80 using __gnu_cxx::_S_mutex;
81 using __gnu_cxx::_S_atomic;
83 template<typename _Tp>
86 typedef void result_type;
87 typedef _Tp* argument_type;
90 operator()(_Tp* __p) const
94 // Empty helper class except when the template argument is _S_mutex.
95 template<_Lock_policy _Lp>
100 class _Mutex_base<_S_mutex>
101 : public __gnu_cxx::__mutex
104 template<_Lock_policy _Lp = __default_lock_policy>
105 class _Sp_counted_base
106 : public _Mutex_base<_Lp>
110 : _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 _M_dispose() = 0; // nothrow
121 // Called when _M_weak_count drops to zero.
123 _M_destroy() // nothrow
127 _M_get_deleter(const std::type_info&) = 0;
131 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
137 _M_release() // nothrow
139 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
144 _GLIBCXX_READ_MEM_BARRIER;
145 _GLIBCXX_WRITE_MEM_BARRIER;
147 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
154 _M_weak_add_ref() // nothrow
155 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
158 _M_weak_release() // nothrow
160 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
163 _GLIBCXX_READ_MEM_BARRIER;
164 _GLIBCXX_WRITE_MEM_BARRIER;
171 _M_get_use_count() const // nothrow
172 { return _M_use_count; } // XXX is this MT safe?
175 _Sp_counted_base(_Sp_counted_base const&);
176 _Sp_counted_base& operator=(_Sp_counted_base const&);
178 _Atomic_word _M_use_count; // #shared
179 _Atomic_word _M_weak_count; // #weak + (#shared != 0)
184 _Sp_counted_base<_S_single>::
187 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
190 __throw_bad_weak_ptr();
196 _Sp_counted_base<_S_mutex>::
199 __gnu_cxx::__scoped_lock sentry(*this);
200 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
203 __throw_bad_weak_ptr();
209 _Sp_counted_base<_S_atomic>::
212 // Perform lock-free add-if-not-zero operation.
213 _Atomic_word __count;
216 __count = _M_use_count;
218 __throw_bad_weak_ptr();
220 // Replace the current counter value with the old value + 1, as
221 // long as it's not changed meanwhile.
223 while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
227 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
228 class _Sp_counted_base_impl
229 : public _Sp_counted_base<_Lp>
234 * @pre __d(__p) must not throw.
236 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
237 : _M_ptr(__p), _M_del(__d) { }
240 _M_dispose() // nothrow
244 _M_get_deleter(const std::type_info& __ti)
245 { return __ti == typeid(_Deleter) ? &_M_del : 0; }
248 _Sp_counted_base_impl(const _Sp_counted_base_impl&);
249 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
251 _Ptr _M_ptr; // copy constructor must not throw
252 _Deleter _M_del; // copy constructor must not throw
255 template<_Lock_policy _Lp = __default_lock_policy>
258 template<_Lock_policy _Lp = __default_lock_policy>
263 : _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 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
281 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
282 template<typename _Tp>
284 __shared_count(std::auto_ptr<_Tp>& __r)
285 : _M_pi(new _Sp_counted_base_impl<_Tp*,
286 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
290 // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
292 __shared_count(const __weak_count<_Lp>& __r);
294 ~__shared_count() // nothrow
300 __shared_count(const __shared_count& __r)
301 : _M_pi(__r._M_pi) // nothrow
304 _M_pi->_M_add_ref_copy();
308 operator=(const __shared_count& __r) // nothrow
310 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
314 __tmp->_M_add_ref_copy();
323 _M_swap(__shared_count& __r) // nothrow
325 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
331 _M_get_use_count() const // nothrow
332 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
335 _M_unique() const // nothrow
336 { return this->_M_get_use_count() == 1; }
339 operator==(const __shared_count& __a, const __shared_count& __b)
340 { return __a._M_pi == __b._M_pi; }
343 operator<(const __shared_count& __a, const __shared_count& __b)
344 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
347 _M_get_deleter(const std::type_info& __ti) const
348 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
351 friend class __weak_count<_Lp>;
353 _Sp_counted_base<_Lp>* _M_pi;
356 template<_Lock_policy _Lp>
361 : _M_pi(0) // nothrow
364 __weak_count(const __shared_count<_Lp>& __r)
365 : _M_pi(__r._M_pi) // nothrow
368 _M_pi->_M_weak_add_ref();
371 __weak_count(const __weak_count<_Lp>& __r)
372 : _M_pi(__r._M_pi) // nothrow
375 _M_pi->_M_weak_add_ref();
378 ~__weak_count() // nothrow
381 _M_pi->_M_weak_release();
385 operator=(const __shared_count<_Lp>& __r) // nothrow
387 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
389 __tmp->_M_weak_add_ref();
391 _M_pi->_M_weak_release();
397 operator=(const __weak_count<_Lp>& __r) // nothrow
399 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
401 __tmp->_M_weak_add_ref();
403 _M_pi->_M_weak_release();
409 _M_swap(__weak_count<_Lp>& __r) // nothrow
411 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
417 _M_get_use_count() const // nothrow
418 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
421 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
422 { return __a._M_pi == __b._M_pi; }
425 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
426 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
429 friend class __shared_count<_Lp>;
431 _Sp_counted_base<_Lp>* _M_pi;
434 template<_Lock_policy _Lp>
436 __shared_count<_Lp>::
437 __shared_count(const __weak_count<_Lp>& __r)
441 _M_pi->_M_add_ref_lock();
443 __throw_bad_weak_ptr();
447 // Forward declarations.
448 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
451 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
454 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
455 class __enable_shared_from_this;
457 template<typename _Tp>
460 template<typename _Tp>
463 template<typename _Tp>
464 class enable_shared_from_this;
466 // Support for enable_shared_from_this.
468 // Friend of __enable_shared_from_this.
469 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
471 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
472 const __enable_shared_from_this<_Tp1,
475 // Friend of enable_shared_from_this.
476 template<typename _Tp1, typename _Tp2>
478 __enable_shared_from_this_helper(const __shared_count<>&,
479 const enable_shared_from_this<_Tp1>*,
482 template<_Lock_policy _Lp>
484 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
488 struct __static_cast_tag { };
489 struct __const_cast_tag { };
490 struct __dynamic_cast_tag { };
493 * @class shared_ptr <tr1/memory>
495 * A smart pointer with reference-counted copy semantics.
496 * The object pointed to is deleted when the last shared_ptr pointing to
497 * it is destroyed or reset.
499 template<typename _Tp, _Lock_policy _Lp>
503 typedef _Tp element_type;
505 /** @brief Construct an empty %__shared_ptr.
506 * @post use_count()==0 && get()==0
509 : _M_ptr(0), _M_refcount() // never throws
512 /** @brief Construct a %__shared_ptr that owns the pointer @a __p.
513 * @param __p A pointer that is convertible to element_type*.
514 * @post use_count() == 1 && get() == __p
515 * @throw std::bad_alloc, in which case @c delete @a __p is called.
517 template<typename _Tp1>
519 __shared_ptr(_Tp1* __p)
520 : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
522 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
523 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
524 __enable_shared_from_this_helper(_M_refcount, __p, __p);
528 // Requirements: _Deleter' copy constructor and destructor must not throw
530 // __shared_ptr will release __p by calling __d(__p)
532 /** @brief Construct a %__shared_ptr that owns the pointer @a __p
533 * and the deleter @a __d.
534 * @param __p A pointer.
535 * @param __d A deleter.
536 * @post use_count() == 1 && get() == __p
537 * @throw std::bad_alloc, in which case @a __d(__p) is called.
539 template<typename _Tp1, typename _Deleter>
540 __shared_ptr(_Tp1* __p, _Deleter __d)
541 : _M_ptr(__p), _M_refcount(__p, __d)
543 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
544 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
545 __enable_shared_from_this_helper(_M_refcount, __p, __p);
548 // generated copy constructor, assignment, destructor are fine.
550 /** @brief If @a __r is empty, constructs an empty %__shared_ptr;
551 * otherwise construct a %__shared_ptr that shares ownership
553 * @param __r A %__shared_ptr.
554 * @post get() == __r.get() && use_count() == __r.use_count()
555 * @throw std::bad_alloc, in which case
557 template<typename _Tp1>
558 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
559 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
560 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
562 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r
563 * and stores a copy of the pointer stored in @a __r.
564 * @param __r A weak_ptr.
565 * @post use_count() == __r.use_count()
566 * @throw bad_weak_ptr when __r.expired(),
567 * in which case the constructor has no effect.
569 template<typename _Tp1>
571 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
572 : _M_refcount(__r._M_refcount) // may throw
574 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
575 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
581 * @post use_count() == 1 and __r.get() == 0
583 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
584 template<typename _Tp1>
586 __shared_ptr(std::auto_ptr<_Tp1>& __r)
587 : _M_ptr(__r.get()), _M_refcount()
589 // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
590 // delete __r.release() well-formed
591 _Tp1* __tmp = __r.get();
592 _M_refcount = __shared_count<_Lp>(__r);
593 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
597 template<typename _Tp1>
598 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
599 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
600 _M_refcount(__r._M_refcount)
603 template<typename _Tp1>
604 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
605 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
606 _M_refcount(__r._M_refcount)
609 template<typename _Tp1>
610 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
611 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
612 _M_refcount(__r._M_refcount)
614 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
615 _M_refcount = __shared_count<_Lp>();
618 template<typename _Tp1>
620 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
623 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
627 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
628 template<typename _Tp1>
630 operator=(std::auto_ptr<_Tp1>& __r)
632 __shared_ptr(__r).swap(*this);
638 reset() // never throws
639 { __shared_ptr().swap(*this); }
641 template<typename _Tp1>
643 reset(_Tp1* __p) // _Tp1 must be complete.
645 // Catch self-reset errors.
646 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
647 __shared_ptr(__p).swap(*this);
650 template<typename _Tp1, typename _Deleter>
652 reset(_Tp1* __p, _Deleter __d)
653 { __shared_ptr(__p, __d).swap(*this); }
655 // Allow class instantiation when _Tp is [cv-qual] void.
656 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
657 typename std::add_lvalue_reference<_Tp>::type
659 typename std::tr1::add_reference<_Tp>::type
661 operator*() const // never throws
663 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
668 operator->() const // never throws
670 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
675 get() const // never throws
678 // Implicit conversion to "bool"
680 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
683 operator __unspecified_bool_type() const // never throws
684 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
687 unique() const // never throws
688 { return _M_refcount._M_unique(); }
691 use_count() const // never throws
692 { return _M_refcount._M_get_use_count(); }
695 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
697 std::swap(_M_ptr, __other._M_ptr);
698 _M_refcount._M_swap(__other._M_refcount);
703 _M_get_deleter(const std::type_info& __ti) const
704 { return _M_refcount._M_get_deleter(__ti); }
706 template<typename _Tp1, _Lock_policy _Lp1>
708 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
709 { return _M_refcount < __rhs._M_refcount; }
711 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
712 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
714 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
715 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
717 // Friends injected into enclosing namespace and found by ADL:
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.get() != __b.get(); }
728 template<typename _Tp1>
730 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
731 { return __a._M_less(__b); }
733 _Tp* _M_ptr; // Contained pointer.
734 __shared_count<_Lp> _M_refcount; // Reference counter.
737 // 2.2.3.8 shared_ptr specialized algorithms.
738 template<typename _Tp, _Lock_policy _Lp>
740 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
743 // 2.2.3.9 shared_ptr casts
744 /** @warning The seemingly equivalent
745 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
746 * will eventually result in undefined behaviour,
747 * attempting to delete the same object twice.
749 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
750 __shared_ptr<_Tp, _Lp>
751 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
752 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
754 /** @warning The seemingly equivalent
755 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
756 * will eventually result in undefined behaviour,
757 * attempting to delete the same object twice.
759 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
760 __shared_ptr<_Tp, _Lp>
761 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
762 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
764 /** @warning The seemingly equivalent
765 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
766 * will eventually result in undefined behaviour,
767 * attempting to delete the same object twice.
769 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
770 __shared_ptr<_Tp, _Lp>
771 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
772 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
774 // 2.2.3.7 shared_ptr I/O
775 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
776 std::basic_ostream<_Ch, _Tr>&
777 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
778 const __shared_ptr<_Tp, _Lp>& __p)
784 // 2.2.3.10 shared_ptr get_deleter (experimental)
785 template<typename _Del, typename _Tp, _Lock_policy _Lp>
787 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
788 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
791 template<typename _Tp, _Lock_policy _Lp>
795 typedef _Tp element_type;
798 : _M_ptr(0), _M_refcount() // never throws
801 // Generated copy constructor, assignment, destructor are fine.
803 // The "obvious" converting constructor implementation:
805 // template<typename _Tp1>
806 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
807 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
810 // has a serious problem.
812 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
813 // conversion may require access to *__r._M_ptr (virtual inheritance).
815 // It is not possible to avoid spurious access violations since
816 // in multithreaded programs __r._M_ptr may be invalidated at any point.
817 template<typename _Tp1>
818 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
819 : _M_refcount(__r._M_refcount) // never throws
821 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
822 _M_ptr = __r.lock().get();
825 template<typename _Tp1>
826 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
827 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
828 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
830 template<typename _Tp1>
832 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
834 _M_ptr = __r.lock().get();
835 _M_refcount = __r._M_refcount;
839 template<typename _Tp1>
841 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
844 _M_refcount = __r._M_refcount;
848 __shared_ptr<_Tp, _Lp>
849 lock() const // never throws
852 // Optimization: avoid throw overhead.
854 return __shared_ptr<element_type, _Lp>();
858 return __shared_ptr<element_type, _Lp>(*this);
860 catch(const bad_weak_ptr&)
862 // Q: How can we get here?
863 // A: Another thread may have invalidated r after the
864 // use_count test above.
865 return __shared_ptr<element_type, _Lp>();
869 // Optimization: avoid try/catch overhead when single threaded.
870 return expired() ? __shared_ptr<element_type, _Lp>()
871 : __shared_ptr<element_type, _Lp>(*this);
877 use_count() const // never throws
878 { return _M_refcount._M_get_use_count(); }
881 expired() const // never throws
882 { return _M_refcount._M_get_use_count() == 0; }
885 reset() // never throws
886 { __weak_ptr().swap(*this); }
889 swap(__weak_ptr& __s) // never throws
891 std::swap(_M_ptr, __s._M_ptr);
892 _M_refcount._M_swap(__s._M_refcount);
896 // Used by __enable_shared_from_this.
898 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
901 _M_refcount = __refcount;
904 template<typename _Tp1>
906 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
907 { return _M_refcount < __rhs._M_refcount; }
909 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
910 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
911 friend class __enable_shared_from_this<_Tp, _Lp>;
912 friend class enable_shared_from_this<_Tp>;
914 // Friend injected into namespace and found by ADL.
915 template<typename _Tp1>
917 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
918 { return __lhs._M_less(__rhs); }
920 _Tp* _M_ptr; // Contained pointer.
921 __weak_count<_Lp> _M_refcount; // Reference counter.
924 // 2.2.4.7 weak_ptr specialized algorithms.
925 template<typename _Tp, _Lock_policy _Lp>
927 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
931 template<typename _Tp, _Lock_policy _Lp>
932 class __enable_shared_from_this
935 __enable_shared_from_this() { }
937 __enable_shared_from_this(const __enable_shared_from_this&) { }
939 __enable_shared_from_this&
940 operator=(const __enable_shared_from_this&)
943 ~__enable_shared_from_this() { }
946 __shared_ptr<_Tp, _Lp>
948 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
950 __shared_ptr<const _Tp, _Lp>
951 shared_from_this() const
952 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
955 template<typename _Tp1>
957 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
958 { _M_weak_this._M_assign(__p, __n); }
960 template<typename _Tp1>
962 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
963 const __enable_shared_from_this* __pe,
967 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
970 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
974 // The actual TR1 shared_ptr, with forwarding constructors and
975 // assignment operators.
976 template<typename _Tp>
978 : public __shared_ptr<_Tp>
982 : __shared_ptr<_Tp>() { }
984 template<typename _Tp1>
986 shared_ptr(_Tp1* __p)
987 : __shared_ptr<_Tp>(__p) { }
989 template<typename _Tp1, typename _Deleter>
990 shared_ptr(_Tp1* __p, _Deleter __d)
991 : __shared_ptr<_Tp>(__p, __d) { }
993 template<typename _Tp1>
994 shared_ptr(const shared_ptr<_Tp1>& __r)
995 : __shared_ptr<_Tp>(__r) { }
997 template<typename _Tp1>
999 shared_ptr(const weak_ptr<_Tp1>& __r)
1000 : __shared_ptr<_Tp>(__r) { }
1002 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
1003 template<typename _Tp1>
1005 shared_ptr(std::auto_ptr<_Tp1>& __r)
1006 : __shared_ptr<_Tp>(__r) { }
1009 template<typename _Tp1>
1010 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1011 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1013 template<typename _Tp1>
1014 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1015 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1017 template<typename _Tp1>
1018 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1019 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1021 template<typename _Tp1>
1023 operator=(const shared_ptr<_Tp1>& __r) // never throws
1025 this->__shared_ptr<_Tp>::operator=(__r);
1029 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_USE_DEPRECATED
1030 template<typename _Tp1>
1032 operator=(std::auto_ptr<_Tp1>& __r)
1034 this->__shared_ptr<_Tp>::operator=(__r);
1040 template<typename _Tp, typename _Tp1>
1042 static_pointer_cast(const shared_ptr<_Tp1>& __r)
1043 { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1045 template<typename _Tp, typename _Tp1>
1047 const_pointer_cast(const shared_ptr<_Tp1>& __r)
1048 { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1050 template<typename _Tp, typename _Tp1>
1052 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1053 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1056 // The actual TR1 weak_ptr, with forwarding constructors and
1057 // assignment operators.
1058 template<typename _Tp>
1060 : public __weak_ptr<_Tp>
1064 : __weak_ptr<_Tp>() { }
1066 template<typename _Tp1>
1067 weak_ptr(const weak_ptr<_Tp1>& __r)
1068 : __weak_ptr<_Tp>(__r) { }
1070 template<typename _Tp1>
1071 weak_ptr(const shared_ptr<_Tp1>& __r)
1072 : __weak_ptr<_Tp>(__r) { }
1074 template<typename _Tp1>
1076 operator=(const weak_ptr<_Tp1>& __r) // never throws
1078 this->__weak_ptr<_Tp>::operator=(__r);
1082 template<typename _Tp1>
1084 operator=(const shared_ptr<_Tp1>& __r) // never throws
1086 this->__weak_ptr<_Tp>::operator=(__r);
1091 lock() const // never throws
1094 if (this->expired())
1095 return shared_ptr<_Tp>();
1099 return shared_ptr<_Tp>(*this);
1101 catch(const bad_weak_ptr&)
1103 return shared_ptr<_Tp>();
1106 return this->expired() ? shared_ptr<_Tp>()
1107 : shared_ptr<_Tp>(*this);
1113 template<typename _Tp>
1114 class enable_shared_from_this
1117 enable_shared_from_this() { }
1119 enable_shared_from_this(const enable_shared_from_this&) { }
1121 enable_shared_from_this&
1122 operator=(const enable_shared_from_this&)
1125 ~enable_shared_from_this() { }
1130 { return shared_ptr<_Tp>(this->_M_weak_this); }
1132 shared_ptr<const _Tp>
1133 shared_from_this() const
1134 { return shared_ptr<const _Tp>(this->_M_weak_this); }
1137 template<typename _Tp1>
1139 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1140 { _M_weak_this._M_assign(__p, __n); }
1142 template<typename _Tp1>
1144 __enable_shared_from_this_helper(const __shared_count<>& __pn,
1145 const enable_shared_from_this* __pe,
1149 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1152 mutable weak_ptr<_Tp> _M_weak_this;
1155 _GLIBCXX_END_NAMESPACE_TR1