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
61 template<
typename _Ptr,
typename _Deleter, _Lock_policy _Lp>
62 class _Sp_counted_base_impl
63 :
public _Sp_counted_base<_Lp>
70 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
71 : _M_ptr(__p), _M_del(__d) { }
79 {
return __ti ==
typeid(_Deleter) ? &_M_del : 0; }
82 _Sp_counted_base_impl(
const _Sp_counted_base_impl&);
83 _Sp_counted_base_impl& operator=(
const _Sp_counted_base_impl&);
89 template<_Lock_policy _Lp = __default_lock_policy>
92 template<
typename _Tp>
95 typedef void result_type;
96 typedef _Tp* argument_type;
97 void operator()(_Tp* __p)
const {
delete __p; }
100 template<_Lock_policy _Lp = __default_lock_policy>
108 template<
typename _Ptr>
109 __shared_count(_Ptr __p) : _M_pi(0)
113 typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
114 _M_pi =
new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
115 __p, _Sp_deleter<_Tp>());
120 __throw_exception_again;
124 template<
typename _Ptr,
typename _Deleter>
125 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
129 _M_pi =
new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
134 __throw_exception_again;
139 template<
typename _Tp>
142 : _M_pi(new _Sp_counted_base_impl<_Tp*,
143 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
148 __shared_count(
const __weak_count<_Lp>& __r);
156 __shared_count(
const __shared_count& __r)
160 _M_pi->_M_add_ref_copy();
164 operator=(
const __shared_count& __r)
166 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
170 __tmp->_M_add_ref_copy();
179 _M_swap(__shared_count& __r)
181 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
187 _M_get_use_count() const
188 {
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
192 {
return this->_M_get_use_count() == 1; }
195 operator==(
const __shared_count& __a,
const __shared_count& __b)
196 {
return __a._M_pi == __b._M_pi; }
199 operator<(
const __shared_count& __a,
const __shared_count& __b)
204 {
return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
207 friend class __weak_count<_Lp>;
209 _Sp_counted_base<_Lp>* _M_pi;
213 template<_Lock_policy _Lp>
221 __weak_count(
const __shared_count<_Lp>& __r)
225 _M_pi->_M_weak_add_ref();
228 __weak_count(
const __weak_count<_Lp>& __r)
232 _M_pi->_M_weak_add_ref();
238 _M_pi->_M_weak_release();
242 operator=(
const __shared_count<_Lp>& __r)
244 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
246 __tmp->_M_weak_add_ref();
248 _M_pi->_M_weak_release();
254 operator=(
const __weak_count<_Lp>& __r)
256 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
258 __tmp->_M_weak_add_ref();
260 _M_pi->_M_weak_release();
266 _M_swap(__weak_count<_Lp>& __r)
268 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
274 _M_get_use_count() const
275 {
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
278 operator==(
const __weak_count<_Lp>& __a,
const __weak_count<_Lp>& __b)
279 {
return __a._M_pi == __b._M_pi; }
282 operator<(const __weak_count<_Lp>& __a,
const __weak_count<_Lp>& __b)
286 friend class __shared_count<_Lp>;
288 _Sp_counted_base<_Lp>* _M_pi;
292 template<_Lock_policy _Lp>
294 __shared_count<_Lp>::
295 __shared_count(
const __weak_count<_Lp>& __r)
299 _M_pi->_M_add_ref_lock();
301 __throw_bad_weak_ptr();
305 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
308 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
311 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
312 class __enable_shared_from_this;
314 template<
typename _Tp>
317 template<
typename _Tp>
320 template<
typename _Tp>
321 class enable_shared_from_this;
326 template<_Lock_policy _Lp,
typename _Tp1,
typename _Tp2>
328 __enable_shared_from_this_helper(
const __shared_count<_Lp>&,
329 const __enable_shared_from_this<_Tp1,
333 template<
typename _Tp1,
typename _Tp2>
335 __enable_shared_from_this_helper(
const __shared_count<>&,
336 const enable_shared_from_this<_Tp1>*,
339 template<_Lock_policy _Lp>
341 __enable_shared_from_this_helper(
const __shared_count<_Lp>&, ...)
345 struct __static_cast_tag { };
346 struct __const_cast_tag { };
347 struct __dynamic_cast_tag { };
356 template<
typename _Tp, _Lock_policy _Lp>
360 typedef _Tp element_type;
366 : _M_ptr(0), _M_refcount()
374 template<
typename _Tp1>
376 __shared_ptr(_Tp1* __p)
377 : _M_ptr(__p), _M_refcount(__p)
379 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
381 __enable_shared_from_this_helper(_M_refcount, __p, __p);
397 template<typename _Tp1, typename _Deleter>
398 __shared_ptr(_Tp1* __p, _Deleter __d)
399 : _M_ptr(__p), _M_refcount(__p, __d)
401 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
403 __enable_shared_from_this_helper(_M_refcount, __p, __p);
414 template<typename _Tp1>
415 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
416 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
417 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
426 template<
typename _Tp1>
428 __shared_ptr(
const __weak_ptr<_Tp1, _Lp>& __r)
429 : _M_refcount(__r._M_refcount)
431 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
437 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
441 template<
typename _Tp1>
444 : _M_ptr(__r.get()), _M_refcount()
446 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
448 _Tp1* __tmp = __r.get();
449 _M_refcount = __shared_count<_Lp>(__r);
450 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
455 template<
typename _Tp1>
456 __shared_ptr(
const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
457 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
458 _M_refcount(__r._M_refcount)
461 template<
typename _Tp1>
462 __shared_ptr(
const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
463 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
464 _M_refcount(__r._M_refcount)
467 template<
typename _Tp1>
468 __shared_ptr(
const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
469 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
470 _M_refcount(__r._M_refcount)
473 _M_refcount = __shared_count<_Lp>();
476 template<
typename _Tp1>
478 operator=(
const __shared_ptr<_Tp1, _Lp>& __r)
481 _M_refcount = __r._M_refcount;
485 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
486 template<
typename _Tp1>
490 __shared_ptr(__r).swap(*
this);
497 { __shared_ptr().swap(*
this); }
499 template<
typename _Tp1>
504 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
505 __shared_ptr(__p).swap(*
this);
508 template<
typename _Tp1,
typename _Deleter>
510 reset(_Tp1* __p, _Deleter __d)
511 { __shared_ptr(__p, __d).swap(*
this); }
514 typename std::tr1::add_reference<_Tp>::type
517 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
524 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
534 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
537 operator __unspecified_bool_type() const
538 {
return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
542 {
return _M_refcount._M_unique(); }
546 {
return _M_refcount._M_get_use_count(); }
549 swap(__shared_ptr<_Tp, _Lp>& __other)
551 std::swap(_M_ptr, __other._M_ptr);
552 _M_refcount._M_swap(__other._M_refcount);
558 {
return _M_refcount._M_get_deleter(__ti); }
560 template<
typename _Tp1, _Lock_policy _Lp1>
562 _M_less(
const __shared_ptr<_Tp1, _Lp1>& __rhs)
const
563 {
return _M_refcount < __rhs._M_refcount; }
565 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
566 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
568 template<
typename _Del,
typename _Tp1, _Lock_policy _Lp1>
569 friend _Del* get_deleter(
const __shared_ptr<_Tp1, _Lp1>&);
572 template<
typename _Tp1>
574 operator==(
const __shared_ptr& __a,
const __shared_ptr<_Tp1, _Lp>& __b)
575 {
return __a.get() == __b.get(); }
577 template<
typename _Tp1>
579 operator!=(
const __shared_ptr& __a,
const __shared_ptr<_Tp1, _Lp>& __b)
580 {
return __a.get() != __b.get(); }
582 template<
typename _Tp1>
584 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
585 {
return __a._M_less(__b); }
588 __shared_count<_Lp> _M_refcount;
592 template<
typename _Tp, _Lock_policy _Lp>
594 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
603 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
604 inline __shared_ptr<_Tp, _Lp>
605 static_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r)
606 {
return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
613 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
614 inline __shared_ptr<_Tp, _Lp>
615 const_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r)
616 {
return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
623 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
624 inline __shared_ptr<_Tp, _Lp>
625 dynamic_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r)
626 {
return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
629 template<
typename _Ch,
typename _Tr,
typename _Tp, _Lock_policy _Lp>
631 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
632 const __shared_ptr<_Tp, _Lp>& __p)
639 template<
typename _Del,
typename _Tp, _Lock_policy _Lp>
641 get_deleter(
const __shared_ptr<_Tp, _Lp>& __p)
642 {
return static_cast<_Del*
>(__p._M_get_deleter(
typeid(_Del))); }
645 template<
typename _Tp, _Lock_policy _Lp>
649 typedef _Tp element_type;
652 : _M_ptr(0), _M_refcount()
671 template<
typename _Tp1>
672 __weak_ptr(
const __weak_ptr<_Tp1, _Lp>& __r)
673 : _M_refcount(__r._M_refcount)
675 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
676 _M_ptr = __r.
lock().get();
679 template<typename _Tp1>
680 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
681 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
682 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
684 template<
typename _Tp1>
686 operator=(
const __weak_ptr<_Tp1, _Lp>& __r)
688 _M_ptr = __r.lock().get();
689 _M_refcount = __r._M_refcount;
693 template<
typename _Tp1>
695 operator=(
const __shared_ptr<_Tp1, _Lp>& __r)
698 _M_refcount = __r._M_refcount;
702 __shared_ptr<_Tp, _Lp>
708 return __shared_ptr<element_type, _Lp>();
712 return __shared_ptr<element_type, _Lp>(*this);
714 __catch(
const bad_weak_ptr&)
719 return __shared_ptr<element_type, _Lp>();
724 return expired() ? __shared_ptr<element_type, _Lp>()
725 : __shared_ptr<element_type, _Lp>(*
this);
732 {
return _M_refcount._M_get_use_count(); }
736 {
return _M_refcount._M_get_use_count() == 0; }
740 { __weak_ptr().swap(*
this); }
743 swap(__weak_ptr& __s)
745 std::swap(_M_ptr, __s._M_ptr);
746 _M_refcount._M_swap(__s._M_refcount);
752 _M_assign(_Tp* __ptr,
const __shared_count<_Lp>& __refcount)
755 _M_refcount = __refcount;
758 template<
typename _Tp1>
760 _M_less(
const __weak_ptr<_Tp1, _Lp>& __rhs)
const
761 {
return _M_refcount < __rhs._M_refcount; }
763 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
764 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
765 friend class __enable_shared_from_this<_Tp, _Lp>;
766 friend class enable_shared_from_this<_Tp>;
769 template<
typename _Tp1>
771 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
772 {
return __lhs._M_less(__rhs); }
775 __weak_count<_Lp> _M_refcount;
779 template<
typename _Tp, _Lock_policy _Lp>
781 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
785 template<
typename _Tp, _Lock_policy _Lp>
786 class __enable_shared_from_this
789 __enable_shared_from_this() { }
791 __enable_shared_from_this(
const __enable_shared_from_this&) { }
793 __enable_shared_from_this&
794 operator=(
const __enable_shared_from_this&)
797 ~__enable_shared_from_this() { }
800 __shared_ptr<_Tp, _Lp>
802 {
return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
804 __shared_ptr<const _Tp, _Lp>
805 shared_from_this()
const
806 {
return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
809 template<
typename _Tp1>
811 _M_weak_assign(_Tp1* __p,
const __shared_count<_Lp>& __n)
const
812 { _M_weak_this._M_assign(__p, __n); }
814 template<
typename _Tp1>
816 __enable_shared_from_this_helper(
const __shared_count<_Lp>& __pn,
817 const __enable_shared_from_this* __pe,
821 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
824 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
831 template<
typename _Tp>
833 :
public __shared_ptr<_Tp>
837 : __shared_ptr<_Tp>() { }
839 template<
typename _Tp1>
841 shared_ptr(_Tp1* __p)
842 : __shared_ptr<_Tp>(__p) { }
844 template<
typename _Tp1,
typename _Deleter>
845 shared_ptr(_Tp1* __p, _Deleter __d)
846 : __shared_ptr<_Tp>(__p, __d) { }
848 template<
typename _Tp1>
849 shared_ptr(
const shared_ptr<_Tp1>& __r)
850 : __shared_ptr<_Tp>(__r) { }
852 template<
typename _Tp1>
854 shared_ptr(
const weak_ptr<_Tp1>& __r)
855 : __shared_ptr<_Tp>(__r) { }
857 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
858 template<
typename _Tp1>
861 : __shared_ptr<_Tp>(__r) { }
864 template<
typename _Tp1>
865 shared_ptr(
const shared_ptr<_Tp1>& __r, __static_cast_tag)
866 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
868 template<
typename _Tp1>
869 shared_ptr(
const shared_ptr<_Tp1>& __r, __const_cast_tag)
870 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
872 template<
typename _Tp1>
873 shared_ptr(
const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
874 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
876 template<
typename _Tp1>
878 operator=(
const shared_ptr<_Tp1>& __r)
880 this->__shared_ptr<_Tp>::operator=(__r);
884 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
885 template<
typename _Tp1>
889 this->__shared_ptr<_Tp>::operator=(__r);
896 template<
typename _Tp>
898 swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
901 template<
typename _Tp,
typename _Tp1>
902 inline shared_ptr<_Tp>
903 static_pointer_cast(
const shared_ptr<_Tp1>& __r)
904 {
return shared_ptr<_Tp>(__r, __static_cast_tag()); }
906 template<
typename _Tp,
typename _Tp1>
907 inline shared_ptr<_Tp>
908 const_pointer_cast(
const shared_ptr<_Tp1>& __r)
909 {
return shared_ptr<_Tp>(__r, __const_cast_tag()); }
911 template<
typename _Tp,
typename _Tp1>
912 inline shared_ptr<_Tp>
913 dynamic_pointer_cast(
const shared_ptr<_Tp1>& __r)
914 {
return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
920 template<
typename _Tp>
922 :
public __weak_ptr<_Tp>
926 : __weak_ptr<_Tp>() { }
928 template<
typename _Tp1>
929 weak_ptr(
const weak_ptr<_Tp1>& __r)
930 : __weak_ptr<_Tp>(__r) { }
932 template<
typename _Tp1>
933 weak_ptr(
const shared_ptr<_Tp1>& __r)
934 : __weak_ptr<_Tp>(__r) { }
936 template<
typename _Tp1>
938 operator=(
const weak_ptr<_Tp1>& __r)
940 this->__weak_ptr<_Tp>::operator=(__r);
944 template<
typename _Tp1>
946 operator=(
const shared_ptr<_Tp1>& __r)
948 this->__weak_ptr<_Tp>::operator=(__r);
957 return shared_ptr<_Tp>();
961 return shared_ptr<_Tp>(*this);
963 __catch(
const bad_weak_ptr&)
965 return shared_ptr<_Tp>();
968 return this->expired() ? shared_ptr<_Tp>()
969 : shared_ptr<_Tp>(*
this);
975 template<
typename _Tp>
976 class enable_shared_from_this
979 enable_shared_from_this() { }
981 enable_shared_from_this(
const enable_shared_from_this&) { }
983 enable_shared_from_this&
984 operator=(
const enable_shared_from_this&)
987 ~enable_shared_from_this() { }
992 {
return shared_ptr<_Tp>(this->_M_weak_this); }
994 shared_ptr<const _Tp>
995 shared_from_this()
const
996 {
return shared_ptr<const _Tp>(this->_M_weak_this); }
999 template<
typename _Tp1>
1001 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const
1002 { _M_weak_this._M_assign(__p, __n); }
1004 template<
typename _Tp1>
1006 __enable_shared_from_this_helper(
const __shared_count<>& __pn,
1007 const enable_shared_from_this* __pe,
1011 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1014 mutable weak_ptr<_Tp> _M_weak_this;
1020 #endif // _TR1_SHARED_PTR_H