/[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 31 - (hide 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 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     // --------------------------------------------------------------------------------------
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