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