1 // <tr1/shared_ptr.h> -*- C++ -*-
3 // Copyright (C) 2007, 2008, 2009 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 3, 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 // 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.
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/>.
26 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
30 // Copyright (C) 2001, 2002, 2003 Peter Dimov
33 // Copyright (C) 2001, 2002, 2003 Peter Dimov
35 // enable_shared_from_this.hpp
36 // Copyright (C) 2002 Peter Dimov
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)
42 // GCC Note: based on version 1.32.0 of the Boost library.
44 /** @file tr1/shared_ptr.h
45 * This is an internal header file, included by other library headers.
46 * You should not attempt to use it directly.
49 #ifndef _TR1_SHARED_PTR_H
50 #define _TR1_SHARED_PTR_H 1
52 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
53 # error TR1 header cannot be included from C++0x header
60 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
61 class _Sp_counted_base_impl
62 : public _Sp_counted_base<_Lp>
65 // Precondition: __d(__p) must not throw.
66 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
67 : _M_ptr(__p), _M_del(__d) { }
70 _M_dispose() // nothrow
74 _M_get_deleter(const std::type_info& __ti)
75 { return __ti == typeid(_Deleter) ? &_M_del : 0; }
78 _Sp_counted_base_impl(const _Sp_counted_base_impl&);
79 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
81 _Ptr _M_ptr; // copy constructor must not throw
82 _Deleter _M_del; // copy constructor must not throw
85 template<_Lock_policy _Lp = __default_lock_policy>
88 template<typename _Tp>
91 typedef void result_type;
92 typedef _Tp* argument_type;
93 void operator()(_Tp* __p) const { delete __p; }
96 template<_Lock_policy _Lp = __default_lock_policy>
101 : _M_pi(0) // nothrow
104 template<typename _Ptr>
105 __shared_count(_Ptr __p) : _M_pi(0)
109 typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
110 _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
111 __p, _Sp_deleter<_Tp>());
116 __throw_exception_again;
120 template<typename _Ptr, typename _Deleter>
121 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
125 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
129 __d(__p); // Call _Deleter on __p.
130 __throw_exception_again;
134 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
135 template<typename _Tp>
137 __shared_count(std::auto_ptr<_Tp>& __r)
138 : _M_pi(new _Sp_counted_base_impl<_Tp*,
139 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
142 // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
144 __shared_count(const __weak_count<_Lp>& __r);
146 ~__shared_count() // nothrow
152 __shared_count(const __shared_count& __r)
153 : _M_pi(__r._M_pi) // nothrow
156 _M_pi->_M_add_ref_copy();
160 operator=(const __shared_count& __r) // nothrow
162 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
166 __tmp->_M_add_ref_copy();
175 _M_swap(__shared_count& __r) // nothrow
177 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
183 _M_get_use_count() const // nothrow
184 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
187 _M_unique() const // nothrow
188 { return this->_M_get_use_count() == 1; }
191 operator==(const __shared_count& __a, const __shared_count& __b)
192 { return __a._M_pi == __b._M_pi; }
195 operator<(const __shared_count& __a, const __shared_count& __b)
196 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
199 _M_get_deleter(const std::type_info& __ti) const
200 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
203 friend class __weak_count<_Lp>;
205 _Sp_counted_base<_Lp>* _M_pi;
209 template<_Lock_policy _Lp>
214 : _M_pi(0) // nothrow
217 __weak_count(const __shared_count<_Lp>& __r)
218 : _M_pi(__r._M_pi) // nothrow
221 _M_pi->_M_weak_add_ref();
224 __weak_count(const __weak_count<_Lp>& __r)
225 : _M_pi(__r._M_pi) // nothrow
228 _M_pi->_M_weak_add_ref();
231 ~__weak_count() // nothrow
234 _M_pi->_M_weak_release();
238 operator=(const __shared_count<_Lp>& __r) // nothrow
240 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
242 __tmp->_M_weak_add_ref();
244 _M_pi->_M_weak_release();
250 operator=(const __weak_count<_Lp>& __r) // nothrow
252 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
254 __tmp->_M_weak_add_ref();
256 _M_pi->_M_weak_release();
262 _M_swap(__weak_count<_Lp>& __r) // nothrow
264 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
270 _M_get_use_count() const // nothrow
271 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
274 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
275 { return __a._M_pi == __b._M_pi; }
278 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
279 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
282 friend class __shared_count<_Lp>;
284 _Sp_counted_base<_Lp>* _M_pi;
287 // now that __weak_count is defined we can define this constructor:
288 template<_Lock_policy _Lp>
290 __shared_count<_Lp>::
291 __shared_count(const __weak_count<_Lp>& __r)
295 _M_pi->_M_add_ref_lock();
297 __throw_bad_weak_ptr();
300 // Forward declarations.
301 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
304 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
307 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
308 class __enable_shared_from_this;
310 template<typename _Tp>
313 template<typename _Tp>
316 template<typename _Tp>
317 class enable_shared_from_this;
319 // Support for enable_shared_from_this.
321 // Friend of __enable_shared_from_this.
322 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
324 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
325 const __enable_shared_from_this<_Tp1,
328 // Friend of enable_shared_from_this.
329 template<typename _Tp1, typename _Tp2>
331 __enable_shared_from_this_helper(const __shared_count<>&,
332 const enable_shared_from_this<_Tp1>*,
335 template<_Lock_policy _Lp>
337 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
341 struct __static_cast_tag { };
342 struct __const_cast_tag { };
343 struct __dynamic_cast_tag { };
345 // A smart pointer with reference-counted copy semantics. The
346 // object pointed to is deleted when the last shared_ptr pointing to
347 // it is destroyed or reset.
348 template<typename _Tp, _Lock_policy _Lp>
352 typedef _Tp element_type;
355 : _M_ptr(0), _M_refcount() // never throws
358 template<typename _Tp1>
360 __shared_ptr(_Tp1* __p)
361 : _M_ptr(__p), _M_refcount(__p)
363 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
364 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
365 __enable_shared_from_this_helper(_M_refcount, __p, __p);
368 template<typename _Tp1, typename _Deleter>
369 __shared_ptr(_Tp1* __p, _Deleter __d)
370 : _M_ptr(__p), _M_refcount(__p, __d)
372 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
373 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
374 __enable_shared_from_this_helper(_M_refcount, __p, __p);
377 // generated copy constructor, assignment, destructor are fine.
379 template<typename _Tp1>
380 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
381 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
382 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
384 template<typename _Tp1>
386 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
387 : _M_refcount(__r._M_refcount) // may throw
389 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
390 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
395 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
396 // Postcondition: use_count() == 1 and __r.get() == 0
397 template<typename _Tp1>
399 __shared_ptr(std::auto_ptr<_Tp1>& __r)
400 : _M_ptr(__r.get()), _M_refcount()
402 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
403 // TODO requires _Tp1 is complete, delete __r.release() well-formed
404 _Tp1* __tmp = __r.get();
405 _M_refcount = __shared_count<_Lp>(__r);
406 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
411 template<typename _Tp1>
412 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
413 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
414 _M_refcount(__r._M_refcount)
417 template<typename _Tp1>
418 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
419 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
420 _M_refcount(__r._M_refcount)
423 template<typename _Tp1>
424 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
425 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
426 _M_refcount(__r._M_refcount)
428 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
429 _M_refcount = __shared_count<_Lp>();
432 template<typename _Tp1>
434 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
437 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
441 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
442 template<typename _Tp1>
444 operator=(std::auto_ptr<_Tp1>& __r)
446 __shared_ptr(__r).swap(*this);
452 reset() // never throws
453 { __shared_ptr().swap(*this); }
455 template<typename _Tp1>
457 reset(_Tp1* __p) // _Tp1 must be complete.
459 // Catch self-reset errors.
460 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
461 __shared_ptr(__p).swap(*this);
464 template<typename _Tp1, typename _Deleter>
466 reset(_Tp1* __p, _Deleter __d)
467 { __shared_ptr(__p, __d).swap(*this); }
469 // Allow class instantiation when _Tp is [cv-qual] void.
470 typename std::tr1::add_reference<_Tp>::type
471 operator*() const // never throws
473 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
478 operator->() const // never throws
480 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
485 get() const // never throws
488 // Implicit conversion to "bool"
490 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
493 operator __unspecified_bool_type() const // never throws
494 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
497 unique() const // never throws
498 { return _M_refcount._M_unique(); }
501 use_count() const // never throws
502 { return _M_refcount._M_get_use_count(); }
505 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
507 std::swap(_M_ptr, __other._M_ptr);
508 _M_refcount._M_swap(__other._M_refcount);
513 _M_get_deleter(const std::type_info& __ti) const
514 { return _M_refcount._M_get_deleter(__ti); }
516 template<typename _Tp1, _Lock_policy _Lp1>
518 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
519 { return _M_refcount < __rhs._M_refcount; }
521 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
522 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
524 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
525 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
527 // Friends injected into enclosing namespace and found by ADL:
528 template<typename _Tp1>
530 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
531 { return __a.get() == __b.get(); }
533 template<typename _Tp1>
535 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
536 { return __a.get() != __b.get(); }
538 template<typename _Tp1>
540 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
541 { return __a._M_less(__b); }
543 _Tp* _M_ptr; // Contained pointer.
544 __shared_count<_Lp> _M_refcount; // Reference counter.
547 // 2.2.3.8 shared_ptr specialized algorithms.
548 template<typename _Tp, _Lock_policy _Lp>
550 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
553 // 2.2.3.9 shared_ptr casts
554 /* The seemingly equivalent
555 * shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
556 * will eventually result in undefined behaviour,
557 * attempting to delete the same object twice.
559 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
560 inline __shared_ptr<_Tp, _Lp>
561 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
562 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
564 /* The seemingly equivalent
565 * shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
566 * will eventually result in undefined behaviour,
567 * attempting to delete the same object twice.
569 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
570 inline __shared_ptr<_Tp, _Lp>
571 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
572 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
574 /* The seemingly equivalent
575 * shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
576 * will eventually result in undefined behaviour,
577 * attempting to delete the same object twice.
579 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
580 inline __shared_ptr<_Tp, _Lp>
581 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
582 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
584 // 2.2.3.7 shared_ptr I/O
585 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
586 std::basic_ostream<_Ch, _Tr>&
587 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
588 const __shared_ptr<_Tp, _Lp>& __p)
594 // 2.2.3.10 shared_ptr get_deleter (experimental)
595 template<typename _Del, typename _Tp, _Lock_policy _Lp>
597 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
598 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
601 template<typename _Tp, _Lock_policy _Lp>
605 typedef _Tp element_type;
608 : _M_ptr(0), _M_refcount() // never throws
611 // Generated copy constructor, assignment, destructor are fine.
613 // The "obvious" converting constructor implementation:
615 // template<typename _Tp1>
616 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
617 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
620 // has a serious problem.
622 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
623 // conversion may require access to *__r._M_ptr (virtual inheritance).
625 // It is not possible to avoid spurious access violations since
626 // in multithreaded programs __r._M_ptr may be invalidated at any point.
627 template<typename _Tp1>
628 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
629 : _M_refcount(__r._M_refcount) // never throws
631 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
632 _M_ptr = __r.lock().get();
635 template<typename _Tp1>
636 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
637 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
638 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
640 template<typename _Tp1>
642 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
644 _M_ptr = __r.lock().get();
645 _M_refcount = __r._M_refcount;
649 template<typename _Tp1>
651 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
654 _M_refcount = __r._M_refcount;
658 __shared_ptr<_Tp, _Lp>
659 lock() const // never throws
662 // Optimization: avoid throw overhead.
664 return __shared_ptr<element_type, _Lp>();
668 return __shared_ptr<element_type, _Lp>(*this);
670 __catch(const bad_weak_ptr&)
672 // Q: How can we get here?
673 // A: Another thread may have invalidated r after the
674 // use_count test above.
675 return __shared_ptr<element_type, _Lp>();
679 // Optimization: avoid try/catch overhead when single threaded.
680 return expired() ? __shared_ptr<element_type, _Lp>()
681 : __shared_ptr<element_type, _Lp>(*this);
687 use_count() const // never throws
688 { return _M_refcount._M_get_use_count(); }
691 expired() const // never throws
692 { return _M_refcount._M_get_use_count() == 0; }
695 reset() // never throws
696 { __weak_ptr().swap(*this); }
699 swap(__weak_ptr& __s) // never throws
701 std::swap(_M_ptr, __s._M_ptr);
702 _M_refcount._M_swap(__s._M_refcount);
706 // Used by __enable_shared_from_this.
708 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
711 _M_refcount = __refcount;
714 template<typename _Tp1>
716 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
717 { return _M_refcount < __rhs._M_refcount; }
719 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
720 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
721 friend class __enable_shared_from_this<_Tp, _Lp>;
722 friend class enable_shared_from_this<_Tp>;
724 // Friend injected into namespace and found by ADL.
725 template<typename _Tp1>
727 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
728 { return __lhs._M_less(__rhs); }
730 _Tp* _M_ptr; // Contained pointer.
731 __weak_count<_Lp> _M_refcount; // Reference counter.
734 // 2.2.4.7 weak_ptr specialized algorithms.
735 template<typename _Tp, _Lock_policy _Lp>
737 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
741 template<typename _Tp, _Lock_policy _Lp>
742 class __enable_shared_from_this
745 __enable_shared_from_this() { }
747 __enable_shared_from_this(const __enable_shared_from_this&) { }
749 __enable_shared_from_this&
750 operator=(const __enable_shared_from_this&)
753 ~__enable_shared_from_this() { }
756 __shared_ptr<_Tp, _Lp>
758 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
760 __shared_ptr<const _Tp, _Lp>
761 shared_from_this() const
762 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
765 template<typename _Tp1>
767 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
768 { _M_weak_this._M_assign(__p, __n); }
770 template<typename _Tp1>
772 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
773 const __enable_shared_from_this* __pe,
777 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
780 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
784 // The actual shared_ptr, with forwarding constructors and
785 // assignment operators.
786 template<typename _Tp>
788 : public __shared_ptr<_Tp>
792 : __shared_ptr<_Tp>() { }
794 template<typename _Tp1>
796 shared_ptr(_Tp1* __p)
797 : __shared_ptr<_Tp>(__p) { }
799 template<typename _Tp1, typename _Deleter>
800 shared_ptr(_Tp1* __p, _Deleter __d)
801 : __shared_ptr<_Tp>(__p, __d) { }
803 template<typename _Tp1>
804 shared_ptr(const shared_ptr<_Tp1>& __r)
805 : __shared_ptr<_Tp>(__r) { }
807 template<typename _Tp1>
809 shared_ptr(const weak_ptr<_Tp1>& __r)
810 : __shared_ptr<_Tp>(__r) { }
812 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
813 template<typename _Tp1>
815 shared_ptr(std::auto_ptr<_Tp1>& __r)
816 : __shared_ptr<_Tp>(__r) { }
819 template<typename _Tp1>
820 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
821 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
823 template<typename _Tp1>
824 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
825 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
827 template<typename _Tp1>
828 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
829 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
831 template<typename _Tp1>
833 operator=(const shared_ptr<_Tp1>& __r) // never throws
835 this->__shared_ptr<_Tp>::operator=(__r);
839 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
840 template<typename _Tp1>
842 operator=(std::auto_ptr<_Tp1>& __r)
844 this->__shared_ptr<_Tp>::operator=(__r);
850 // 2.2.3.8 shared_ptr specialized algorithms.
851 template<typename _Tp>
853 swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
856 template<typename _Tp, typename _Tp1>
857 inline shared_ptr<_Tp>
858 static_pointer_cast(const shared_ptr<_Tp1>& __r)
859 { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
861 template<typename _Tp, typename _Tp1>
862 inline shared_ptr<_Tp>
863 const_pointer_cast(const shared_ptr<_Tp1>& __r)
864 { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
866 template<typename _Tp, typename _Tp1>
867 inline shared_ptr<_Tp>
868 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
869 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
872 // The actual weak_ptr, with forwarding constructors and
873 // assignment operators.
874 template<typename _Tp>
876 : public __weak_ptr<_Tp>
880 : __weak_ptr<_Tp>() { }
882 template<typename _Tp1>
883 weak_ptr(const weak_ptr<_Tp1>& __r)
884 : __weak_ptr<_Tp>(__r) { }
886 template<typename _Tp1>
887 weak_ptr(const shared_ptr<_Tp1>& __r)
888 : __weak_ptr<_Tp>(__r) { }
890 template<typename _Tp1>
892 operator=(const weak_ptr<_Tp1>& __r) // never throws
894 this->__weak_ptr<_Tp>::operator=(__r);
898 template<typename _Tp1>
900 operator=(const shared_ptr<_Tp1>& __r) // never throws
902 this->__weak_ptr<_Tp>::operator=(__r);
907 lock() const // never throws
911 return shared_ptr<_Tp>();
915 return shared_ptr<_Tp>(*this);
917 __catch(const bad_weak_ptr&)
919 return shared_ptr<_Tp>();
922 return this->expired() ? shared_ptr<_Tp>()
923 : shared_ptr<_Tp>(*this);
928 template<typename _Tp>
929 class enable_shared_from_this
932 enable_shared_from_this() { }
934 enable_shared_from_this(const enable_shared_from_this&) { }
936 enable_shared_from_this&
937 operator=(const enable_shared_from_this&)
940 ~enable_shared_from_this() { }
945 { return shared_ptr<_Tp>(this->_M_weak_this); }
947 shared_ptr<const _Tp>
948 shared_from_this() const
949 { return shared_ptr<const _Tp>(this->_M_weak_this); }
952 template<typename _Tp1>
954 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
955 { _M_weak_this._M_assign(__p, __n); }
957 template<typename _Tp1>
959 __enable_shared_from_this_helper(const __shared_count<>& __pn,
960 const enable_shared_from_this* __pe,
964 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
967 mutable weak_ptr<_Tp> _M_weak_this;
972 #endif // _TR1_SHARED_PTR_H