Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 343 lines (284 sloc) 7.752 kb
c143e77 @vade Moving everything to Trunk in prep for Branch "helper app" Open Emu proj...
vade authored
1 ////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // Nestopia - NES/Famicom emulator written in C++
4 //
5 // Copyright (C) 2003-2008 Martin Freij
6 //
7 // This file is part of Nestopia.
8 //
9 // Nestopia is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Nestopia is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Nestopia; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 //
23 ////////////////////////////////////////////////////////////////////////////////////////
24
25 #ifndef NST_VECTOR_H
26 #define NST_VECTOR_H
27
28 #ifndef NST_ASSERT_H
29 #include "NstAssert.hpp"
30 #endif
31
32 #ifdef NST_PRAGMA_ONCE
33 #pragma once
34 #endif
35
36 namespace Nes
37 {
38 namespace Core
39 {
40 template<typename T>
41 class Vector;
42
43 template<>
44 class Vector<void>
45 {
46 public:
47
48 static void* Malloc(dword);
49 static void* Realloc(void*,dword);
50 static void Free(void*);
51 static void Copy(void*,const void*,dword);
52 static void Move(void*,const void*,dword);
53
54 template<typename T>
55 static void Copy(T& dst,const T& src)
56 {
57 Copy( &dst, &src, sizeof(T) );
58 }
59 };
60
61 template<> inline void Vector<void>::Copy(char& dst,const char& src) { dst = src; }
62 template<> inline void Vector<void>::Copy(schar& dst,const schar& src) { dst = src; }
63 template<> inline void Vector<void>::Copy(uchar& dst,const uchar& src) { dst = src; }
64 template<> inline void Vector<void>::Copy(short& dst,const short& src) { dst = src; }
65 template<> inline void Vector<void>::Copy(ushort& dst,const ushort& src) { dst = src; }
66 template<> inline void Vector<void>::Copy(int& dst,const int& src) { dst = src; }
67 template<> inline void Vector<void>::Copy(uint& dst,const uint& src) { dst = src; }
68 template<> inline void Vector<void>::Copy(long& dst,const long& src) { dst = src; }
69 template<> inline void Vector<void>::Copy(ulong& dst,const ulong& src) { dst = src; }
70
71 template<typename T>
72 class Vector
73 {
74 T* data;
75 dword size;
76 dword capacity;
77
78 void MakeRoom(dword);
79
80 typedef Vector<void> Allocator;
81
82 public:
83
84 typedef T Type;
85
86 Vector();
87 explicit Vector(dword);
88 Vector(const Vector<T>&);
89 Vector(const T*,dword);
90
91 bool operator == (const Vector<T>&) const;
92
93 void Reserve(dword);
94 void Resize(dword);
95 void Expand(dword);
96 void Assign(const T*,dword);
97 void Append(const T&);
98 void Append(const T*,dword);
99 T* Insert(T*,const T&);
100 void Erase(T*,dword=1);
101 void Destroy();
102 void Defrag();
103
104 static void Swap(Vector<T>&,Vector<T>&);
105
106 ~Vector()
107 {
108 Allocator::Free( data );
109 }
110
111 void operator = (const Vector<T>& vector)
112 {
113 Assign( vector.data, vector.size );
114 }
115
116 void operator += (const Vector<T>& vector)
117 {
118 Append( vector.data, vector.size );
119 }
120
121 T& operator [] (dword i) const
122 {
123 NST_ASSERT( i < size );
124 return data[i];
125 }
126
127 T* Begin() const
128 {
129 return data;
130 }
131
132 T* End() const
133 {
134 return data + size;
135 }
136
137 dword Size() const
138 {
139 return size;
140 }
141
142 dword Capacity() const
143 {
144 return capacity;
145 }
146
147 T& Front() const
148 {
149 NST_ASSERT( size );
150 return data[0];
151 }
152
153 T& Back() const
154 {
155 NST_ASSERT( size );
156 return data[size - 1];
157 }
158
159 const T& Pop()
160 {
161 NST_ASSERT( size );
162 return data[--size];
163 }
164
165 void SetTo(dword count)
166 {
167 NST_ASSERT( count <= capacity );
168 size = count;
169 }
170
171 void Clear()
172 {
173 size = 0;
174 }
175 };
176
177 template<typename T>
178 Vector<T>::Vector()
179 : data(NULL), size(0), capacity(0) {}
180
181 template<typename T>
182 Vector<T>::Vector(const dword count)
183 : data(count ? static_cast<T*>(Allocator::Malloc(count * sizeof(T))) : NULL), size(count), capacity(count)
184 {
185 }
186
187 template<typename T>
188 Vector<T>::Vector(const T* in,const dword count)
189 : data(count ? static_cast<T*>(Allocator::Malloc(count * sizeof(T))) : NULL), size(count), capacity(count)
190 {
191 Allocator::Copy( data, in, count * sizeof(T) );
192 }
193
194 template<typename T>
195 Vector<T>::Vector(const Vector<T>& v)
196 : data(v.size ? static_cast<T*>(Allocator::Malloc(v.size * sizeof(T))) : NULL), size(v.size), capacity(v.size)
197 {
198 Allocator::Copy( data, v.data, v.size * sizeof(T) );
199 }
200
201 template<typename T>
202 void Vector<T>::MakeRoom(const dword count)
203 {
204 NST_ASSERT( count );
205 data = static_cast<T*>(Allocator::Realloc( data, count * sizeof(T) ));
206 capacity = count;
207 }
208
209 template<typename T>
210 void Vector<T>::Append(const T& value)
211 {
212 if (size == capacity)
213 MakeRoom( (size + 1) * 2 );
214
215 Allocator::Copy( data[size++], value );
216 }
217
218 template<typename T>
219 void Vector<T>::Assign(const T* const NST_RESTRICT inData,const dword inSize)
220 {
221 if (capacity < inSize)
222 MakeRoom( inSize );
223
224 Allocator::Copy( data, inData, (size=inSize) * sizeof(T) );
225 }
226
227 template<typename T>
228 void Vector<T>::Append(const T* const NST_RESTRICT inData,const dword inSize)
229 {
230 if (capacity < size + inSize)
231 MakeRoom( (size * 2) + inSize );
232
233 void* const tmp = data + size;
234 size += inSize;
235
236 Allocator::Copy( tmp, inData, inSize * sizeof(T) );
237 }
238
239 template<typename T>
240 T* Vector<T>::Insert(T* it,const T& value)
241 {
242 const dword pos = it - data;
243
244 if (size++ == capacity)
245 MakeRoom( size * 2 );
246
247 Allocator::Move( data+pos+1, data+pos, (size - (pos+1)) * sizeof(T) );
248 Allocator::Copy( data[pos], value );
249
250 return data+pos;
251 }
252
253 template<typename T>
254 void Vector<T>::Erase(T* it,dword count)
255 {
256 NST_ASSERT( size >= count );
257
258 const dword s = size;
259 size -= count;
260 Allocator::Move( it, it + count, (s - ((it-data) + count)) * sizeof(T) );
261 }
262
263 template<typename T>
264 void Vector<T>::Reserve(dword count)
265 {
266 if (capacity < count)
267 MakeRoom( count );
268 }
269
270 template<typename T>
271 void Vector<T>::Resize(dword count)
272 {
273 Reserve( count );
274 size = count;
275 }
276
277 template<typename T>
278 void Vector<T>::Expand(dword count)
279 {
280 Reserve( size + count );
281 size += count;
282 }
283
284 template<typename T>
285 void Vector<T>::Defrag()
286 {
287 if (size)
288 {
289 MakeRoom( size );
290 }
291 else if (void* const tmp = data)
292 {
293 data = NULL;
294 capacity = 0;
295 Allocator::Free( tmp );
296 }
297 }
298
299 template<typename T>
300 bool Vector<T>::operator == (const Vector<T>& vector) const
301 {
302 if (size != vector.size)
303 return false;
304
305 for (const T *a=data, *b=vector.data, *const end=data+size; a != end; ++a, ++b)
306 {
307 if (!(*a == *b))
308 return false;
309 }
310
311 return true;
312 }
313
314 template<typename T>
315 void Vector<T>::Destroy()
316 {
317 if (void* const tmp = data)
318 {
319 data = NULL;
320 size = 0;
321 capacity = 0;
322 Allocator::Free( tmp );
323 }
324 }
325
326 template<typename T>
327 void Vector<T>::Swap(Vector<T>& a,Vector<T>& b)
328 {
329 T* t = a.data;
330 a.data = b.data;
331 b.data = t;
332 dword u = a.size;
333 a.size = b.size;
334 b.size = u;
335 u = a.capacity;
336 a.capacity = b.capacity;
337 b.capacity = u;
338 }
339 }
340 }
341
342 #endif
Something went wrong with that request. Please try again.