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

Contents of /trunk/common/include/Utilities/SafeArray.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 7933 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 //////////////////////////////////////////////////////////////////////////////////////////
20 // Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
21 // pointer to null after deallocation.
22
23 #define safe_delete( ptr ) \
24 ((void) (delete (ptr)), (ptr) = NULL)
25
26 #define safe_delete_array( ptr ) \
27 ((void) (delete[] (ptr)), (ptr) = NULL)
28
29 // No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
30 // just about every compiler and libc implementation of any recentness.
31 #define safe_free( ptr ) \
32 ( (void) (free( ptr ), !!0), (ptr) = NULL )
33 //((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL))
34
35 #define safe_fclose( ptr ) \
36 ((void) (( ( (ptr) != NULL ) && (fclose( ptr ), !!0) ), (ptr) = NULL))
37
38 // Implementation note: all known implementations of _aligned_free check the pointer for
39 // NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
40 // do it here.
41 #define safe_aligned_free( ptr ) \
42 ((void) ( _aligned_free( ptr ), (ptr) = NULL ))
43
44 #define SafeSysMunmap( ptr, size ) \
45 ((void) ( HostSys::Munmap( (uptr)(ptr), size ), (ptr) = NULL ))
46
47 // Microsoft Windows only macro, useful for freeing out COM objects:
48 #define safe_release( ptr ) \
49 ((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL))
50
51 // --------------------------------------------------------------------------------------
52 // SafeArray
53 // --------------------------------------------------------------------------------------
54 // Handy little class for allocating a resizable memory block, complete with exception
55 // error handling and automatic cleanup. A lightweight alternative to std::vector.
56 //
57 template< typename T >
58 class SafeArray
59 {
60 DeclareNoncopyableObject(SafeArray);
61
62 public:
63 static const int DefaultChunkSize = 0x1000 * sizeof(T);
64
65 public:
66 wxString Name; // user-assigned block name
67 int ChunkSize;
68
69 protected:
70 T* m_ptr;
71 int m_size; // size of the allocation of memory
72
73 protected:
74 SafeArray( const wxChar* name, T* allocated_mem, int initSize );
75 virtual T* _virtual_realloc( int newsize );
76
77 // A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
78 // builds only -- no bounds checking is done in release builds).
79 T* _getPtr( uint i ) const
80 {
81 IndexBoundsAssumeDev( Name.c_str(), i, m_size );
82 return &m_ptr[i];
83 }
84
85 public:
86 virtual ~SafeArray() throw();
87
88 explicit SafeArray( const wxChar* name=L"Unnamed" );
89 explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" );
90
91 void Dispose();
92 void ExactAlloc( int newsize );
93 void MakeRoomFor( int newsize )
94 {
95 if( newsize > m_size )
96 ExactAlloc( newsize );
97 }
98
99 bool IsDisposed() const { return (m_ptr==NULL); }
100
101 // Returns the size of the memory allocation, as according to the array type.
102 int GetLength() const { return m_size; }
103 // Returns the size of the memory allocation in bytes.
104 int GetSizeInBytes() const { return m_size * sizeof(T); }
105
106 // Extends the containment area of the array. Extensions are performed
107 // in chunks.
108 void GrowBy( int items )
109 {
110 MakeRoomFor( m_size + ChunkSize + items + 1 );
111 }
112
113 // Gets a pointer to the requested allocation index.
114 // DevBuilds : Generates assertion if the index is invalid.
115 T *GetPtr( uint idx=0 ) { return _getPtr( idx ); }
116 const T *GetPtr( uint idx=0 ) const { return _getPtr( idx ); }
117
118 // Gets an element of this memory allocation much as if it were an array.
119 // DevBuilds : Generates assertion if the index is invalid.
120 T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
121 const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
122
123 virtual SafeArray<T>* Clone() const;
124 };
125
126 //////////////////////////////////////////////////////////////////////////////////////////
127 // SafeList - Simple growable container without all the mess or hassle of std containers.
128 //
129 // This container is intended for reasonably simple class types only. Things which this
130 // container does not handle with desired robustness:
131 //
132 // * Classes with non-trivial constructors (such that construction creates much overhead)
133 // * Classes with copy constructors (copying is done using performance memcpy)
134 // * Classes with destructors (they're not called, sorry!)
135 //
136 template< typename T >
137 class SafeList
138 {
139 DeclareNoncopyableObject(SafeList);
140
141 public:
142 static const int DefaultChunkSize = 0x80 * sizeof(T);
143
144 public:
145 wxString Name; // user-assigned block name
146 int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
147
148 protected:
149 T* m_ptr;
150 int m_allocsize; // size of the allocation of memory
151 uint m_length; // length of the array (active items, not buffer allocation)
152
153 protected:
154 virtual T* _virtual_realloc( int newsize );
155 void _MakeRoomFor_threshold( int newsize );
156
157 T* _getPtr( uint i ) const
158 {
159 IndexBoundsAssumeDev( Name.c_str(), i, m_length );
160 return &m_ptr[i];
161 }
162
163 public:
164 virtual ~SafeList() throw();
165 explicit SafeList( const wxChar* name=L"Unnamed" );
166 explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" );
167 virtual SafeList<T>* Clone() const;
168
169 void Remove( int index );
170 void MakeRoomFor( int blockSize );
171
172 T& New();
173 int Add( const T& src );
174 T& AddNew( const T& src );
175
176 // Returns the size of the list, as according to the array type. This includes
177 // mapped items only. The actual size of the allocation may differ.
178 int GetLength() const { return m_length; }
179
180 // Returns the size of the list, in bytes. This includes mapped items only.
181 // The actual size of the allocation may differ.
182 int GetSizeInBytes() const { return m_length * sizeof(T); }
183
184 void MatchLengthToAllocatedSize()
185 {
186 m_length = m_allocsize;
187 }
188
189 void GrowBy( int items )
190 {
191 MakeRoomFor( m_length + ChunkSize + items + 1 );
192 }
193
194 // Sets the item length to zero. Does not free memory allocations.
195 void Clear()
196 {
197 m_length = 0;
198 }
199
200 // Gets an element of this memory allocation much as if it were an array.
201 // DevBuilds : Generates assertion if the index is invalid.
202 T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
203 const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
204
205 T* GetPtr() { return m_ptr; }
206 const T* GetPtr() const { return m_ptr; }
207
208 T& GetLast() { return m_ptr[m_length-1]; }
209 const T& GetLast() const{ return m_ptr[m_length-1]; }
210 };
211
212 // --------------------------------------------------------------------------------------
213 // SafeAlignedArray<T>
214 // --------------------------------------------------------------------------------------
215 // Handy little class for allocating a resizable memory block, complete with
216 // exception-based error handling and automatic cleanup.
217 // This one supports aligned data allocations too!
218
219 template< typename T, uint Alignment >
220 class SafeAlignedArray : public SafeArray<T>
221 {
222 typedef SafeArray<T> _parent;
223
224 protected:
225 T* _virtual_realloc( int newsize );
226
227 public:
228 using _parent::operator[];
229
230 virtual ~SafeAlignedArray() throw();
231
232 explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
233 SafeArray<T>::SafeArray( name )
234 {
235 }
236
237 explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" );
238 virtual SafeAlignedArray<T,Alignment>* Clone() const;
239 };
240

  ViewVC Help
Powered by ViewVC 1.1.22