Changeset 1293
- Timestamp:
- Apr 25, 2012, 1:05:09 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/array.h
r1285 r1293 12 12 // The Array class 13 13 // --------------- 14 // A very simple Array class not unlike the std::vector. 14 // A very simple Array class not unlike the std::vector, with some nice 15 // additional features, eg. Array<int,float> for automatic arrays of structs. 15 16 // 16 17 … … 23 24 { 24 25 25 template<typename T1, typename T2 = void, typename T3 = void> class Array 26 { 27 public: 28 typedef struct { T1 m1; T2 m2; T3 m3; } Element; 29 30 inline Array() : m_data(0), m_count(0), m_reserved(0) {} 31 inline ~Array() { delete[] m_data; } 32 33 Array(Array const& that) : m_data(0), m_count(0), m_reserved(0) 26 /* 27 * The base array type 28 * FIXME: only works properly with POD types for now 29 */ 30 31 template<typename T> class ArrayBase 32 { 33 public: 34 typedef T Element; 35 36 inline ArrayBase() : m_data(0), m_count(0), m_reserved(0) {} 37 inline ~ArrayBase() { delete[] m_data; } 38 39 ArrayBase(ArrayBase const& that) : m_data(0), m_count(0), m_reserved(0) 34 40 { 35 41 Reserve(that.m_reserved); … … 38 44 } 39 45 40 Array & operator=(Arrayconst& that)46 ArrayBase& operator=(ArrayBase const& that) 41 47 { 42 48 m_data = 0; … … 59 65 } 60 66 61 inline Array <T1, T2, T3> const& operator<<(Elementconst &x)67 inline ArrayBase<T> const& operator<<(T const &x) 62 68 { 63 69 if (m_count >= m_reserved) 64 70 { 65 /* Protect ourselves against insertion of an element that is 66 * already in m_data. */ 67 Element tmp = x; 71 T tmp = x; 68 72 Reserve(m_count * 13 / 8 + 8); 69 73 m_data[m_count++] = tmp; 70 74 } 71 75 else 76 { 72 77 m_data[m_count++] = x; 78 } 73 79 return *this; 74 80 } 75 81 76 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3) 77 { 78 if (m_count >= m_reserved) 79 { 80 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; 81 Reserve(m_count * 13 / 8 + 8); 82 m_data[m_count].m1 = tmp1; 83 m_data[m_count].m2 = tmp2; 84 m_data[m_count].m3 = tmp3; 85 } 86 else 87 { 88 m_data[m_count].m1 = m1; 89 m_data[m_count].m2 = m2; 90 m_data[m_count].m3 = m3; 91 } 92 ++m_count; 82 inline void Append(T const &x) 83 { 84 *this << x; 93 85 } 94 86 … … 123 115 inline int Bytes() const { return m_count * sizeof(Element); } 124 116 125 pr ivate:117 protected: 126 118 Element *m_data; 127 119 int m_count, m_reserved; 128 120 }; 129 121 130 template<typename T1, typename T2> class Array<T1, T2, void> 131 { 132 public: 133 typedef struct { T1 m1; T2 m2; } Element; 134 135 inline Array() : m_data(0), m_count(0), m_reserved(0) {} 136 inline ~Array() { delete[] m_data; } 137 138 Array(Array const& that) : m_data(0), m_count(0), m_reserved(0) 139 { 140 Reserve(that.m_reserved); 141 memcpy(m_data, that.m_data, m_count * sizeof(Element)); 142 m_count = that.m_count; 143 } 144 145 Array& operator=(Array const& that) 146 { 147 m_data = 0; 148 m_count = 0; 149 m_reserved = 0; 150 Reserve(that.m_reserved); 151 memcpy(m_data, that.m_data, that.m_count * sizeof(Element)); 152 m_count = that.m_count; 153 return *this; 154 } 155 156 inline Element& operator[](int n) 157 { 158 return m_data[n]; 159 } 160 161 inline Element const& operator[](int n) const 162 { 163 return m_data[n]; 164 } 165 166 inline Array<T1, T2> const& operator<<(Element const &x) 167 { 168 if (m_count >= m_reserved) 169 { 170 /* Protect ourselves against insertion of an element that is 171 * already in m_data. */ 172 Element tmp = x; 173 Reserve(m_count * 13 / 8 + 8); 174 m_data[m_count++] = tmp; 175 } 176 else 177 m_data[m_count++] = x; 178 return *this; 179 } 180 122 /* 123 * Element types 124 */ 125 126 template<typename T1, typename T2, typename T3 = void, typename T4 = void, 127 typename T5 = void, typename T6 = void, typename T7 = void, 128 typename T8 = void> 129 class ArrayElement 130 { 131 public: 132 T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; T7 m7; T8 m8; 133 }; 134 135 template<typename T1, typename T2, typename T3, typename T4, typename T5, 136 typename T6, typename T7> 137 class ArrayElement<T1, T2, T3, T4, T5, T6, T7, void> 138 { 139 public: 140 T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; T7 m7; 141 }; 142 143 template<typename T1, typename T2, typename T3, typename T4, typename T5, 144 typename T6> 145 class ArrayElement<T1, T2, T3, T4, T5, T6, void, void> 146 { 147 public: 148 T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; T6 m6; 149 }; 150 151 template<typename T1, typename T2, typename T3, typename T4, typename T5> 152 class ArrayElement<T1, T2, T3, T4, T5, void, void, void> 153 { 154 public: 155 T1 m1; T2 m2; T3 m3; T4 m4; T5 m5; 156 }; 157 158 template<typename T1, typename T2, typename T3, typename T4> 159 class ArrayElement<T1, T2, T3, T4, void, void, void, void> 160 { 161 public: 162 T1 m1; T2 m2; T3 m3; T4 m4; 163 }; 164 165 template<typename T1, typename T2, typename T3> 166 class ArrayElement<T1, T2, T3, void, void, void, void, void> 167 { 168 public: 169 T1 m1; T2 m2; T3 m3; 170 }; 171 172 template<typename T1, typename T2> 173 class ArrayElement<T1, T2, void, void, void, void, void, void> 174 { 175 public: 176 T1 m1; T2 m2; 177 }; 178 179 /* 180 * Array specialisations implementing specific setters 181 */ 182 183 template<typename T1, typename T2 = void, typename T3 = void, 184 typename T4 = void, typename T5 = void, typename T6 = void, 185 typename T7 = void, typename T8 = void> 186 class Array : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, T7, T8> > 187 { 188 public: 189 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4, 190 T5 const &m5, T6 const &m6, T7 const &m7, T8 const &m8) 191 { 192 if (this->m_count >= this->m_reserved) 193 { 194 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4; 195 T5 tmp5 = m5; T6 tmp6 = m6; T7 tmp7 = m7; T8 tmp8 = m8; 196 Reserve(this->m_count * 13 / 8 + 8); 197 this->m_data[this->m_count].m1 = tmp1; 198 this->m_data[this->m_count].m2 = tmp2; 199 this->m_data[this->m_count].m3 = tmp3; 200 this->m_data[this->m_count].m4 = tmp4; 201 this->m_data[this->m_count].m5 = tmp5; 202 this->m_data[this->m_count].m6 = tmp6; 203 this->m_data[this->m_count].m7 = tmp7; 204 this->m_data[this->m_count].m8 = tmp8; 205 } 206 else 207 { 208 this->m_data[this->m_count].m1 = m1; 209 this->m_data[this->m_count].m2 = m2; 210 this->m_data[this->m_count].m3 = m3; 211 this->m_data[this->m_count].m4 = m4; 212 this->m_data[this->m_count].m5 = m5; 213 this->m_data[this->m_count].m6 = m6; 214 this->m_data[this->m_count].m7 = m7; 215 this->m_data[this->m_count].m8 = m8; 216 } 217 ++this->m_count; 218 } 219 }; 220 221 template<typename T1, typename T2, typename T3, typename T4, typename T5, 222 typename T6, typename T7> 223 class Array<T1, T2, T3, T4, T5, T6, T7, void> 224 : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, T7, void> > 225 { 226 public: 227 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4, 228 T5 const &m5, T6 const &m6, T7 const &m7) 229 { 230 if (this->m_count >= this->m_reserved) 231 { 232 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4; 233 T5 tmp5 = m5; T6 tmp6 = m6; T7 tmp7 = m7; 234 Reserve(this->m_count * 13 / 8 + 8); 235 this->m_data[this->m_count].m1 = tmp1; 236 this->m_data[this->m_count].m2 = tmp2; 237 this->m_data[this->m_count].m3 = tmp3; 238 this->m_data[this->m_count].m4 = tmp4; 239 this->m_data[this->m_count].m5 = tmp5; 240 this->m_data[this->m_count].m6 = tmp6; 241 this->m_data[this->m_count].m7 = tmp7; 242 } 243 else 244 { 245 this->m_data[this->m_count].m1 = m1; 246 this->m_data[this->m_count].m2 = m2; 247 this->m_data[this->m_count].m3 = m3; 248 this->m_data[this->m_count].m4 = m4; 249 this->m_data[this->m_count].m5 = m5; 250 this->m_data[this->m_count].m6 = m6; 251 this->m_data[this->m_count].m7 = m7; 252 } 253 ++this->m_count; 254 } 255 }; 256 257 template<typename T1, typename T2, typename T3, typename T4, typename T5, 258 typename T6> 259 class Array<T1, T2, T3, T4, T5, T6, void, void> 260 : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, T6, void, void> > 261 { 262 public: 263 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4, 264 T5 const &m5, T6 const &m6) 265 { 266 if (this->m_count >= this->m_reserved) 267 { 268 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4; 269 T5 tmp5 = m5; T6 tmp6 = m6; 270 Reserve(this->m_count * 13 / 8 + 8); 271 this->m_data[this->m_count].m1 = tmp1; 272 this->m_data[this->m_count].m2 = tmp2; 273 this->m_data[this->m_count].m3 = tmp3; 274 this->m_data[this->m_count].m4 = tmp4; 275 this->m_data[this->m_count].m5 = tmp5; 276 this->m_data[this->m_count].m6 = tmp6; 277 } 278 else 279 { 280 this->m_data[this->m_count].m1 = m1; 281 this->m_data[this->m_count].m2 = m2; 282 this->m_data[this->m_count].m3 = m3; 283 this->m_data[this->m_count].m4 = m4; 284 this->m_data[this->m_count].m5 = m5; 285 this->m_data[this->m_count].m6 = m6; 286 } 287 ++this->m_count; 288 } 289 }; 290 291 template<typename T1, typename T2, typename T3, typename T4, typename T5> 292 class Array<T1, T2, T3, T4, T5, void, void, void> 293 : public ArrayBase<ArrayElement<T1, T2, T3, T4, T5, void, void, void> > 294 { 295 public: 296 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4, 297 T5 const &m5) 298 { 299 if (this->m_count >= this->m_reserved) 300 { 301 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4; 302 T5 tmp5 = m5; 303 Reserve(this->m_count * 13 / 8 + 8); 304 this->m_data[this->m_count].m1 = tmp1; 305 this->m_data[this->m_count].m2 = tmp2; 306 this->m_data[this->m_count].m3 = tmp3; 307 this->m_data[this->m_count].m4 = tmp4; 308 this->m_data[this->m_count].m5 = tmp5; 309 } 310 else 311 { 312 this->m_data[this->m_count].m1 = m1; 313 this->m_data[this->m_count].m2 = m2; 314 this->m_data[this->m_count].m3 = m3; 315 this->m_data[this->m_count].m4 = m4; 316 this->m_data[this->m_count].m5 = m5; 317 } 318 ++this->m_count; 319 } 320 }; 321 322 template<typename T1, typename T2, typename T3, typename T4> 323 class Array<T1, T2, T3, T4, void, void, void, void> 324 : public ArrayBase<ArrayElement<T1, T2, T3, T4, void, void, void, void> > 325 { 326 public: 327 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3, T4 const &m4) 328 { 329 if (this->m_count >= this->m_reserved) 330 { 331 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; T4 tmp4 = m4; 332 Reserve(this->m_count * 13 / 8 + 8); 333 this->m_data[this->m_count].m1 = tmp1; 334 this->m_data[this->m_count].m2 = tmp2; 335 this->m_data[this->m_count].m3 = tmp3; 336 this->m_data[this->m_count].m4 = tmp4; 337 } 338 else 339 { 340 this->m_data[this->m_count].m1 = m1; 341 this->m_data[this->m_count].m2 = m2; 342 this->m_data[this->m_count].m3 = m3; 343 this->m_data[this->m_count].m4 = m4; 344 } 345 ++this->m_count; 346 } 347 }; 348 349 template<typename T1, typename T2, typename T3> 350 class Array<T1, T2, T3, void, void, void, void, void> 351 : public ArrayBase<ArrayElement<T1, T2, T3, void, void, void, void, void> > 352 { 353 public: 354 inline void Append(T1 const &m1, T2 const &m2, T3 const &m3) 355 { 356 if (this->m_count >= this->m_reserved) 357 { 358 T1 tmp1 = m1; T2 tmp2 = m2; T3 tmp3 = m3; 359 Reserve(this->m_count * 13 / 8 + 8); 360 this->m_data[this->m_count].m1 = tmp1; 361 this->m_data[this->m_count].m2 = tmp2; 362 this->m_data[this->m_count].m3 = tmp3; 363 } 364 else 365 { 366 this->m_data[this->m_count].m1 = m1; 367 this->m_data[this->m_count].m2 = m2; 368 this->m_data[this->m_count].m3 = m3; 369 } 370 ++this->m_count; 371 } 372 }; 373 374 template<typename T1, typename T2> 375 class Array<T1, T2, void, void, void, void, void, void> 376 : public ArrayBase<ArrayElement<T1, T2, void, void, void, void, void, void> > 377 { 378 public: 181 379 inline void Append(T1 const &m1, T2 const &m2) 182 380 { 183 if ( m_count >=m_reserved)381 if (this->m_count >= this->m_reserved) 184 382 { 185 383 T1 tmp1 = m1; T2 tmp2 = m2; 186 Reserve(m_count * 13 / 8 + 8); 187 m_data[m_count].m1 = tmp1; 188 m_data[m_count].m2 = tmp2; 189 } 190 else 191 { 192 m_data[m_count].m1 = m1; 193 m_data[m_count].m2 = m2; 194 } 195 ++m_count; 196 } 197 198 void Remove(int pos) 199 { 200 memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1); 201 m_count--; 202 } 203 204 void Remove(int pos, int count) 205 { 206 memmove(m_data + pos, m_data + pos + count, m_count - pos - count); 207 m_count -= count; 208 } 209 210 void Reserve(int count) 211 { 212 if (count <= (int)m_reserved) 213 return; 214 215 Element *tmp = new Element[count]; 216 if (m_data) 217 { 218 memcpy(tmp, m_data, m_count * sizeof(Element)); 219 delete[] m_data; 220 } 221 m_data = tmp; 222 m_reserved = count; 223 } 224 225 inline int Count() const { return m_count; } 226 inline int Bytes() const { return m_count * sizeof(Element); } 227 228 private: 229 Element *m_data; 230 int m_count, m_reserved; 231 }; 232 233 template<typename T1> class Array<T1, void, void> 234 { 235 public: 236 typedef T1 Element; 237 238 inline Array() : m_data(0), m_count(0), m_reserved(0) {} 239 inline ~Array() { delete[] m_data; } 240 241 Array(Array const& that) : m_data(0), m_count(0), m_reserved(0) 242 { 243 Reserve(that.m_reserved); 244 memcpy(m_data, that.m_data, m_count * sizeof(Element)); 245 m_count = that.m_count; 246 } 247 248 Array& operator=(Array const& that) 249 { 250 m_data = 0; 251 m_count = 0; 252 m_reserved = 0; 253 Reserve(that.m_reserved); 254 memcpy(m_data, that.m_data, that.m_count * sizeof(Element)); 255 m_count = that.m_count; 256 return *this; 257 } 258 259 inline Element& operator[](int n) 260 { 261 return m_data[n]; 262 } 263 264 inline Element const& operator[](int n) const 265 { 266 return m_data[n]; 267 } 268 269 inline Array<T1> const& operator<<(T1 const &x) 270 { 271 if (m_count >= m_reserved) 272 { 273 T1 tmp = x; 274 Reserve(m_count * 13 / 8 + 8); 275 m_data[m_count++] = tmp; 276 } 277 else 278 { 279 m_data[m_count++] = x; 280 } 281 return *this; 282 } 283 284 inline void Append(T1 const &x) 285 { 286 *this << x; 287 } 288 289 void Remove(int pos) 290 { 291 memmove(m_data + pos, m_data + pos + 1, m_count - pos - 1); 292 m_count--; 293 } 294 295 void Remove(int pos, int count) 296 { 297 memmove(m_data + pos, m_data + pos + count, m_count - pos - count); 298 m_count -= count; 299 } 300 301 void Reserve(int count) 302 { 303 if (count <= (int)m_reserved) 304 return; 305 306 Element *tmp = new Element[count]; 307 if (m_data) 308 { 309 memcpy(tmp, m_data, m_count * sizeof(Element)); 310 delete[] m_data; 311 } 312 m_data = tmp; 313 m_reserved = count; 314 } 315 316 inline int Count() const { return m_count; } 317 inline int Bytes() const { return m_count * sizeof(Element); } 318 319 private: 320 Element *m_data; 321 int m_count, m_reserved; 384 Reserve(this->m_count * 13 / 8 + 8); 385 this->m_data[this->m_count].m1 = tmp1; 386 this->m_data[this->m_count].m2 = tmp2; 387 } 388 else 389 { 390 this->m_data[this->m_count].m1 = m1; 391 this->m_data[this->m_count].m2 = m2; 392 } 393 ++this->m_count; 394 } 395 }; 396 397 template<typename T> 398 class Array<T, void, void, void, void, void, void, void> : public ArrayBase<T> 399 { 322 400 }; 323 401
Note: See TracChangeset
for help on using the changeset viewer.