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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (hide 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 william 31 /* 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 william 273 #include "Assertions.h"
19    
20 william 31 // --------------------------------------------------------------------------------------
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 william 401 // 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 william 31 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 william 62 wxEXPLICIT ScopedArray( size_t size )
166 william 31 {
167 william 62 m_array = new T[size];
168     m_valid_range = size;
169 william 31 }
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 william 273 m_valid_range = 0xffffffff;
181 william 31 }
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