forked from boostorg/smart_ptr
intrusive_ptr.hpp added (still experimental)
[SVN r13526]
This commit is contained in:
@@ -41,9 +41,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
class counted_base
|
class counted_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -77,7 +74,7 @@ public:
|
|||||||
#ifdef BOOST_HAS_THREADS
|
#ifdef BOOST_HAS_THREADS
|
||||||
lightweight_mutex::scoped_lock lock(mtx_);
|
lightweight_mutex::scoped_lock lock(mtx_);
|
||||||
#endif
|
#endif
|
||||||
if(use_count_ == 0) throw use_count_is_zero();
|
if(use_count_ == 0 && weak_count_ != 0) throw use_count_is_zero();
|
||||||
++use_count_;
|
++use_count_;
|
||||||
++weak_count_;
|
++weak_count_;
|
||||||
}
|
}
|
||||||
@@ -161,6 +158,19 @@ private:
|
|||||||
void (*self_deleter_) (counted_base *);
|
void (*self_deleter_) (counted_base *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void intrusive_ptr_add_ref(counted_base * p)
|
||||||
|
{
|
||||||
|
if(p != 0) p->add_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void intrusive_ptr_release(counted_base * p)
|
||||||
|
{
|
||||||
|
if(p != 0) p->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
template<class P, class D> class counted_base_impl: public counted_base
|
template<class P, class D> class counted_base_impl: public counted_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -202,6 +212,11 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit shared_count(counted_base * pi): pi_(pi) // never throws
|
||||||
|
{
|
||||||
|
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): pi_(0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
201
include/boost/intrusive_ptr.hpp
Normal file
201
include/boost/intrusive_ptr.hpp
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
||||||
|
#define BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// intrusive_ptr.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001, 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.
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4284) // odd return type for operator->
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <functional> // std::less
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// intrusive_ptr
|
||||||
|
//
|
||||||
|
// A smart pointer that uses intrusive reference counting.
|
||||||
|
//
|
||||||
|
// Relies on unqualified calls to
|
||||||
|
//
|
||||||
|
// void intrusive_ptr_add_ref(T * p);
|
||||||
|
// void intrusive_ptr_release(T * p);
|
||||||
|
// (note: p may be 0!)
|
||||||
|
//
|
||||||
|
// The object is responsible for destroying itself.
|
||||||
|
//
|
||||||
|
|
||||||
|
template<class T> class intrusive_ptr
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef intrusive_ptr this_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
intrusive_ptr(): p_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
intrusive_ptr(T * p): p_(p)
|
||||||
|
{
|
||||||
|
intrusive_ptr_add_ref(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
~intrusive_ptr()
|
||||||
|
{
|
||||||
|
intrusive_ptr_release(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
||||||
|
|
||||||
|
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
|
||||||
|
{
|
||||||
|
intrusive_ptr_add_ref(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
|
||||||
|
{
|
||||||
|
intrusive_ptr_add_ref(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
||||||
|
|
||||||
|
template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
|
||||||
|
{
|
||||||
|
this_type(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
intrusive_ptr & operator=(intrusive_ptr const & rhs)
|
||||||
|
{
|
||||||
|
this_type(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
intrusive_ptr & operator=(T * rhs)
|
||||||
|
{
|
||||||
|
this_type(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(intrusive_ptr & rhs)
|
||||||
|
{
|
||||||
|
T * tmp = p_;
|
||||||
|
p_ = rhs.p_;
|
||||||
|
rhs.p_ = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
T * get() const
|
||||||
|
{
|
||||||
|
return p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator*() const
|
||||||
|
{
|
||||||
|
return *p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T * operator->() const
|
||||||
|
{
|
||||||
|
return p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return p_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bool (intrusive_ptr::*bool_type) () const;
|
||||||
|
|
||||||
|
operator bool_type () const
|
||||||
|
{
|
||||||
|
return p_ == 0? 0: &intrusive_ptr::empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
T * p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> intrusive_ptr<T> shared_dynamic_cast(intrusive_ptr<U> const & p)
|
||||||
|
{
|
||||||
|
return dynamic_cast<T *>(p.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> intrusive_ptr<T> shared_static_cast(intrusive_ptr<U> const & p)
|
||||||
|
{
|
||||||
|
return static_cast<T *>(p.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||||
|
{
|
||||||
|
return a.get() == b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
|
||||||
|
{
|
||||||
|
return a.get() != b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||||
|
{
|
||||||
|
return std::less<T *>(a.get(), b.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
|
||||||
|
{
|
||||||
|
return a.get() == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
|
||||||
|
{
|
||||||
|
return a.get() != b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
|
||||||
|
{
|
||||||
|
return a == b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
|
||||||
|
{
|
||||||
|
return a != b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// mem_fn support
|
||||||
|
|
||||||
|
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
|
||||||
|
{
|
||||||
|
return p.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
@@ -68,6 +68,7 @@ template<> struct shared_ptr_traits<void>
|
|||||||
//
|
//
|
||||||
|
|
||||||
template<typename T> class weak_ptr;
|
template<typename T> class weak_ptr;
|
||||||
|
template<typename T> class intrusive_ptr;
|
||||||
|
|
||||||
template<typename T> class shared_ptr
|
template<typename T> class shared_ptr
|
||||||
{
|
{
|
||||||
@@ -110,6 +111,11 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Y>
|
||||||
|
shared_ptr(intrusive_ptr<Y> const & r): px(r.get()), pn(r.get()) // never throws
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Y>
|
template<typename 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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user