/[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 62 - (hide annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 5 months 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 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 william 62 wxEXPLICIT ScopedArray( size_t size )
159 william 31 {
160 william 62 m_array = new T[size];
161     m_valid_range = size;
162 william 31 }
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