X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2Fintrusive_refcount.hh;h=d3b980f35ffdbe8ac60f8b9a0e31270900fdac45;hb=412024ed31a4ab4eaea7a4165a434f8efebee325;hp=a0c36e0ffae9fbf001568f5bdea146fc754e653a;hpb=98f3f38c5872d26fcf544a9d28efe0518e3895e2;p=senf.git diff --git a/Utils/intrusive_refcount.hh b/Utils/intrusive_refcount.hh index a0c36e0..d3b980f 100644 --- a/Utils/intrusive_refcount.hh +++ b/Utils/intrusive_refcount.hh @@ -1,9 +1,9 @@ // $Id$ // // Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -23,8 +23,8 @@ /** \file \brief intrusive_refcount public header */ -#ifndef HH_intrusive_refcount_ -#define HH_intrusive_refcount_ 1 +#ifndef HH_SENF_Utils_intrusive_refcount_ +#define HH_SENF_Utils_intrusive_refcount_ 1 // Custom includes #include @@ -34,50 +34,140 @@ 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 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 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_; + + template void intrusive_ptr_add_ref(); + template void intrusive_ptr_release(); + + template + friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t const * p); + template + friend void senf::intrusive_ptr_release(intrusive_refcount_t const * 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). - friend void senf::intrusive_ptr_add_ref(intrusive_refcount* p); - friend void senf::intrusive_ptr_release(intrusive_refcount* p); + 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(); + }; + + /** \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 const * p); + template + void intrusive_ptr_release(intrusive_refcount_t const * p); + } ///////////////////////////////hh.e//////////////////////////////////////// #include "intrusive_refcount.cci" //#include "intrusive_refcount.ct" -//#include "intrusive_refcount.cti" +#include "intrusive_refcount.cti" #endif @@ -87,4 +177,6 @@ namespace senf { // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: