"Fossies" - the Fresh Open Source Software Archive 
Member "regexxer-0.10/src/sharedptr.h" (6 Oct 2011, 6397 Bytes) of package /linux/privat/old/regexxer-0.10.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "sharedptr.h" see the
Fossies "Dox" file reference documentation.
1 /*
2 * Copyright (c) 2002-2007 Daniel Elstner <daniel.kitta@gmail.com>
3 *
4 * This file is part of regexxer.
5 *
6 * regexxer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * regexxer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with regexxer; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef REGEXXER_SHAREDPTR_H_INCLUDED
22 #define REGEXXER_SHAREDPTR_H_INCLUDED
23
24 #include <algorithm>
25
26 namespace Util
27 {
28
29 template <class> class SharedPtr;
30
31 /*
32 * Common base class of objects managed by SharedPtr<>.
33 */
34 class SharedObject
35 {
36 protected:
37 inline SharedObject(); // initial reference count is 0
38 inline ~SharedObject();
39
40 private:
41 mutable long refcount_;
42
43 // noncopyable
44 SharedObject(const SharedObject&);
45 SharedObject& operator=(const SharedObject&);
46
47 template <class> friend class SharedPtr;
48 };
49
50 /*
51 * Intrusive smart pointer implementation. It requires the managed types
52 * to be derived from class SharedObject, in order to do reference counting
53 * as efficient as possible.
54 *
55 * The intrusive approach also simplifies the implementation, particularly
56 * with regards to exception safety. A non-intrusive smart pointer like
57 * boost::shared_ptr<> would have to allocate memory to hold the reference
58 * count -- this is tricky not only because of the 'new' which could throw,
59 * but it also complicates the implementation of the cast templates like
60 * shared_dynamic_cast<> etc.
61 *
62 * The cast template functions use the same syntax as in boost:
63 *
64 * shared_static_cast<T> returns static_cast<T*>(pointer)
65 * shared_dynamic_cast<T> returns dynamic_cast<T*>(pointer)
66 * shared_polymorphic_cast<T> returns &dynamic_cast<T&>(*pointer)
67 *
68 * I didn't implement shared_polymorphic_downcast<T> because it seems to be
69 * just a debug check for those who don't want to ship with debugging enabled.
70 * This would be silly IMHO, considering that the dynamic_cast<> overhead is
71 * negligible in a GUI application like regexxer.
72 *
73 * About operator const void*() const:
74 *
75 * This operator fulfills the same task operator bool() would, but safer.
76 * A SharedPtr<> will never be implicitely converted to an integer type,
77 * which is particularly important in the context of overload resolution.
78 * An additional advantage is that operator const void*() gets us equality
79 * and non-equality tests for free.
80 *
81 * Note that boost is using an operator that converts to a PMF (pointer to
82 * member function) for this purpose. However, I consider this solution
83 * to be somewhat over the top.
84 */
85 template <class T>
86 class SharedPtr
87 {
88 public:
89 inline SharedPtr();
90 inline ~SharedPtr();
91
92 explicit inline SharedPtr(T* ptr); // obtains reference
93
94 inline SharedPtr(const SharedPtr<T>& other);
95 inline SharedPtr<T>& operator=(const SharedPtr<T>& other);
96
97 template <class U> inline SharedPtr(const SharedPtr<U>& other);
98 template <class U> inline SharedPtr<T>& operator=(const SharedPtr<U>& other);
99
100 inline void swap(SharedPtr<T>& other);
101
102 inline void reset(T* ptr = 0); // obtains reference
103 inline T* get() const;
104
105 inline T* operator->() const;
106 inline T& operator*() const;
107
108 inline operator const void*() const;
109
110 private:
111 T* ptr_;
112 };
113
114 /*
115 * Explicitely forbid the usage of a generic SharedPtr<SharedObject>
116 * because class SharedObject doesn't have a virtual destructor.
117 */
118 template <> class SharedPtr<SharedObject> {};
119 template <> class SharedPtr<const SharedObject> {};
120
121 inline
122 SharedObject::SharedObject()
123 :
124 refcount_ (0)
125 {}
126
127 inline
128 SharedObject::~SharedObject()
129 {}
130
131 template <class T> inline
132 SharedPtr<T>::SharedPtr()
133 :
134 ptr_ (0)
135 {}
136
137 template <class T> inline
138 SharedPtr<T>::~SharedPtr()
139 {
140 if (ptr_ && --ptr_->refcount_ <= 0)
141 delete ptr_;
142 }
143
144 template <class T> inline
145 SharedPtr<T>::SharedPtr(T* ptr)
146 :
147 ptr_ (ptr)
148 {
149 if (ptr_)
150 ++ptr_->refcount_;
151 }
152
153 /*
154 * Note that reset() and get() are defined here and not in declaration order
155 * on purpose -- defining them before their first use is required with some
156 * compilers for for maximum inlining.
157 */
158 template <class T> inline
159 void SharedPtr<T>::swap(SharedPtr<T>& other)
160 {
161 std::swap(ptr_, other.ptr_);
162 }
163
164 template <class T> inline
165 void SharedPtr<T>::reset(T* ptr)
166 {
167 // Note that SharedPtr<>::reset() obtains a reference.
168 SharedPtr<T> temp (ptr);
169 std::swap(ptr_, temp.ptr_);
170 }
171
172 template <class T> inline
173 T* SharedPtr<T>::get() const
174 {
175 return ptr_;
176 }
177
178 template <class T> inline
179 SharedPtr<T>::SharedPtr(const SharedPtr<T>& other)
180 :
181 ptr_ (other.ptr_)
182 {
183 if (ptr_)
184 ++ptr_->refcount_;
185 }
186
187 template <class T> inline
188 SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr<T>& other)
189 {
190 this->reset(other.ptr_);
191 return *this;
192 }
193
194 template <class T>
195 template <class U>
196 inline
197 SharedPtr<T>::SharedPtr(const SharedPtr<U>& other)
198 :
199 ptr_ (other.get())
200 {
201 if (ptr_)
202 ++ptr_->refcount_;
203 }
204
205 template <class T>
206 template <class U>
207 inline
208 SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr<U>& other)
209 {
210 this->reset(other.get());
211 return *this;
212 }
213
214 template <class T> inline
215 T* SharedPtr<T>::operator->() const
216 {
217 return ptr_;
218 }
219
220 template <class T> inline
221 T& SharedPtr<T>::operator*() const
222 {
223 return *ptr_;
224 }
225
226 template <class T> inline
227 SharedPtr<T>::operator const void*() const
228 {
229 return ptr_;
230 }
231
232 template <class T> inline
233 void swap(SharedPtr<T>& a, SharedPtr<T>& b)
234 {
235 a.swap(b);
236 }
237
238 template <class T, class U> inline
239 SharedPtr<T> shared_static_cast(const SharedPtr<U>& other)
240 {
241 return SharedPtr<T>(static_cast<T*>(other.get()));
242 }
243
244 template <class T, class U> inline
245 SharedPtr<T> shared_dynamic_cast(const SharedPtr<U>& other)
246 {
247 return SharedPtr<T>(dynamic_cast<T*>(other.get()));
248 }
249
250 template <class T, class U> inline
251 SharedPtr<T> shared_polymorphic_cast(const SharedPtr<U>& other)
252 {
253 return SharedPtr<T>(&dynamic_cast<T&>(*other)); // may throw std::bad_cast
254 }
255
256 } // namespace Util
257
258 #endif /* REGEXXER_SHAREDPTR_H_INCLUDED */