removed some useless spaces; not very important, I know :)
[senf.git] / 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_intrusive_refcount_
27 #define HH_intrusive_refcount_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31
32 //#include "intrusive_refcount.mpp"
33 ///////////////////////////////hh.p////////////////////////////////////////
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();          ///< current refcount
53         bool is_shared();               ///< 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     };
65
66     /** \brief Customizable reference count mixin for intrusive_ptr
67
68         This class provides a simple internally managed refcount and supplies the <a
69         href="http://www.boost.org/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
70         required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
71         publicly from intrusive_refcount_t.
72
73         \code
74         class SomeClass 
75             : public intrusive_refcount_t<SomeClass>
76         {
77             // ...
78
79         private:
80             typedef intrusive_refcount_t<SomeClass> intrusive_base;
81
82             void add_ref()
83             {
84                 // somehow call intrusive_base::add_ref()
85             }
86
87             bool release()
88             {
89                 // Call intrusive_base::release() to decrement the
90                 // refcount. This call will return 'true' when the refcount reaches 0.
91         
92                 // Return 'true', if the instance shall be deleted
93             }
94
95             // Needed to give intrusive_base access to 'add_ref' and 'release'
96             friend class intrusive_base;
97         };
98         \endcode
99        
100         Two additional benefits of using intrusive_refcount are
101         \li The object can access it's own refcount
102         \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
103             (not only after new)
104
105         This class allows to customize the reference counting strategy (e.g. additional refcounting
106         within another object or checking some additional condition before deleting the object when
107         the refcount reaches 0).
108
109         The interface of this class is defined in \ref intrusive_refcount_base (which you should not
110         use directly).
111      */
112     template <class Self>
113     class intrusive_refcount_t
114         : public intrusive_refcount_base
115     {
116     protected:
117         intrusive_refcount_t();
118
119     private:
120         void intrusive_ptr_add_ref();
121         void intrusive_ptr_release();
122
123         template <class S>
124         friend void senf::intrusive_ptr_add_ref(intrusive_refcount_t<S> * p);
125         template <class S>
126         friend void senf::intrusive_ptr_release(intrusive_refcount_t<S> * p);
127     };
128
129     /** \brief Reference count mixin for intrusive_ptr
130
131         This class provides a simple internally managed refcount and supplies the <a
132         href="http://www.boost.org/libs/smart_ptr/intrusive_ptr.html">boost::intrusive_ptr</a>
133         required interface. To make a class compatible with \c boost::intrusive_ptr, just derive
134         publicly from intrusive_refcount.
135
136         \code
137         class SomeClass
138             : public intrusive_refcount
139         {
140             // ...
141         };
142         \endcode
143
144         Two additional benefits of using intrusive_refcount are
145         \li The object can access it's own refcount
146         \li It is valid and safe to convert a plain object pointer to an intrusive_ptr at any time
147             (not only after new)
148
149         This mixin class directly uses the default allocation strategy. If you want to customize the
150         reference couting, use \ref intrusive_refcount_t.
151
152         The interface of this class is defined in \ref intrusive_refcount_t and \ref
153         intrusive_refcount_base (the latter of which you should not use directly).
154      */
155     class intrusive_refcount
156         : public intrusive_refcount_t<intrusive_refcount>
157     {
158     protected:
159         intrusive_refcount();
160     };
161
162     template <class Self>
163     void intrusive_ptr_add_ref(intrusive_refcount_t<Self> * p);
164     template <class Self>
165     void intrusive_ptr_release(intrusive_refcount_t<Self> * p);
166
167 }
168
169 ///////////////////////////////hh.e////////////////////////////////////////
170 #include "intrusive_refcount.cci"
171 //#include "intrusive_refcount.ct"
172 #include "intrusive_refcount.cti"
173 #endif
174
175 \f
176 // Local Variables:
177 // mode: c++
178 // fill-column: 100
179 // c-file-style: "senf"
180 // indent-tabs-mode: nil
181 // ispell-local-dictionary: "american"
182 // compile-command: "scons -u test"
183 // comment-column: 40
184 // End: