]> git.saurik.com Git - wxWidgets.git/blob - include/wx/ptr_scpd.h
no real changes, just add some comments
[wxWidgets.git] / include / wx / ptr_scpd.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/ptr_scpd.h
3 // Purpose: scoped smart pointer class
4 // Author: Jesse Lovelace <jllovela@eos.ncsu.edu>
5 // Modified by: Vadim Zeitlin to add template wxScopedArray
6 // Created: 06/01/02
7 // RCS-ID: $Id$
8 // Copyright: (c) Jesse Lovelace and original Boost authors (see below)
9 // (c) 2009 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // This class closely follows the implementation of the boost
14 // library scoped_ptr and is an adaption for c++ macro's in
15 // the wxWidgets project. The original authors of the boost
16 // scoped_ptr are given below with their respective copyrights.
17
18 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
19 // Copyright (c) 2001, 2002 Peter Dimov
20 //
21 // Permission to copy, use, modify, sell and distribute this software
22 // is granted provided this copyright notice appears in all copies.
23 // This software is provided "as is" without express or implied
24 // warranty, and with no claim as to its suitability for any purpose.
25 //
26 // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
27 //
28
29 #ifndef __WX_SCOPED_POINTER__
30 #define __WX_SCOPED_POINTER__
31
32 #include "wx/defs.h"
33
34 // ----------------------------------------------------------------------------
35 // wxScopedPtr: A scoped pointer
36 // ----------------------------------------------------------------------------
37
38 template <class T>
39 class wxScopedPtr
40 {
41 public:
42 typedef T element_type;
43
44 wxEXPLICIT wxScopedPtr(T * ptr = NULL) : m_ptr(ptr) { }
45
46 ~wxScopedPtr() { delete m_ptr; }
47
48 // test for pointer validity: defining conversion to unspecified_bool_type
49 // and not more obvious bool to avoid implicit conversions to integer types
50 typedef T *(wxScopedPtr<T>::*unspecified_bool_type)() const;
51 operator unspecified_bool_type() const
52 {
53 return m_ptr ? &wxScopedPtr<T>::get : NULL;
54 }
55
56 void reset(T * ptr = NULL)
57 {
58 if ( ptr != m_ptr )
59 {
60 delete m_ptr;
61 m_ptr = ptr;
62 }
63 }
64
65 T *release()
66 {
67 T *ptr = m_ptr;
68 m_ptr = NULL;
69 return ptr;
70 }
71
72 T & operator*() const
73 {
74 wxASSERT(m_ptr != NULL);
75 return *m_ptr;
76 }
77
78 T * operator->() const
79 {
80 wxASSERT(m_ptr != NULL);
81 return m_ptr;
82 }
83
84 T * get() const
85 {
86 return m_ptr;
87 }
88
89 void swap(wxScopedPtr& other)
90 {
91 T * const tmp = other.m_ptr;
92 other.m_ptr = m_ptr;
93 m_ptr = tmp;
94 }
95
96 private:
97 T * m_ptr;
98
99 DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedPtr, T)
100 };
101
102 // ----------------------------------------------------------------------------
103 // wxScopedArray: A scoped array
104 // ----------------------------------------------------------------------------
105
106 template <class T>
107 class wxScopedArray
108 {
109 public:
110 typedef T element_type;
111
112 wxEXPLICIT wxScopedArray(T * array = NULL) : m_array(array) { }
113
114 ~wxScopedArray() { delete [] m_array; }
115
116 // test for pointer validity: defining conversion to unspecified_bool_type
117 // and not more obvious bool to avoid implicit conversions to integer types
118 typedef T *(wxScopedArray<T>::*unspecified_bool_type)() const;
119 operator unspecified_bool_type() const
120 {
121 return m_array ? &wxScopedArray<T>::get : NULL;
122 }
123
124 void reset(T *array = NULL)
125 {
126 if ( array != m_array )
127 {
128 delete m_array;
129 m_array = array;
130 }
131 }
132
133 T& operator[](size_t n) const { return m_array[n]; }
134
135 T *get() const { return m_array; }
136
137 void swap(wxScopedArray &other)
138 {
139 T * const tmp = other.m_array;
140 other.m_array = m_array;
141 m_array = tmp;
142 }
143
144 private:
145 T *m_array;
146
147 DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedArray, T)
148 };
149
150 // ----------------------------------------------------------------------------
151 // old macro based implementation
152 // ----------------------------------------------------------------------------
153
154 /*
155 checked deleters are used to make sure that the type being deleted is really
156 a complete type.: otherwise sizeof() would result in a compile-time error
157
158 do { ... } while ( 0 ) construct is used to have an anonymous scope
159 (otherwise we could have name clashes between different "complete"s) but
160 still force a semicolon after the macro
161 */
162
163 #ifdef __WATCOMC__
164 #define wxFOR_ONCE(name) for(int name=0; name<1; name++)
165 #define wxPRE_NO_WARNING_SCOPE(name) wxFOR_ONCE(wxMAKE_UNIQUE_NAME(name))
166 #define wxPOST_NO_WARNING_SCOPE(name)
167 #else
168 #define wxPRE_NO_WARNING_SCOPE(name) do
169 #define wxPOST_NO_WARNING_SCOPE(name) while ( wxFalse )
170 #endif
171
172 #define wxCHECKED_DELETE(ptr) \
173 wxPRE_NO_WARNING_SCOPE(scope_var1) \
174 { \
175 typedef char complete[sizeof(*ptr)]; \
176 delete ptr; \
177 } wxPOST_NO_WARNING_SCOPE(scope_var1)
178
179 #define wxCHECKED_DELETE_ARRAY(ptr) \
180 wxPRE_NO_WARNING_SCOPE(scope_var2) \
181 { \
182 typedef char complete[sizeof(*ptr)]; \
183 delete [] ptr; \
184 } wxPOST_NO_WARNING_SCOPE(scope_var2)
185
186 /* The type being used *must* be complete at the time
187 that wxDEFINE_SCOPED_* is called or a compiler error will result.
188 This is because the class checks for the completeness of the type
189 being used. */
190
191 #define wxDECLARE_SCOPED_PTR(T, name) \
192 class name \
193 { \
194 private: \
195 T * m_ptr; \
196 \
197 name(name const &); \
198 name & operator=(name const &); \
199 \
200 public: \
201 wxEXPLICIT name(T * ptr = NULL) \
202 : m_ptr(ptr) { } \
203 \
204 ~name(); \
205 \
206 void reset(T * ptr = NULL) \
207 { \
208 if (m_ptr != ptr) \
209 { \
210 delete m_ptr; \
211 m_ptr = ptr; \
212 } \
213 } \
214 \
215 T *release() \
216 { \
217 T *ptr = m_ptr; \
218 m_ptr = NULL; \
219 return ptr; \
220 } \
221 \
222 T & operator*() const \
223 { \
224 wxASSERT(m_ptr != NULL); \
225 return *m_ptr; \
226 } \
227 \
228 T * operator->() const \
229 { \
230 wxASSERT(m_ptr != NULL); \
231 return m_ptr; \
232 } \
233 \
234 T * get() const \
235 { \
236 return m_ptr; \
237 } \
238 \
239 void swap(name & ot) \
240 { \
241 T * tmp = ot.m_ptr; \
242 ot.m_ptr = m_ptr; \
243 m_ptr = tmp; \
244 } \
245 };
246
247 #define wxDEFINE_SCOPED_PTR(T, name)\
248 name::~name() \
249 { \
250 wxCHECKED_DELETE(m_ptr); \
251 }
252
253 // this macro can be used for the most common case when you want to declare and
254 // define the scoped pointer at the same time and want to use the standard
255 // naming convention: auto pointer to Foo is called FooPtr
256 #define wxDEFINE_SCOPED_PTR_TYPE(T) \
257 wxDECLARE_SCOPED_PTR(T, T ## Ptr) \
258 wxDEFINE_SCOPED_PTR(T, T ## Ptr)
259
260 // the same but for arrays instead of simple pointers
261 #define wxDECLARE_SCOPED_ARRAY(T, name)\
262 class name \
263 { \
264 private: \
265 T * m_ptr; \
266 name(name const &); \
267 name & operator=(name const &); \
268 \
269 public: \
270 wxEXPLICIT name(T * p = NULL) : m_ptr(p) \
271 {} \
272 \
273 ~name(); \
274 void reset(T * p = NULL); \
275 \
276 T & operator[](long int i) const\
277 { \
278 wxASSERT(m_ptr != NULL); \
279 wxASSERT(i >= 0); \
280 return m_ptr[i]; \
281 } \
282 \
283 T * get() const \
284 { \
285 return m_ptr; \
286 } \
287 \
288 void swap(name & ot) \
289 { \
290 T * tmp = ot.m_ptr; \
291 ot.m_ptr = m_ptr; \
292 m_ptr = tmp; \
293 } \
294 };
295
296 #define wxDEFINE_SCOPED_ARRAY(T, name) \
297 name::~name() \
298 { \
299 wxCHECKED_DELETE_ARRAY(m_ptr); \
300 } \
301 void name::reset(T * p){ \
302 if (m_ptr != p) \
303 { \
304 wxCHECKED_DELETE_ARRAY(m_ptr); \
305 m_ptr = p; \
306 } \
307 }
308
309 // ----------------------------------------------------------------------------
310 // "Tied" scoped pointer: same as normal one but also sets the value of
311 // some other variable to the pointer value
312 // ----------------------------------------------------------------------------
313
314 #define wxDEFINE_TIED_SCOPED_PTR_TYPE(T) \
315 wxDEFINE_SCOPED_PTR_TYPE(T) \
316 class T ## TiedPtr : public T ## Ptr \
317 { \
318 public: \
319 T ## TiedPtr(T **pp, T *p) \
320 : T ## Ptr(p), m_pp(pp) \
321 { \
322 m_pOld = *pp; \
323 *pp = p; \
324 } \
325 \
326 ~ T ## TiedPtr() \
327 { \
328 *m_pp = m_pOld; \
329 } \
330 \
331 private: \
332 T **m_pp; \
333 T *m_pOld; \
334 };
335
336 #endif // __WX_SCOPED_POINTER__
337