c790403b439300d17c80311a43c33c566840bed7
[senf.git] / senf / Utils / intrusive_refcount.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief intrusive_refcount public header */
25
26 #ifndef HH_SENF_Utils_intrusive_refcount_
27 #define HH_SENF_Utils_intrusive_refcount_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31
32 //#include "intrusive_refcount.mpp"
33 //-/////////////////////////////////////////////////////////////////////////////////////////////////
34
35 namespace senf {
36
37     template <class Self> class intrusive_refcount_t;
38
39     /** \brief Reference count mixin interface baseclass
40
41         This class is the baseclass of all intrusive refcount mixins. See \ref intrusive_refcount_t
42         and \ref intrusive_refcount for more information.
43      */
44     class intrusive_refcount_base
45         : public boost::noncopyable
46     {
47     public:
48         typedef unsigned refcount_t;    ///< reference count type
49
50         virtual ~intrusive_refcount_base();
51
52         refcount_t refcount() const;    ///< current refcount
53         bool is_shared() const;         ///< return \c true if refcount() > 1
54
55     protected:
56         intrusive_refcount_base();
57
58         void add_ref();
59         bool release();
60
61     private:
62         refcount_t refcount_;
63
64         template <class S> void intrusive_ptr_add_ref();
65         template <class S> void intrusive_ptr_release();
66
67         template <class S>
68         friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t<S> const * p);
69         template <class S>
70         friend void senf::intrusive_ptr_release(intrusive_refcount_t<S> const * p);
71     };
72
73     /** \brief Customizable reference count mixin for intrusive_ptr
74
75         This class provides a simple internally managed refcount and supplies the <a
76         href="http://www.boost.org/doc/libs/release/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
77         required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
78         publicly from intrusive_refcount_t.
79
80         \code
81         class SomeClass
82             : public intrusive_refcount_t<SomeClass>
83         {
84             // ...
85
86         private:
87             typedef intrusive_refcount_t<SomeClass> intrusive_base;
88
89             void add_ref()
90             {
91                 // somehow call intrusive_base::add_ref()
92             }
93
94             bool release()
95             {
96                 // Call intrusive_base::release() to decrement the
97                 // refcount. This call will return 'true' when the refcount reaches 0.
98
99                 // Return 'true', if the instance shall be deleted
100             }
101
102             // Needed to give intrusive_base access to 'add_ref' and 'release'
103             friend class intrusive_base;
104         };
105         \endcode
106
107         Two additional benefits of using intrusive_refcount are
108         \li The object can access it's own refcount
109         \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
110             (not only after new)
111
112         This class allows to customize the reference counting strategy (e.g. additional refcounting
113         within another object or checking some additional condition before deleting the object when
114         the refcount reaches 0).
115
116         The interface of this class is defined in \ref intrusive_refcount_base (which you should not
117         use directly).
118      */
119     template <class Self>
120     class intrusive_refcount_t
121         : public intrusive_refcount_base
122     {
123     protected:
124         intrusive_refcount_t();
125     };
126
127     /** \brief Reference count mixin for intrusive_ptr
128
129         This class provides a simple internally managed refcount and supplies the <a
130         href="http://www.boost.org/doc/libs/release/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
131         required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
132         publicly from intrusive_refcount.
133
134         \code
135         class SomeClass
136             : public intrusive_refcount
137         {
138             // ...
139         };
140         \endcode
141
142         Two additional benefits of using intrusive_refcount are
143         \li The object can access it's own refcount
144         \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
145             (not only after new)
146
147         This mixin class directly uses the default allocation strategy. If you want to customize the
148         reference couting, use \ref intrusive_refcount_t.
149
150         The interface of this class is defined in \ref intrusive_refcount_t and \ref
151         intrusive_refcount_base (the latter of which you should not use directly).
152      */
153     class intrusive_refcount
154         : public intrusive_refcount_t<intrusive_refcount>
155     {
156     protected:
157         intrusive_refcount();
158     };
159
160     template <class Self>
161     void intrusive_ptr_add_ref(intrusive_refcount_t<Self> const * p);
162     template <class Self>
163     void intrusive_ptr_release(intrusive_refcount_t<Self> const * p);
164
165 }
166
167 //-/////////////////////////////////////////////////////////////////////////////////////////////////
168 #include "intrusive_refcount.cci"
169 //#include "intrusive_refcount.ct"
170 #include "intrusive_refcount.cti"
171 #endif
172
173 \f
174 // Local Variables:
175 // mode: c++
176 // fill-column: 100
177 // c-file-style: "senf"
178 // indent-tabs-mode: nil
179 // ispell-local-dictionary: "american"
180 // compile-command: "scons -u test"
181 // comment-column: 40
182 // End: