/[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 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 10 months ago) by william
File MIME type: text/plain
File size: 8510 byte(s)
committing r3113 initial commit again...
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 // --------------------------------------------------------------------------------------
19 // ScopedPtr
20 // --------------------------------------------------------------------------------------
21
22 template< typename T >
23 class ScopedPtr
24 {
25 DeclareNoncopyableObject(ScopedPtr);
26
27 protected:
28 T* m_ptr;
29
30 public:
31 typedef T element_type;
32
33 wxEXPLICIT ScopedPtr(T * ptr = NULL)
34 {
35 m_ptr = ptr;
36 }
37
38 ~ScopedPtr() throw() { Delete(); }
39
40 ScopedPtr& Reassign(T * ptr = NULL)
41 {
42 if ( ptr != m_ptr )
43 {
44 Delete();
45 m_ptr = ptr;
46 }
47 return *this;
48 }
49
50 ScopedPtr& Delete() throw()
51 {
52 // Thread-safe deletion: Set the pointer to NULL first, and then issue
53 // the deletion. This allows pending Application messages that might be
54 // dependent on the current object to nullify their actions.
55
56 T* deleteme = m_ptr;
57 m_ptr = NULL;
58 delete deleteme;
59
60 return *this;
61 }
62
63 // Removes the pointer from scoped management, but does not delete!
64 T *DetachPtr()
65 {
66 T *ptr = m_ptr;
67 m_ptr = NULL;
68 return ptr;
69 }
70
71 // Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
72 // has no object in management.
73 T* GetPtr() const
74 {
75 return m_ptr;
76 }
77
78 void SwapPtr(ScopedPtr& other)
79 {
80 T * const tmp = other.m_ptr;
81 other.m_ptr = m_ptr;
82 m_ptr = tmp;
83 }
84
85 // ----------------------------------------------------------------------------
86 // ScopedPtr Operators
87 // ----------------------------------------------------------------------------
88 // I've decided to use the ATL's approach to pointer validity tests, opposed to
89 // the wx/boost approach (which uses some bizarre member method pointer crap, and can't
90 // allow the T* implicit casting.
91
92 bool operator!() const throw()
93 {
94 return m_ptr == NULL;
95 }
96
97 operator T*() const
98 {
99 return m_ptr;
100 }
101
102 // Equality
103 bool operator==(T* pT) const throw()
104 {
105 return m_ptr == pT;
106 }
107
108 // Inequality
109 bool operator!=(T* pT) const throw()
110 {
111 return !operator==(pT);
112 }
113
114 // Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
115 // of the managed pointer.
116 ScopedPtr& operator=( T* src )
117 {
118 return Reassign( src );
119 }
120
121 // Dereference operator, returns a handle to the managed pointer.
122 // Generates a debug assertion if the object is NULL!
123 T& operator*() const
124 {
125 pxAssert(m_ptr != NULL);
126 return *m_ptr;
127 }
128
129 T* operator->() const
130 {
131 pxAssert(m_ptr != NULL);
132 return m_ptr;
133 }
134 };
135
136 // --------------------------------------------------------------------------------------
137 // ScopedArray - same as ScopedPtr but uses delete[], and has operator[]
138 // --------------------------------------------------------------------------------------
139
140 template< typename T >
141 class ScopedArray
142 {
143 DeclareNoncopyableObject(ScopedArray);
144
145 protected:
146 T* m_array;
147 uint m_valid_range;
148
149 public:
150 typedef T element_type;
151
152 wxEXPLICIT ScopedArray(T * ptr = NULL)
153 {
154 m_array = ptr;
155 m_valid_range = 0xffffffff;
156 }
157
158 wxEXPLICIT ScopedArray( int size ) :
159 m_array( pxAssertDev( size >= 0, "Invalid negative size specified." ) ? new T[size] : NULL )
160 , m_valid_range( (uint)size )
161 {
162 }
163
164 // For breaking the 2gb barrier, lets provision this:
165 wxEXPLICIT ScopedArray( s64 size ) :
166 m_array( pxAssertDev( size >= 0 && (size < UINT_MAX), "Invalid negative size specified to ScopedArray." ) ? new T[size] : NULL )
167 , m_valid_range( (uint)size )
168 {
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 }
181 return *this;
182 }
183
184 ScopedArray& Delete() throw()
185 {
186 // Thread-safe deletion: Set the pointer to NULL first, and then issue
187 // the deletion. This allows pending Application messages that might be
188 // dependent on the current object to nullify their actions.
189
190 T* deleteme = m_array;
191 m_array = NULL;
192 delete[] deleteme;
193
194 return *this;
195 }
196
197 // Removes the pointer from scoped management, but does not delete!
198 T *DetachPtr()
199 {
200 T *ptr = m_array;
201 m_array = NULL;
202 return ptr;
203 }
204
205 // Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
206 // has no object in management.
207 T* GetPtr() const
208 {
209 return m_array;
210 }
211
212 void SwapPtr(ScopedArray& other)
213 {
214 T * const tmp = other.m_array;
215 other.m_array = m_array;
216 m_array = tmp;
217 }
218
219 // ----------------------------------------------------------------------------
220 // ScopedPtr Operators
221 // ----------------------------------------------------------------------------
222 // I've decided to use the ATL's approach to pointer validity tests, opposed to
223 // the wx/boost approach (which uses some bizarre member method pointer crap, and can't
224 // allow the T* implicit casting.
225
226 bool operator!() const throw()
227 {
228 return m_array == NULL;
229 }
230
231 // Equality
232 bool operator==(T* pT) const throw()
233 {
234 return m_array == pT;
235 }
236
237 // Inequality
238 bool operator!=(T* pT) const throw()
239 {
240 return !operator==(pT);
241 }
242
243 // Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
244 // of the managed pointer.
245 ScopedArray& operator=( T* src )
246 {
247 return Reassign( src );
248 }
249
250 T& operator[]( uint idx ) const
251 {
252 pxAssertDev( idx < m_valid_range, "Array index out of bounds on ScopedArray." );
253 return m_array[idx];
254 }
255 };
256
257 // --------------------------------------------------------------------------------------
258 // pxObjPtr -- fancified version of wxScopedPtr
259 // --------------------------------------------------------------------------------------
260 // This class is a non-null scoped pointer container. What that means is that the object
261 // always resets itself to a valid "placebo" function rather than NULL, such that methods
262 // can be invoked safely without fear of NULL pointer exceptions. This system is useful
263 // for objects where most or all public methods can fail silently, and still allow program
264 // execution flow to continue.
265 //
266 // It also implements basic scoped pointer behavior: when the pxObjPtr class is deleted,
267 // it will automatically delete the pointer in its posession, if the pointer is valid.
268 //
269 // Notes:
270 // * This class intentionally does not implement the "release" API, because it doesn't
271 // really make sense within the context of a non-nullable pointer specification.
272 //
273 template< typename T, T& DefaultStaticInst >
274 class pxObjPtr
275 {
276 DeclareNoncopyableObject(pxObjPtr);
277
278 protected:
279 T * m_ptr;
280
281 public:
282 typedef T element_type;
283
284 explicit pxObjPtr(T * ptr = &DefaultStaticInst) : m_ptr(ptr) { }
285
286 bool IsEmpty() const
287 {
288 return m_ptr != &DefaultStaticInst;
289 }
290
291 ~pxObjPtr()
292 {
293 if( !IsEmpty() ) delete m_ptr;
294 m_ptr = NULL;
295 }
296
297 // test for pointer validity: defining conversion to unspecified_bool_type
298 // and not more obvious bool to avoid implicit conversions to integer types
299 typedef T *(pxObjPtr<T,DefaultStaticInst>::*unspecified_bool_type)() const;
300
301 operator unspecified_bool_type() const
302 {
303 return ( !IsEmpty() ) ? &ScopedPtr<T>::get : NULL;
304 }
305
306 void reset(T * ptr = &DefaultStaticInst)
307 {
308 if ( ptr != m_ptr )
309 {
310 if( !IsEmpty() )
311 delete m_ptr;
312 m_ptr = ptr;
313 }
314 }
315
316 T& operator*() const
317 {
318 pxAssert(m_ptr != NULL);
319 return *m_ptr;
320 }
321
322 T* operator->() const
323 {
324 pxAssert(m_ptr != NULL);
325 return m_ptr;
326 }
327
328 T* get() const
329 {
330 pxAssert(m_ptr != NULL);
331 return m_ptr;
332 }
333
334 void swap(pxObjPtr& other)
335 {
336 // Neither pointer in either container should ever be NULL...
337 pxAssert(m_ptr != NULL);
338 pxAssert(other.m_ptr != NULL);
339
340 T * const tmp = other.m_ptr;
341 other.m_ptr = m_ptr;
342 m_ptr = tmp;
343 }
344 };
345

  ViewVC Help
Powered by ViewVC 1.1.22