]> git.saurik.com Git - wxWidgets.git/blame - include/wx/ptr_scpd.h
another fix for wxUSE_DRAG_AND_DROP==0 build
[wxWidgets.git] / include / wx / ptr_scpd.h
CommitLineData
5b222f1c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/ptr_scpd.h
3// Purpose: scoped smart pointer class
4// Author: Jesse Lovelace <jllovela@eos.ncsu.edu>
058f225a 5// Modified by: Vadim Zeitlin to add template wxScopedArray
5b222f1c
JS
6// Created: 06/01/02
7// RCS-ID: $Id$
8// Copyright: (c) Jesse Lovelace and original Boost authors (see below)
058f225a 9// (c) 2009 Vadim Zeitlin
65571936 10// Licence: wxWindows licence
5b222f1c
JS
11/////////////////////////////////////////////////////////////////////////////
12
13// This class closely follows the implementation of the boost
7e548f6b 14// library scoped_ptr and is an adaption for c++ macro's in
77ffb593 15// the wxWidgets project. The original authors of the boost
5b222f1c
JS
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
89969a91 34// ----------------------------------------------------------------------------
058f225a 35// wxScopedPtr: A scoped pointer
89969a91
RR
36// ----------------------------------------------------------------------------
37
058f225a 38template <class T>
89969a91 39class wxScopedPtr
058f225a
VZ
40{
41public:
89969a91 42 typedef T element_type;
058f225a
VZ
43
44 wxEXPLICIT wxScopedPtr(T * ptr = NULL) : m_ptr(ptr) { }
45
46 ~wxScopedPtr() { delete m_ptr; }
47
a60b0ddc
RR
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
058f225a
VZ
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
96private:
97 T * m_ptr;
98
99 DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedPtr, T)
100};
101
102// ----------------------------------------------------------------------------
103// wxScopedArray: A scoped array
104// ----------------------------------------------------------------------------
105
106template <class T>
107class wxScopedArray
108{
109public:
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
144private:
145 T *m_array;
146
147 DECLARE_NO_COPY_TEMPLATE_CLASS(wxScopedArray, T)
89969a91
RR
148};
149
150// ----------------------------------------------------------------------------
151// old macro based implementation
152// ----------------------------------------------------------------------------
153
d566b182
VZ
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
5b222f1c
JS
161*/
162
373a5fb3 163#ifdef __WATCOMC__
5c519b6c
WS
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)
373a5fb3 167#else
5c519b6c 168 #define wxPRE_NO_WARNING_SCOPE(name) do
17a1ebd1 169 #define wxPOST_NO_WARNING_SCOPE(name) while ( wxFalse )
373a5fb3
WS
170#endif
171
d566b182 172#define wxCHECKED_DELETE(ptr) \
5c519b6c 173 wxPRE_NO_WARNING_SCOPE(scope_var1) \
d566b182
VZ
174 { \
175 typedef char complete[sizeof(*ptr)]; \
176 delete ptr; \
5c519b6c 177 } wxPOST_NO_WARNING_SCOPE(scope_var1)
d566b182
VZ
178
179#define wxCHECKED_DELETE_ARRAY(ptr) \
5c519b6c 180 wxPRE_NO_WARNING_SCOPE(scope_var2) \
d566b182
VZ
181 { \
182 typedef char complete[sizeof(*ptr)]; \
183 delete [] ptr; \
5c519b6c 184 } wxPOST_NO_WARNING_SCOPE(scope_var2)
5b222f1c 185
89969a91 186/* The type being used *must* be complete at the time
5b222f1c
JS
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
89969a91 189 being used. */
5b222f1c
JS
190
191#define wxDECLARE_SCOPED_PTR(T, name) \
192class name \
193{ \
194private: \
195 T * m_ptr; \
196 \
197 name(name const &); \
198 name & operator=(name const &); \
199 \
200public: \
5455e227 201 wxEXPLICIT name(T * ptr = NULL) \
5b222f1c
JS
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 \
5455e227
VZ
215 T *release() \
216 { \
217 T *ptr = m_ptr; \
218 m_ptr = NULL; \
219 return ptr; \
220 } \
221 \
5b222f1c
JS
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)\
248name::~name() \
249{ \
bb0a3c4a 250 wxCHECKED_DELETE(m_ptr); \
5b222f1c
JS
251}
252
d83eeece
VZ
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
d0ee33f5
WS
256#define wxDEFINE_SCOPED_PTR_TYPE(T) \
257 wxDECLARE_SCOPED_PTR(T, T ## Ptr) \
d83eeece
VZ
258 wxDEFINE_SCOPED_PTR(T, T ## Ptr)
259
260// the same but for arrays instead of simple pointers
5b222f1c
JS
261#define wxDECLARE_SCOPED_ARRAY(T, name)\
262class name \
263{ \
264private: \
265 T * m_ptr; \
266 name(name const &); \
267 name & operator=(name const &); \
268 \
269public: \
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) \
bb0a3c4a
VZ
297name::~name() \
298{ \
299 wxCHECKED_DELETE_ARRAY(m_ptr); \
300} \
301void name::reset(T * p){ \
302 if (m_ptr != p) \
303 { \
304 wxCHECKED_DELETE_ARRAY(m_ptr); \
305 m_ptr = p; \
306 } \
5b222f1c
JS
307}
308
38f15267
VZ
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) \
259c43f6 315 wxDEFINE_SCOPED_PTR_TYPE(T) \
38f15267
VZ
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; \
259c43f6 334 };
38f15267 335
d83eeece
VZ
336#endif // __WX_SCOPED_POINTER__
337