/[pcsx2_0.9.7]/trunk/common/include/Utilities/ScopedPtr.h
ViewVC logotype

Contents of /trunk/common/include/Utilities/ScopedPtr.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (show annotations) (download)
Fri Feb 25 17:31:09 2011 UTC (9 years, 5 months ago) by william
File MIME type: text/plain
File size: 8646 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4358 local: v0.9.7.313-latest) in ./trunk
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 #include "Assertions.h"
19
20 // --------------------------------------------------------------------------------------
21 // ScopedPtr
22 // --------------------------------------------------------------------------------------
23
24 template< typename T >
25 class ScopedPtr
26 {
27 DeclareNoncopyableObject(ScopedPtr);
28
29 protected:
30 T* m_ptr;
31
32 public:
33 typedef T element_type;
34
35 wxEXPLICIT ScopedPtr(T * ptr = NULL)
36 {
37 m_ptr = ptr;
38 }
39
40 ~ScopedPtr() throw() { Delete(); }
41
42 ScopedPtr& Reassign(T * ptr = NULL)
43 {
44 if ( ptr != m_ptr )
45 {
46 Delete();
47 m_ptr = ptr;
48 }
49 return *this;
50 }
51
52 ScopedPtr& Delete() throw()
53 {
54 // Thread-safe deletion: Set the pointer to NULL first, and then issue
55 // the deletion. This allows pending Application messages that might be
56 // dependent on the current object to nullify their actions.
57
58 T* deleteme = m_ptr;
59 m_ptr = NULL;
60 delete deleteme;
61
62 return *this;
63 }
64
65 // Removes the pointer from scoped management, but does not delete!
66 T *DetachPtr()
67 {
68 T *ptr = m_ptr;
69 m_ptr = NULL;
70 return ptr;
71 }
72
73 // Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
74 // has no object in management.
75 T* GetPtr() const
76 {
77 return m_ptr;
78 }
79
80 // Swaps two pointers between likened scoped pointer types. This method is useful for
81 // situations where you need to create a new object with a complex initializer that can
82 // throw exceptions -- and thusly should be disposed if the initialization fails. Use
83 // SwapPtr to assign the new object into the persistent ScopedPtr instance, and have
84 // the old object assigned to the local-scope ScopedPtr instance.
85 void SwapPtr(ScopedPtr& other)
86 {
87 T * const tmp = other.m_ptr;
88 other.m_ptr = m_ptr;
89 m_ptr = tmp;
90 }
91
92 // ----------------------------------------------------------------------------
93 // ScopedPtr Operators
94 // ----------------------------------------------------------------------------
95 // I've decided to use the ATL's approach to pointer validity tests, opposed to
96 // the wx/boost approach (which uses some bizarre member method pointer crap, and can't
97 // allow the T* implicit casting.
98
99 bool operator!() const throw()
100 {
101 return m_ptr == NULL;
102 }
103
104 operator T*() const
105 {
106 return m_ptr;
107 }
108
109 // Equality
110 bool operator==(T* pT) const throw()
111 {
112 return m_ptr == pT;
113 }
114
115 // Inequality
116 bool operator!=(T* pT) const throw()
117 {
118 return !operator==(pT);
119 }
120
121 // Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
122 // of the managed pointer.
123 ScopedPtr& operator=( T* src )
124 {
125 return Reassign( src );
126 }
127
128 // Dereference operator, returns a handle to the managed pointer.
129 // Generates a debug assertion if the object is NULL!
130 T& operator*() const
131 {
132 pxAssert(m_ptr != NULL);
133 return *m_ptr;
134 }
135
136 T* operator->() const
137 {
138 pxAssert(m_ptr != NULL);
139 return m_ptr;
140 }
141 };
142
143 // --------------------------------------------------------------------------------------
144 // ScopedArray - same as ScopedPtr but uses delete[], and has operator[]
145 // --------------------------------------------------------------------------------------
146
147 template< typename T >
148 class ScopedArray
149 {
150 DeclareNoncopyableObject(ScopedArray);
151
152 protected:
153 T* m_array;
154 uint m_valid_range;
155
156 public:
157 typedef T element_type;
158
159 wxEXPLICIT ScopedArray(T * ptr = NULL)
160 {
161 m_array = ptr;
162 m_valid_range = 0xffffffff;
163 }
164
165 wxEXPLICIT ScopedArray( size_t size )
166 {
167 m_array = new T[size];
168 m_valid_range = size;
169 }
170
171 ~ScopedArray() throw()
172 { Delete(); }
173
174 ScopedArray& Reassign(T * ptr = NULL)
175 {
176 if( ptr != m_array )
177 {
178 Delete();
179 m_array = ptr;
180 m_valid_range = 0xffffffff;
181 }
182 return *this;
183 }
184
185 ScopedArray& Delete() throw()
186 {
187 // Thread-safe deletion: Set the pointer to NULL first, and then issue
188 // the deletion. This allows pending Application messages that might be
189 // dependent on the current object to nullify their actions.
190
191 T* deleteme = m_array;
192 m_array = NULL;
193 delete[] deleteme;
194
195 return *this;
196 }
197
198 // Removes the pointer from scoped management, but does not delete!
199 T *DetachPtr()
200 {
201 T *ptr = m_array;
202 m_array = NULL;
203 return ptr;
204 }
205
206 // Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
207 // has no object in management.
208 T* GetPtr() const
209 {
210 return m_array;
211 }
212
213 void SwapPtr(ScopedArray& other)
214 {
215 T * const tmp = other.m_array;
216 other.m_array = m_array;
217 m_array = tmp;
218 }
219
220 // ----------------------------------------------------------------------------
221 // ScopedPtr Operators
222 // ----------------------------------------------------------------------------
223 // I've decided to use the ATL's approach to pointer validity tests, opposed to
224 // the wx/boost approach (which uses some bizarre member method pointer crap, and can't
225 // allow the T* implicit casting.
226
227 bool operator!() const throw()
228 {
229 return m_array == NULL;
230 }
231
232 // Equality
233 bool operator==(T* pT) const throw()
234 {
235 return m_array == pT;
236 }
237
238 // Inequality
239 bool operator!=(T* pT) const throw()
240 {
241 return !operator==(pT);
242 }
243
244 // Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
245 // of the managed pointer.
246 ScopedArray& operator=( T* src )
247 {
248 return Reassign( src );
249 }
250
251 T& operator[]( uint idx ) const
252 {
253 pxAssertDev( idx < m_valid_range, "Array index out of bounds on ScopedArray." );
254 return m_array[idx];
255 }
256 };
257
258 // --------------------------------------------------------------------------------------
259 // pxObjPtr -- fancified version of wxScopedPtr
260 // --------------------------------------------------------------------------------------
261 // This class is a non-null scoped pointer container. What that means is that the object
262 // always resets itself to a valid "placebo" function rather than NULL, such that methods
263 // can be invoked safely without fear of NULL pointer exceptions. This system is useful
264 // for objects where most or all public methods can fail silently, and still allow program
265 // execution flow to continue.
266 //
267 // It also implements basic scoped pointer behavior: when the pxObjPtr class is deleted,
268 // it will automatically delete the pointer in its posession, if the pointer is valid.
269 //
270 // Notes:
271 // * This class intentionally does not implement the "release" API, because it doesn't
272 // really make sense within the context of a non-nullable pointer specification.
273 //
274 template< typename T, T& DefaultStaticInst >
275 class pxObjPtr
276 {
277 DeclareNoncopyableObject(pxObjPtr);
278
279 protected:
280 T * m_ptr;
281
282 public:
283 typedef T element_type;
284
285 explicit pxObjPtr(T * ptr = &DefaultStaticInst) : m_ptr(ptr) { }
286
287 bool IsEmpty() const
288 {
289 return m_ptr != &DefaultStaticInst;
290 }
291
292 ~pxObjPtr()
293 {
294 if( !IsEmpty() ) delete m_ptr;
295 m_ptr = NULL;
296 }
297
298 // test for pointer validity: defining conversion to unspecified_bool_type
299 // and not more obvious bool to avoid implicit conversions to integer types
300 typedef T *(pxObjPtr<T,DefaultStaticInst>::*unspecified_bool_type)() const;
301
302 operator unspecified_bool_type() const
303 {
304 return ( !IsEmpty() ) ? &ScopedPtr<T>::get : NULL;
305 }
306
307 void reset(T * ptr = &DefaultStaticInst)
308 {
309 if ( ptr != m_ptr )
310 {
311 if( !IsEmpty() )
312 delete m_ptr;
313 m_ptr = ptr;
314 }
315 }
316
317 T& operator*() const
318 {
319 pxAssert(m_ptr != NULL);
320 return *m_ptr;
321 }
322
323 T* operator->() const
324 {
325 pxAssert(m_ptr != NULL);
326 return m_ptr;
327 }
328
329 T* get() const
330 {
331 pxAssert(m_ptr != NULL);
332 return m_ptr;
333 }
334
335 void swap(pxObjPtr& other)
336 {
337 // Neither pointer in either container should ever be NULL...
338 pxAssert(m_ptr != NULL);
339 pxAssert(other.m_ptr != NULL);
340
341 T * const tmp = other.m_ptr;
342 other.m_ptr = m_ptr;
343 m_ptr = tmp;
344 }
345 };
346

  ViewVC Help
Powered by ViewVC 1.1.22