enable_shared_from_this-related fixes.

[SVN r16341]
This commit is contained in:
Peter Dimov
2002-11-20 12:38:51 +00:00
parent 4b200e9847
commit 804b1483c7
4 changed files with 42 additions and 35 deletions

View File

@ -72,7 +72,10 @@ int main()
return boost::report_errors(); return boost::report_errors();
} }
class impl: public X, public Y, public boost::enable_shared_from_this<impl> // virtual inheritance from Y to stress the implementation
// (prevents Y* -> impl* casts)
class impl: public X, public virtual Y, public boost::enable_shared_from_this<impl>
{ {
public: public:
@ -88,8 +91,14 @@ public:
} }
}; };
// intermediate impl2 to stress the implementation
class impl2: public impl
{
};
boost::shared_ptr<Y> createY() boost::shared_ptr<Y> createY()
{ {
boost::shared_ptr<impl> pi(new impl); boost::shared_ptr<Y> pi(new impl2);
return pi; return pi;
} }

View File

@ -28,28 +28,20 @@ public:
shared_ptr<T> shared_from_this() shared_ptr<T> shared_from_this()
{ {
shared_ptr<T> p(weak_this); shared_ptr<T> p(_internal_weak_this);
BOOST_ASSERT(p.get() == this); BOOST_ASSERT(p.get() == this);
return p; return p;
} }
shared_ptr<T const> shared_from_this() const shared_ptr<T const> shared_from_this() const
{ {
shared_ptr<T const> p(weak_this); shared_ptr<T const> p(_internal_weak_this);
BOOST_ASSERT(p.get() == this); BOOST_ASSERT(p.get() == this);
return p; return p;
} }
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS typedef T _internal_element_type; // for bcc 5.5.1
weak_ptr<_internal_element_type> _internal_weak_this;
private:
template<class Y> friend class shared_ptr;
#endif
typedef T element_type; // for bcc 5.5.1
weak_ptr<element_type> weak_this;
}; };
} // namespace boost } // namespace boost

View File

@ -39,6 +39,9 @@
namespace boost namespace boost
{ {
template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
namespace detail namespace detail
{ {
@ -65,6 +68,17 @@ template<> struct shared_ptr_traits<void const>
#endif #endif
// enable_shared_from_this support
template<class T, class Y> void sp_enable_shared_from_this(boost::enable_shared_from_this<T> * pe, Y * px, shared_count const & pn)
{
pe->_internal_weak_this._internal_assign(px, pn);
}
void sp_enable_shared_from_this(void const *, void const *, shared_count const &)
{
}
} // namespace detail } // namespace detail
@ -76,9 +90,6 @@ template<> struct shared_ptr_traits<void const>
// is destroyed or reset. // is destroyed or reset.
// //
template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
template<class T> class shared_ptr template<class T> class shared_ptr
{ {
private: private:
@ -86,17 +97,6 @@ private:
// Borland 5.5.1 specific workaround // Borland 5.5.1 specific workaround
typedef shared_ptr<T> this_type; typedef shared_ptr<T> this_type;
// enable_shared_from_this support
template<class Y> void sp_enable_shared_from_this(boost::enable_shared_from_this<Y> * q)
{
q->weak_this = *this;
}
void sp_enable_shared_from_this(void *)
{
}
public: public:
typedef T element_type; typedef T element_type;
@ -111,7 +111,7 @@ public:
template<class Y> template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete
{ {
sp_enable_shared_from_this(p); detail::sp_enable_shared_from_this(p, p, pn);
} }
// //
@ -122,7 +122,7 @@ public:
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d) template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
{ {
sp_enable_shared_from_this(p); detail::sp_enable_shared_from_this(p, p, pn);
} }
// generated copy constructor, assignment, destructor are fine... // generated copy constructor, assignment, destructor are fine...
@ -179,7 +179,7 @@ public:
{ {
Y * tmp = r.get(); Y * tmp = r.get();
pn = detail::shared_count(r); pn = detail::shared_count(r);
sp_enable_shared_from_this(tmp); detail::sp_enable_shared_from_this(tmp, tmp, pn);
} }
#endif #endif
@ -270,7 +270,7 @@ public:
pn.swap(other.pn); pn.swap(other.pn);
} }
bool less(this_type const & rhs) const // implementation detail, never throws bool _internal_less(this_type const & rhs) const // implementation detail, never throws
{ {
return pn < rhs.pn; return pn < rhs.pn;
} }
@ -316,7 +316,7 @@ template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T>
template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b) template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
{ {
return a.less(b); return a._internal_less(b);
} }
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)

View File

@ -92,7 +92,13 @@ public:
pn.swap(other.pn); pn.swap(other.pn);
} }
bool less(this_type const & rhs) const // implementation detail, never throws void _internal_assign(T * px2, detail::shared_count const & pn2) // implementation detail
{
px = px2;
pn = pn2;
}
bool _internal_less(this_type const & rhs) const // implementation detail, never throws
{ {
return pn < rhs.pn; return pn < rhs.pn;
} }
@ -116,7 +122,7 @@ private:
template<class T> inline bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b) template<class T> inline bool operator<(weak_ptr<T> const & a, weak_ptr<T> const & b)
{ {
return a.less(b); return a._internal_less(b);
} }
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)