forked from boostorg/smart_ptr
shared_ptr now autodetects counted_bases; minor test updates; intrusive_ptr no longer calls addref/release for NULL pointers.
[SVN r13602]
This commit is contained in:
@ -169,12 +169,12 @@ private:
|
|||||||
|
|
||||||
inline void intrusive_ptr_add_ref(counted_base * p)
|
inline void intrusive_ptr_add_ref(counted_base * p)
|
||||||
{
|
{
|
||||||
if(p != 0) p->add_ref();
|
p->add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void intrusive_ptr_release(counted_base * p)
|
inline void intrusive_ptr_release(counted_base * p)
|
||||||
{
|
{
|
||||||
if(p != 0) p->release();
|
p->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@ -215,6 +215,8 @@ private:
|
|||||||
|
|
||||||
friend class weak_count;
|
friend class weak_count;
|
||||||
|
|
||||||
|
template<class P, class D> shared_count(P, D, counted_base const *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
shared_count(): pi_(new counted_base(1, 1))
|
shared_count(): pi_(new counted_base(1, 1))
|
||||||
@ -226,7 +228,7 @@ public:
|
|||||||
pi_->add_ref();
|
pi_->add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class P, class D> shared_count(P p, D d): pi_(0)
|
template<class P, class D> shared_count(P p, D d, void const * = 0): pi_(0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -239,6 +241,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class P, class D> shared_count(P, D, counted_base * pi): pi_(pi)
|
||||||
|
{
|
||||||
|
pi_->add_ref();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
// auto_ptr<Y> is special cased to provide the strong guarantee
|
// auto_ptr<Y> is special cased to provide the strong guarantee
|
||||||
|
@ -33,7 +33,8 @@ namespace boost
|
|||||||
//
|
//
|
||||||
// void intrusive_ptr_add_ref(T * p);
|
// void intrusive_ptr_add_ref(T * p);
|
||||||
// void intrusive_ptr_release(T * p);
|
// void intrusive_ptr_release(T * p);
|
||||||
// (note: p may be 0!)
|
//
|
||||||
|
// (p != 0)
|
||||||
//
|
//
|
||||||
// The object is responsible for destroying itself.
|
// The object is responsible for destroying itself.
|
||||||
//
|
//
|
||||||
@ -52,26 +53,26 @@ public:
|
|||||||
|
|
||||||
intrusive_ptr(T * p): p_(p)
|
intrusive_ptr(T * p): p_(p)
|
||||||
{
|
{
|
||||||
intrusive_ptr_add_ref(p_);
|
if(p_ != 0) intrusive_ptr_add_ref(p_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~intrusive_ptr()
|
~intrusive_ptr()
|
||||||
{
|
{
|
||||||
intrusive_ptr_release(p_);
|
if(p_ != 0) intrusive_ptr_release(p_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
||||||
|
|
||||||
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
|
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
|
||||||
{
|
{
|
||||||
intrusive_ptr_add_ref(p_);
|
if(p_ != 0) intrusive_ptr_add_ref(p_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
|
intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
|
||||||
{
|
{
|
||||||
intrusive_ptr_add_ref(p_);
|
if(p_ != 0) intrusive_ptr_add_ref(p_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
||||||
|
@ -87,7 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Y>
|
template<typename 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>(), p) // Y must be complete
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ struct X
|
|||||||
std::cout << "X(" << this << ")::X()\n";
|
std::cout << "X(" << this << ")::X()\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~X()
|
~X() // virtual destructor deliberately omitted
|
||||||
{
|
{
|
||||||
--cnt;
|
--cnt;
|
||||||
std::cout << "X(" << this << ")::~X()\n";
|
std::cout << "X(" << this << ")::~X()\n";
|
||||||
@ -96,6 +96,28 @@ void release_object(int * p)
|
|||||||
std::cout << "release_object()\n";
|
std::cout << "release_object()\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Z: public virtual boost::counted_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Z()
|
||||||
|
{
|
||||||
|
++cnt;
|
||||||
|
std::cout << "Z(" << this << ")::Z()\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
~Z()
|
||||||
|
{
|
||||||
|
--cnt;
|
||||||
|
std::cout << "Z(" << this << ")::~Z()\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Z(Z const &);
|
||||||
|
Z & operator= (Z const &);
|
||||||
|
};
|
||||||
|
|
||||||
template<class T> void test_is_X(boost::shared_ptr<T> const & p)
|
template<class T> void test_is_X(boost::shared_ptr<T> const & p)
|
||||||
{
|
{
|
||||||
BOOST_TEST(p->id() == 1);
|
BOOST_TEST(p->id() == 1);
|
||||||
@ -244,7 +266,7 @@ int test_main(int, char * [])
|
|||||||
test_is_nonzero(boost::make_shared(wp2));
|
test_is_nonzero(boost::make_shared(wp2));
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_ptr<Y> wp3 = shared_dynamic_cast<Y>(boost::make_shared(wp2));
|
weak_ptr<Y> wp3 = shared_dynamic_cast<Y>(boost::make_shared(wp2));
|
||||||
|
|
||||||
BOOST_TEST(wp3.use_count() == 1);
|
BOOST_TEST(wp3.use_count() == 1);
|
||||||
BOOST_TEST(wp3.get() != 0);
|
BOOST_TEST(wp3.get() != 0);
|
||||||
@ -302,7 +324,17 @@ int test_main(int, char * [])
|
|||||||
BOOST_TEST(b1 == (wp1 < wp5));
|
BOOST_TEST(b1 == (wp1 < wp5));
|
||||||
BOOST_TEST(b2 == (wp5 < wp1));
|
BOOST_TEST(b2 == (wp5 < wp1));
|
||||||
|
|
||||||
shared_ptr<int> p6(get_object(), release_object);
|
{
|
||||||
|
// note that both get_object and release_object deal with int*
|
||||||
|
shared_ptr<void> p6(get_object(), release_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// test intrusive counting
|
||||||
|
boost::shared_ptr<void> pv(new Z);
|
||||||
|
boost::shared_ptr<Z> pz = boost::shared_static_cast<Z>(pv);
|
||||||
|
BOOST_TEST(pz.use_count() == pz->use_count());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_TEST(cnt == 0);
|
BOOST_TEST(cnt == 0);
|
||||||
|
Reference in New Issue
Block a user