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