diff options
author | redpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-08-11 02:37:10 +0000 |
---|---|---|
committer | redpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-08-11 02:37:10 +0000 |
commit | 80686d4e567bae579ea39e009826a2de92cd4ace (patch) | |
tree | c3c35fcba57dde423a248f38aa121ad197c79734 /utils/intrusive_refcount.hpp | |
parent | 3c85c407c333899f6b4bc26632d312b8e568b638 (diff) |
major refactor, break bad circular deps
git-svn-id: https://ws10smt.googlecode.com/svn/trunk@509 ec762483-ff6d-05da-a07a-a48fb63a330f
Diffstat (limited to 'utils/intrusive_refcount.hpp')
-rwxr-xr-x | utils/intrusive_refcount.hpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/utils/intrusive_refcount.hpp b/utils/intrusive_refcount.hpp new file mode 100755 index 00000000..4a4b0187 --- /dev/null +++ b/utils/intrusive_refcount.hpp @@ -0,0 +1,84 @@ +#ifndef GRAEHL__SHARED__INTRUSIVE_REFCOUNT_HPP +#define GRAEHL__SHARED__INTRUSIVE_REFCOUNT_HPP + +#include <boost/intrusive_ptr.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/atomic_count.hpp> +#include <cassert> + +/** usage: + struct mine : public boost::instrusive_refcount<mine> {}; + + boost::intrusive_ptr<mine> p(new mine()); +*/ + +namespace boost { +// note: the free functions need to be in boost namespace, OR namespace of involved type. this is the only way to do it. + +template <class T> +class intrusive_refcount; + +template <class T> +class atomic_intrusive_refcount; + +template<class T> +void intrusive_ptr_add_ref(intrusive_refcount<T>* ptr) +{ + ++(ptr->refs); +} + +template<class T> +void intrusive_ptr_release(intrusive_refcount<T>* ptr) +{ + if (!--(ptr->refs)) delete static_cast<T*>(ptr); +} + + +//WARNING: only 2^32 (unsigned) refs allowed. hope that's ok :) +template<class T> +class intrusive_refcount : boost::noncopyable +{ + protected: +// typedef intrusive_refcount<T> pointed_type; + friend void intrusive_ptr_add_ref<T>(intrusive_refcount<T>* ptr); + friend void intrusive_ptr_release<T>(intrusive_refcount<T>* ptr); +// friend class intrusive_ptr<T>; + + intrusive_refcount(): refs(0) {} + ~intrusive_refcount() { assert(refs==0); } + +private: + unsigned refs; +}; + + +template<class T> +void intrusive_ptr_add_ref(atomic_intrusive_refcount<T>* ptr) +{ + ++(ptr->refs); +} + +template<class T> +void intrusive_ptr_release(atomic_intrusive_refcount<T>* ptr) +{ + if(!--(ptr->refs)) delete static_cast<T*>(ptr); +} + +template<class T> +class atomic_intrusive_refcount : boost::noncopyable +{ + protected: + friend void intrusive_ptr_add_ref<T>(atomic_intrusive_refcount<T>* ptr); + friend void intrusive_ptr_release<T>(atomic_intrusive_refcount<T>* ptr); + + atomic_intrusive_refcount(): refs(0) {} + ~atomic_intrusive_refcount() { assert(refs==0); } + +private: + boost::detail::atomic_count refs; +}; + +} + + +#endif |