forked from boostorg/smart_ptr
Add rvalue pointer casts (closes #66)
This commit is contained in:
@ -297,6 +297,8 @@ template<class T> T * get_pointer(intrusive_ptr<T> const & p) BOOST_SP_NOEXCEPT
|
|||||||
return p.get();
|
return p.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pointer casts
|
||||||
|
|
||||||
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
|
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
|
||||||
{
|
{
|
||||||
return static_cast<T *>(p.get());
|
return static_cast<T *>(p.get());
|
||||||
@ -312,6 +314,31 @@ template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U
|
|||||||
return dynamic_cast<T *>(p.get());
|
return dynamic_cast<T *>(p.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
template<class T, class U> intrusive_ptr<T> static_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
return intrusive_ptr<T>( static_cast<T*>( p.detach() ), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> intrusive_ptr<T> const_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
return intrusive_ptr<T>( const_cast<T*>( p.detach() ), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
|
||||||
|
{
|
||||||
|
T * p2 = dynamic_cast<T*>( p.get() );
|
||||||
|
|
||||||
|
intrusive_ptr<T> r( p2, false );
|
||||||
|
|
||||||
|
if( p2 ) p.detach();
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
// operator<<
|
// operator<<
|
||||||
|
|
||||||
#if !defined(BOOST_NO_IOSTREAM)
|
#if !defined(BOOST_NO_IOSTREAM)
|
||||||
|
@ -41,7 +41,7 @@ class base
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::detail::atomic_count use_count_;
|
mutable boost::detail::atomic_count use_count_;
|
||||||
|
|
||||||
base(base const &);
|
base(base const &);
|
||||||
base & operator=(base const &);
|
base & operator=(base const &);
|
||||||
@ -69,24 +69,24 @@ public:
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
|
|
||||||
inline friend void intrusive_ptr_add_ref(base * p)
|
inline friend void intrusive_ptr_add_ref(base const * p)
|
||||||
{
|
{
|
||||||
++p->use_count_;
|
++p->use_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline friend void intrusive_ptr_release(base * p)
|
inline friend void intrusive_ptr_release(base const * p)
|
||||||
{
|
{
|
||||||
if(--p->use_count_ == 0) delete p;
|
if(--p->use_count_ == 0) delete p;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void add_ref()
|
void add_ref() const
|
||||||
{
|
{
|
||||||
++use_count_;
|
++use_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void release()
|
void release() const
|
||||||
{
|
{
|
||||||
if(--use_count_ == 0) delete this;
|
if(--use_count_ == 0) delete this;
|
||||||
}
|
}
|
||||||
@ -103,12 +103,12 @@ long base::instances = 0;
|
|||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
inline void intrusive_ptr_add_ref(N::base * p)
|
inline void intrusive_ptr_add_ref(N::base const * p)
|
||||||
{
|
{
|
||||||
p->add_ref();
|
p->add_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void intrusive_ptr_release(N::base * p)
|
inline void intrusive_ptr_release(N::base const * p)
|
||||||
{
|
{
|
||||||
p->release();
|
p->release();
|
||||||
}
|
}
|
||||||
@ -209,6 +209,58 @@ int main()
|
|||||||
BOOST_TEST( N::base::instances == 0 );
|
BOOST_TEST( N::base::instances == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::intrusive_ptr<X> px( new Y );
|
||||||
|
|
||||||
|
X * px2 = px.get();
|
||||||
|
|
||||||
|
boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( std::move( px ) );
|
||||||
|
BOOST_TEST( py.get() == px2 );
|
||||||
|
BOOST_TEST( px.get() == 0 );
|
||||||
|
BOOST_TEST( py->use_count() == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( N::base::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::intrusive_ptr<X const> px( new X );
|
||||||
|
|
||||||
|
X const * px2 = px.get();
|
||||||
|
|
||||||
|
boost::intrusive_ptr<X> px3 = boost::const_pointer_cast<X>( std::move( px ) );
|
||||||
|
BOOST_TEST( px3.get() == px2 );
|
||||||
|
BOOST_TEST( px.get() == 0 );
|
||||||
|
BOOST_TEST( px3->use_count() == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( N::base::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::intrusive_ptr<X> px( new Y );
|
||||||
|
|
||||||
|
X * px2 = px.get();
|
||||||
|
|
||||||
|
boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( std::move( px ) );
|
||||||
|
BOOST_TEST( py.get() == px2 );
|
||||||
|
BOOST_TEST( px.get() == 0 );
|
||||||
|
BOOST_TEST( py->use_count() == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( N::base::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::intrusive_ptr<X> px( new X );
|
||||||
|
|
||||||
|
X * px2 = px.get();
|
||||||
|
|
||||||
|
boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( std::move( px ) );
|
||||||
|
BOOST_TEST( py.get() == 0 );
|
||||||
|
BOOST_TEST( px.get() == px2 );
|
||||||
|
BOOST_TEST( px->use_count() == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( N::base::instances == 0 );
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user