forked from boostorg/smart_ptr
Major changes to shared_ptr and weak_ptr
[SVN r16314]
This commit is contained in:
@ -40,7 +40,7 @@ namespace boost
|
|||||||
|
|
||||||
// The standard library that comes with Borland C++ 5.5.1
|
// The standard library that comes with Borland C++ 5.5.1
|
||||||
// defines std::exception and its members as having C calling
|
// defines std::exception and its members as having C calling
|
||||||
// convention (-pc). When the definition of use_count_is_zero
|
// convention (-pc). When the definition of bad_weak_ptr
|
||||||
// is compiled with -ps, the compiler issues an error.
|
// is compiled with -ps, the compiler issues an error.
|
||||||
// Hence, the temporary #pragma option -pc below. The version
|
// Hence, the temporary #pragma option -pc below. The version
|
||||||
// check is deliberately conservative.
|
// check is deliberately conservative.
|
||||||
@ -49,13 +49,13 @@ namespace boost
|
|||||||
# pragma option push -pc
|
# pragma option push -pc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class use_count_is_zero: public std::exception
|
class bad_weak_ptr: public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual char const * what() const throw()
|
virtual char const * what() const throw()
|
||||||
{
|
{
|
||||||
return "boost::use_count_is_zero";
|
return "boost::bad_weak_ptr";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,6 +63,9 @@ public:
|
|||||||
# pragma option pop
|
# pragma option pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
class counted_base
|
class counted_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -109,50 +112,36 @@ public:
|
|||||||
|
|
||||||
void add_ref()
|
void add_ref()
|
||||||
{
|
{
|
||||||
#ifdef BOOST_HAS_THREADS
|
#if defined(BOOST_HAS_THREADS)
|
||||||
mutex_type::scoped_lock lock(mtx_);
|
mutex_type::scoped_lock lock(mtx_);
|
||||||
#endif
|
#endif
|
||||||
if(use_count_ == 0 && weak_count_ != 0) boost::throw_exception(boost::use_count_is_zero());
|
if(use_count_ == 0 && weak_count_ != 0) boost::throw_exception(boost::bad_weak_ptr());
|
||||||
++use_count_;
|
++use_count_;
|
||||||
++weak_count_;
|
++weak_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void release() // nothrow
|
void release() // nothrow
|
||||||
{
|
{
|
||||||
long new_use_count;
|
|
||||||
long new_weak_count = 0;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef BOOST_HAS_THREADS
|
#if defined(BOOST_HAS_THREADS)
|
||||||
mutex_type::scoped_lock lock(mtx_);
|
mutex_type::scoped_lock lock(mtx_);
|
||||||
#endif
|
#endif
|
||||||
new_use_count = --use_count_;
|
long new_use_count = --use_count_;
|
||||||
|
|
||||||
if(new_use_count != 0)
|
if(new_use_count != 0)
|
||||||
{
|
{
|
||||||
new_weak_count = --weak_count_;
|
--weak_count_;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_use_count == 0)
|
dispose();
|
||||||
{
|
weak_release();
|
||||||
dispose();
|
|
||||||
|
|
||||||
#ifdef BOOST_HAS_THREADS
|
|
||||||
mutex_type::scoped_lock lock(mtx_);
|
|
||||||
#endif
|
|
||||||
new_weak_count = --weak_count_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(new_weak_count == 0)
|
|
||||||
{
|
|
||||||
destruct();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void weak_add_ref() // nothrow
|
void weak_add_ref() // nothrow
|
||||||
{
|
{
|
||||||
#ifdef BOOST_HAS_THREADS
|
#if defined(BOOST_HAS_THREADS)
|
||||||
mutex_type::scoped_lock lock(mtx_);
|
mutex_type::scoped_lock lock(mtx_);
|
||||||
#endif
|
#endif
|
||||||
++weak_count_;
|
++weak_count_;
|
||||||
@ -163,7 +152,7 @@ public:
|
|||||||
long new_weak_count;
|
long new_weak_count;
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef BOOST_HAS_THREADS
|
#if defined(BOOST_HAS_THREADS)
|
||||||
mutex_type::scoped_lock lock(mtx_);
|
mutex_type::scoped_lock lock(mtx_);
|
||||||
#endif
|
#endif
|
||||||
new_weak_count = --weak_count_;
|
new_weak_count = --weak_count_;
|
||||||
@ -177,7 +166,7 @@ public:
|
|||||||
|
|
||||||
long use_count() const // nothrow
|
long use_count() const // nothrow
|
||||||
{
|
{
|
||||||
#ifdef BOOST_HAS_THREADS
|
#if defined(BOOST_HAS_THREADS)
|
||||||
mutex_type::scoped_lock lock(mtx_);
|
mutex_type::scoped_lock lock(mtx_);
|
||||||
#endif
|
#endif
|
||||||
return use_count_;
|
return use_count_;
|
||||||
@ -193,29 +182,16 @@ private:
|
|||||||
long use_count_;
|
long use_count_;
|
||||||
long weak_count_;
|
long weak_count_;
|
||||||
|
|
||||||
#ifdef BOOST_HAS_THREADS
|
#if defined(BOOST_HAS_THREADS)
|
||||||
mutable mutex_type mtx_;
|
mutable mutex_type mtx_;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void intrusive_ptr_add_ref(counted_base * p)
|
|
||||||
{
|
|
||||||
p->add_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void intrusive_ptr_release(counted_base * p)
|
|
||||||
{
|
|
||||||
p->release();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Borland's Codeguard trips up over the -Vx- option here:
|
// Borland's Codeguard trips up over the -Vx- option here:
|
||||||
//
|
//
|
||||||
#ifdef __CODEGUARD__
|
#ifdef __CODEGUARD__
|
||||||
#pragma option push -Vx-
|
# pragma option push -Vx-
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class P, class D> class counted_base_impl: public counted_base
|
template<class P, class D> class counted_base_impl: public counted_base
|
||||||
@ -273,16 +249,11 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
shared_count(): pi_(new counted_base(1, 1))
|
shared_count(): pi_(0) // (new counted_base(1, 1))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit shared_count(counted_base * pi): pi_(pi) // never throws
|
template<class P, class D> shared_count(P p, D d): pi_(0)
|
||||||
{
|
|
||||||
pi_->add_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class P, class D> shared_count(P p, D d, void const * = 0): pi_(0)
|
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
@ -309,11 +280,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -328,21 +294,21 @@ public:
|
|||||||
|
|
||||||
~shared_count() // nothrow
|
~shared_count() // nothrow
|
||||||
{
|
{
|
||||||
pi_->release();
|
if(pi_ != 0) pi_->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||||
{
|
{
|
||||||
pi_->add_ref();
|
if(pi_ != 0) pi_->add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit shared_count(weak_count const & r); // throws use_count_is_zero when r.use_count() == 0
|
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
||||||
|
|
||||||
shared_count & operator= (shared_count const & r) // nothrow
|
shared_count & operator= (shared_count const & r) // nothrow
|
||||||
{
|
{
|
||||||
counted_base * tmp = r.pi_;
|
counted_base * tmp = r.pi_;
|
||||||
tmp->add_ref();
|
if(tmp != 0) tmp->add_ref();
|
||||||
pi_->release();
|
if(pi_ != 0) pi_->release();
|
||||||
pi_ = tmp;
|
pi_ = tmp;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -357,12 +323,12 @@ public:
|
|||||||
|
|
||||||
long use_count() const // nothrow
|
long use_count() const // nothrow
|
||||||
{
|
{
|
||||||
return pi_->use_count();
|
return pi_ != 0? pi_->use_count(): 42; // '42' is an example of 'unspecified'
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unique() const // nothrow
|
bool unique() const // nothrow
|
||||||
{
|
{
|
||||||
return pi_->use_count() == 1;
|
return use_count() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
||||||
@ -377,7 +343,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __CODEGUARD__
|
#ifdef __CODEGUARD__
|
||||||
#pragma option pop
|
# pragma option pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -391,30 +357,30 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
weak_count(): pi_(new counted_base(0, 1)) // can throw
|
weak_count(): pi_(0) // nothrow // (new counted_base(0, 1)) // can throw
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
||||||
{
|
{
|
||||||
pi_->weak_add_ref();
|
if(pi_ != 0) pi_->weak_add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
||||||
{
|
{
|
||||||
pi_->weak_add_ref();
|
if(pi_ != 0) pi_->weak_add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
~weak_count() // nothrow
|
~weak_count() // nothrow
|
||||||
{
|
{
|
||||||
pi_->weak_release();
|
if(pi_ != 0) pi_->weak_release();
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_count & operator= (shared_count const & r) // nothrow
|
weak_count & operator= (shared_count const & r) // nothrow
|
||||||
{
|
{
|
||||||
counted_base * tmp = r.pi_;
|
counted_base * tmp = r.pi_;
|
||||||
tmp->weak_add_ref();
|
if(tmp != 0) tmp->weak_add_ref();
|
||||||
pi_->weak_release();
|
if(pi_ != 0) pi_->weak_release();
|
||||||
pi_ = tmp;
|
pi_ = tmp;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -423,8 +389,8 @@ public:
|
|||||||
weak_count & operator= (weak_count const & r) // nothrow
|
weak_count & operator= (weak_count const & r) // nothrow
|
||||||
{
|
{
|
||||||
counted_base * tmp = r.pi_;
|
counted_base * tmp = r.pi_;
|
||||||
tmp->weak_add_ref();
|
if(tmp != 0) tmp->weak_add_ref();
|
||||||
pi_->weak_release();
|
if(pi_ != 0) pi_->weak_release();
|
||||||
pi_ = tmp;
|
pi_ = tmp;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -439,7 +405,7 @@ public:
|
|||||||
|
|
||||||
long use_count() const // nothrow
|
long use_count() const // nothrow
|
||||||
{
|
{
|
||||||
return pi_->use_count();
|
return pi_ != 0? pi_->use_count(): 804; // '804' is an example of 'unspecified'
|
||||||
}
|
}
|
||||||
|
|
||||||
friend inline bool operator==(weak_count const & a, weak_count const & b)
|
friend inline bool operator==(weak_count const & a, weak_count const & b)
|
||||||
@ -455,7 +421,7 @@ public:
|
|||||||
|
|
||||||
inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
|
inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
|
||||||
{
|
{
|
||||||
pi_->add_ref();
|
if(pi_ != 0) pi_->add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
51
include/boost/enable_shared_from_this.hpp
Normal file
51
include/boost/enable_shared_from_this.hpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||||
|
#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable_shared_from_this.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002 Peter Dimov
|
||||||
|
//
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class T> class enable_shared_from_this
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
shared_ptr<T> shared_from_this()
|
||||||
|
{
|
||||||
|
return shared_ptr<T>(weak_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<T const> shared_from_this() const
|
||||||
|
{
|
||||||
|
return shared_ptr<T const>(weak_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template<class Y> friend class shared_ptr;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
weak_ptr<T> weak_this;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
@ -76,8 +76,14 @@ template<> struct shared_ptr_traits<void const>
|
|||||||
// is destroyed or reset.
|
// is destroyed or reset.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if defined(BOOST_SP_ENABLE_CONSTRUCTOR_HOOK)
|
||||||
|
|
||||||
|
void shared_ptr_constructor_hook(void * p);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T> class weak_ptr;
|
template<class T> class weak_ptr;
|
||||||
template<class T> class intrusive_ptr;
|
template<class T> class enable_shared_from_this;
|
||||||
|
|
||||||
template<class T> class shared_ptr
|
template<class T> class shared_ptr
|
||||||
{
|
{
|
||||||
@ -87,18 +93,36 @@ private:
|
|||||||
// typedef checked_deleter<T> deleter;
|
// typedef checked_deleter<T> deleter;
|
||||||
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;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
typedef T * pointer;
|
||||||
|
typedef typename detail::shared_ptr_traits<T>::reference reference;
|
||||||
|
|
||||||
shared_ptr(): px(0), pn()
|
shared_ptr(): px(0), pn()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>(), p) // 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);
|
||||||
|
|
||||||
|
#if defined(BOOST_SP_ENABLE_CONSTRUCTOR_HOOK)
|
||||||
|
shared_ptr_constructor_hook(p);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -109,6 +133,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generated copy constructor, assignment, destructor are fine
|
// generated copy constructor, assignment, destructor are fine
|
||||||
@ -123,11 +148,6 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
shared_ptr(intrusive_ptr<Y> const & r): px(r.get()), pn(r.get()) // never throws
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
||||||
{
|
{
|
||||||
@ -154,8 +174,11 @@ public:
|
|||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn(r)
|
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
|
||||||
{
|
{
|
||||||
|
Y * tmp = r.get();
|
||||||
|
pn = detail::shared_count(r);
|
||||||
|
sp_enable_shared_from_this(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -199,7 +222,7 @@ public:
|
|||||||
this_type(p, d).swap(*this);
|
this_type(p, d).swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
typename detail::shared_ptr_traits<T>::reference operator* () const // never throws
|
reference operator* () const // never throws
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(px != 0);
|
BOOST_ASSERT(px != 0);
|
||||||
return *px;
|
return *px;
|
||||||
@ -246,6 +269,11 @@ public:
|
|||||||
pn.swap(other.pn);
|
pn.swap(other.pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool less(this_type const & rhs) const // implementation detail, never throws
|
||||||
|
{
|
||||||
|
return pn < rhs.pn;
|
||||||
|
}
|
||||||
|
|
||||||
// Tasteless as this may seem, making all members public allows member templates
|
// Tasteless as this may seem, making all members public allows member templates
|
||||||
// to work in the absence of member template friends. (Matthew Langston)
|
// to work in the absence of member template friends. (Matthew Langston)
|
||||||
|
|
||||||
@ -287,7 +315,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 std::less<T*>()(a.get(), b.get());
|
return a.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)
|
||||||
@ -295,6 +323,18 @@ template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
|||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
|
||||||
|
{
|
||||||
|
return shared_ptr<T>(r, detail::static_cast_tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
|
||||||
|
{
|
||||||
|
return shared_ptr<T>(r, detail::dynamic_cast_tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::static_cast_tag());
|
return shared_ptr<T>(r, detail::static_cast_tag());
|
||||||
@ -323,28 +363,6 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
|||||||
return p.get();
|
return p.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared_from_this() creates a shared_ptr from a raw pointer (usually 'this')
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
inline void sp_assert_counted_base(boost::counted_base const *)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline T * sp_remove_const(T const * p)
|
|
||||||
{
|
|
||||||
return const_cast<T *>(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<class T> shared_ptr<T> shared_from_this(T * p)
|
|
||||||
{
|
|
||||||
detail::sp_assert_counted_base(p);
|
|
||||||
return shared_ptr<T>(detail::sp_remove_const(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
|
@ -76,11 +76,6 @@ public:
|
|||||||
this_type().swap(*this);
|
this_type().swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
T * get() const // never throws; deprecated, removal pending, don't use
|
|
||||||
{
|
|
||||||
return pn.use_count() == 0? 0: px;
|
|
||||||
}
|
|
||||||
|
|
||||||
long use_count() const // never throws
|
long use_count() const // never throws
|
||||||
{
|
{
|
||||||
return pn.use_count();
|
return pn.use_count();
|
||||||
@ -119,27 +114,6 @@ private:
|
|||||||
|
|
||||||
}; // weak_ptr
|
}; // weak_ptr
|
||||||
|
|
||||||
template<class T, class U> inline bool operator==(weak_ptr<T> const & a, weak_ptr<U> const & b)
|
|
||||||
{
|
|
||||||
return a.get() == b.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class U> inline bool operator!=(weak_ptr<T> const & a, weak_ptr<U> const & b)
|
|
||||||
{
|
|
||||||
return a.get() != b.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
|
|
||||||
|
|
||||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
|
||||||
|
|
||||||
template<class T> inline bool operator!=(weak_ptr<T> const & a, weak_ptr<T> const & b)
|
|
||||||
{
|
|
||||||
return a.get() != b.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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.less(b);
|
||||||
@ -152,6 +126,8 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
|||||||
|
|
||||||
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r) // never throws
|
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r) // never throws
|
||||||
{
|
{
|
||||||
|
#if defined(BOOST_HAS_THREADS)
|
||||||
|
|
||||||
// optimization: avoid throw overhead
|
// optimization: avoid throw overhead
|
||||||
if(r.use_count() == 0)
|
if(r.use_count() == 0)
|
||||||
{
|
{
|
||||||
@ -162,15 +138,20 @@ template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r) // never thro
|
|||||||
{
|
{
|
||||||
return shared_ptr<T>(r);
|
return shared_ptr<T>(r);
|
||||||
}
|
}
|
||||||
catch(use_count_is_zero const &)
|
catch(bad_weak_ptr const &)
|
||||||
{
|
{
|
||||||
|
// Q: how can we get here?
|
||||||
|
// A: another thread may have invalidated r after the use_count test above.
|
||||||
return shared_ptr<T>();
|
return shared_ptr<T>();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Note: there is no get_pointer overload for weak_ptr.
|
#else
|
||||||
// This is intentional. Even get() will disappear in a
|
|
||||||
// future release; these accessors are too error-prone.
|
// optimization: avoid try/catch overhead when single threaded
|
||||||
|
return r.use_count() == 0? shared_ptr<T>(): shared_ptr<T>(r);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
2374
shared_ptr_test.cpp
2374
shared_ptr_test.cpp
File diff suppressed because it is too large
Load Diff
@ -24,11 +24,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
bool boost_error(char const *, char const *, char const *, long)
|
|
||||||
{
|
|
||||||
return true; // fail with assert()
|
|
||||||
}
|
|
||||||
|
|
||||||
class Incomplete;
|
class Incomplete;
|
||||||
|
|
||||||
Incomplete * get_ptr( boost::shared_ptr<Incomplete>& incomplete )
|
Incomplete * get_ptr( boost::shared_ptr<Incomplete>& incomplete )
|
||||||
@ -164,7 +159,6 @@ void test()
|
|||||||
cp.reset();
|
cp.reset();
|
||||||
BOOST_TEST( cp2.use_count() == 2 );
|
BOOST_TEST( cp2.use_count() == 2 );
|
||||||
BOOST_TEST( cp3.use_count() == 2 );
|
BOOST_TEST( cp3.use_count() == 2 );
|
||||||
BOOST_TEST( cp.use_count() == 1 );
|
|
||||||
cp.reset( new int );
|
cp.reset( new int );
|
||||||
*cp = 98765;
|
*cp = 98765;
|
||||||
BOOST_TEST( *cp == 98765 );
|
BOOST_TEST( *cp == 98765 );
|
||||||
|
Reference in New Issue
Block a user