#ifndef GRAEHL__SHARED__INTRUSIVE_REFCOUNT_HPP #define GRAEHL__SHARED__INTRUSIVE_REFCOUNT_HPP #include #include #include #include /** usage: struct mine : public boost::instrusive_refcount {}; boost::intrusive_ptr 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 intrusive_refcount; template class atomic_intrusive_refcount; template void intrusive_ptr_add_ref(intrusive_refcount* ptr) { ++(ptr->refs); } template void intrusive_ptr_release(intrusive_refcount* ptr) { if (!--(ptr->refs)) delete static_cast(ptr); } //WARNING: only 2^32 (unsigned) refs allowed. hope that's ok :) template class intrusive_refcount : boost::noncopyable { protected: // typedef intrusive_refcount pointed_type; friend void intrusive_ptr_add_ref(intrusive_refcount* ptr); friend void intrusive_ptr_release(intrusive_refcount* ptr); // friend class intrusive_ptr; intrusive_refcount(): refs(0) {} ~intrusive_refcount() { assert(refs==0); } private: unsigned refs; }; template void intrusive_ptr_add_ref(atomic_intrusive_refcount* ptr) { ++(ptr->refs); } template void intrusive_ptr_release(atomic_intrusive_refcount* ptr) { if(!--(ptr->refs)) delete static_cast(ptr); } template class atomic_intrusive_refcount : boost::noncopyable { protected: friend void intrusive_ptr_add_ref(atomic_intrusive_refcount* ptr); friend void intrusive_ptr_release(atomic_intrusive_refcount* ptr); atomic_intrusive_refcount(): refs(0) {} ~atomic_intrusive_refcount() { assert(refs==0); } private: boost::detail::atomic_count refs; }; } #endif