X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2Fintrusive_refcount.hh;h=ca2ccb6d2e0285341c1873a9fe3eb1590e7081e3;hb=81ffa1c459b96dd44472bcef37e1e373934ee138;hp=fe0f10e82954b0ab2d82185535052b2c9ad9786b;hpb=85ab07d100a382467a42e19d741d403a7a96c951;p=senf.git diff --git a/Utils/intrusive_refcount.hh b/Utils/intrusive_refcount.hh index fe0f10e..ca2ccb6 100644 --- a/Utils/intrusive_refcount.hh +++ b/Utils/intrusive_refcount.hh @@ -34,50 +34,142 @@ namespace senf { - /** \brief Reference count mixin for intrusive_ptr + template class intrusive_refcount_t; - This class provides a simple internally managed refcount and supplies the boost::intrusive_ptr - required interface. To make a class compatible with \c boost::intrusive_ptr, just derive - publicly from intrusive_refcount. + /** \brief Reference count mixin interface baseclass - Two additional benifits of using intrusive_refcount are - \li The object can access it's own refcount - \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time - (not only after new) + This class is the baseclass of all intrusive refcount mixins. See \ref intrusive_refcount_t + and \ref intrusive_refcount for more information. */ - class intrusive_refcount + class intrusive_refcount_base : public boost::noncopyable { public: typedef unsigned refcount_t; ///< reference count type - virtual ~intrusive_refcount(); + virtual ~intrusive_refcount_base(); refcount_t refcount(); ///< current refcount bool is_shared(); ///< return \c true if refcount() > 1 protected: - intrusive_refcount(); + intrusive_refcount_base(); - private: void add_ref(); bool release(); + private: refcount_t refcount_; + + }; - friend void senf::intrusive_ptr_add_ref(intrusive_refcount* p); - friend void senf::intrusive_ptr_release(intrusive_refcount* p); + /** \brief Customizable reference count mixin for intrusive_ptr + + This class provides a simple internally managed refcount and supplies the boost::intrusive_ptr + required interface. To make a class compatible with \c boost::intrusive_ptr, just derive + publicly from intrusive_refcount_t. + + \code + class SomeClass + : public intrusive_refcount_t + { + // ... + + private: + typedef intrusive_refcount_t intrusive_base; + + void add_ref() + { + // somehow call intrusive_base::add_ref() + } + + bool release() + { + // Call intrusive_base::release() to decrement the + // refcount. This call will return 'true' when the refcount reaches 0. + + // Return 'true', if the instance shall be deleted + } + + // Needed to give intrusive_base access to 'add_ref' and 'release' + friend class intrusive_base; + }; + \endcode + + Two additional benefits of using intrusive_refcount are + \li The object can access it's own refcount + \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time + (not only after new) + + This class allows to customize the reference counting strategy (e.g. additional refcounting + within another object or checking some additional condition before deleting the object when + the refcount reaches 0). + + The interface of this class is defined in \ref intrusive_refcount_base (which you should not + use directly). + */ + template + class intrusive_refcount_t + : public intrusive_refcount_base + { + protected: + intrusive_refcount_t(); + + private: + void intrusive_ptr_add_ref(); + void intrusive_ptr_release(); + + template + friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t * p); + template + friend void senf::intrusive_ptr_release(intrusive_refcount_t * p); + }; + + /** \brief Reference count mixin for intrusive_ptr + + This class provides a simple internally managed refcount and supplies the boost::intrusive_ptr + required interface. To make a class compatible with \c boost::intrusive_ptr, just derive + publicly from intrusive_refcount. + + \code + class SomeClass + : public intrusive_refcount + { + // ... + }; + \endcode + + Two additional benefits of using intrusive_refcount are + \li The object can access it's own refcount + \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time + (not only after new) + + This mixin class directly uses the default allocation strategy. If you want to customize the + reference couting, use \ref intrusive_refcount_t. + + The interface of this class is defined in \ref intrusive_refcount_t and \ref + intrusive_refcount_base (the latter of which you should not use directly). + */ + class intrusive_refcount + : public intrusive_refcount_t + { + protected: + intrusive_refcount(); }; - void intrusive_ptr_add_ref(intrusive_refcount* p); - void intrusive_ptr_release(intrusive_refcount* p); + template + void intrusive_ptr_add_ref(intrusive_refcount_t * p); + template + void intrusive_ptr_release(intrusive_refcount_t * p); + } ///////////////////////////////hh.e//////////////////////////////////////// #include "intrusive_refcount.cci" //#include "intrusive_refcount.ct" -//#include "intrusive_refcount.cti" +#include "intrusive_refcount.cti" #endif @@ -87,4 +179,6 @@ namespace senf { // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: