/[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 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (10 years, 1 month ago) by william
File MIME type: text/plain
File size: 8172 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug 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 // --------------------------------------------------------------------------------------
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( size_t size )
159 {
160 m_array = new T[size];
161 m_valid_range = size;
162 }
163
164 ~ScopedArray() throw()
165 { Delete(); }
166
167 ScopedArray& Reassign(T * ptr = NULL)
168 {
169 if( ptr != m_array )
170 {
171 Delete();
172 m_array = ptr;
173 }
174 return *this;
175 }
176
177 ScopedArray& Delete() throw()
178 {
179 // Thread-safe deletion: Set the pointer to NULL first, and then issue
180 // the deletion. This allows pending Application messages that might be
181 // dependent on the current object to nullify their actions.
182
183 T* deleteme = m_array;
184 m_array = NULL;
185 delete[] deleteme;
186
187 return *this;
188 }
189
190 // Removes the pointer from scoped management, but does not delete!
191 T *DetachPtr()
192 {
193 T *ptr = m_array;
194 m_array = NULL;
195 return ptr;
196 }
197
198 // Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
199 // has no object in management.
200 T* GetPtr() const
201 {
202 return m_array;
203 }
204
205 void SwapPtr(ScopedArray& other)
206 {
207 T * const tmp = other.m_array;
208 other.m_array = m_array;
209 m_array = tmp;
210 }
211
212 // ----------------------------------------------------------------------------
213 // ScopedPtr Operators
214 // ----------------------------------------------------------------------------
215 // I've decided to use the ATL's approach to pointer validity tests, opposed to
216 // the wx/boost approach (which uses some bizarre member method pointer crap, and can't
217 // allow the T* implicit casting.
218
219 bool operator!() const throw()
220 {
221 return m_array == NULL;
222 }
223
224 // Equality
225 bool operator==(T* pT) const throw()
226 {
227 return m_array == pT;
228 }
229
230 // Inequality
231 bool operator!=(T* pT) const throw()
232 {
233 return !operator==(pT);
234 }
235
236 // Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
237 // of the managed pointer.
238 ScopedArray& operator=( T* src )
239 {
240 return Reassign( src );
241 }
242
243 T& operator[]( uint idx ) const
244 {
245 pxAssertDev( idx < m_valid_range, "Array index out of bounds on ScopedArray." );
246 return m_array[idx];
247 }
248 };
249
250 // --------------------------------------------------------------------------------------
251 // pxObjPtr -- fancified version of wxScopedPtr
252 // --------------------------------------------------------------------------------------
253 // This class is a non-null scoped pointer container. What that means is that the object
254 // always resets itself to a valid "placebo" function rather than NULL, such that methods
255 // can be invoked safely without fear of NULL pointer exceptions. This system is useful
256 // for objects where most or all public methods can fail silently, and still allow program
257 // execution flow to continue.
258 //
259 // It also implements basic scoped pointer behavior: when the pxObjPtr class is deleted,
260 // it will automatically delete the pointer in its posession, if the pointer is valid.
261 //
262 // Notes:
263 // * This class intentionally does not implement the "release" API, because it doesn't
264 // really make sense within the context of a non-nullable pointer specification.
265 //
266 template< typename T, T& DefaultStaticInst >
267 class pxObjPtr
268 {
269 DeclareNoncopyableObject(pxObjPtr);
270
271 protected:
272 T * m_ptr;
273
274 public:
275 typedef T element_type;
276
277 explicit pxObjPtr(T * ptr = &DefaultStaticInst) : m_ptr(ptr) { }
278
279 bool IsEmpty() const
280 {
281 return m_ptr != &DefaultStaticInst;
282 }
283
284 ~pxObjPtr()
285 {
286 if( !IsEmpty() ) delete m_ptr;
287 m_ptr = NULL;
288 }
289
290 // test for pointer validity: defining conversion to unspecified_bool_type
291 // and not more obvious bool to avoid implicit conversions to integer types
292 typedef T *(pxObjPtr<T,DefaultStaticInst>::*unspecified_bool_type)() const;
293
294 operator unspecified_bool_type() const
295 {
296 return ( !IsEmpty() ) ? &ScopedPtr<T>::get : NULL;
297 }
298
299 void reset(T * ptr = &DefaultStaticInst)
300 {
301 if ( ptr != m_ptr )
302 {
303 if( !IsEmpty() )
304 delete m_ptr;
305 m_ptr = ptr;
306 }
307 }
308
309 T& operator*() const
310 {
311 pxAssert(m_ptr != NULL);
312 return *m_ptr;
313 }
314
315 T* operator->() const
316 {
317 pxAssert(m_ptr != NULL);
318 return m_ptr;
319 }
320
321 T* get() const
322 {
323 pxAssert(m_ptr != NULL);
324 return m_ptr;
325 }
326
327 void swap(pxObjPtr& other)
328 {
329 // Neither pointer in either container should ever be NULL...
330 pxAssert(m_ptr != NULL);
331 pxAssert(other.m_ptr != NULL);
332
333 T * const tmp = other.m_ptr;
334 other.m_ptr = m_ptr;
335 m_ptr = tmp;
336 }
337 };
338

  ViewVC Help
Powered by ViewVC 1.1.22