]>
Commit | Line | Data |
---|---|---|
30122bae | 1 | /**************************************************************************** |
2 | * This file is property of and copyright by the ALICE HLT Project * | |
3 | * ALICE Experiment at CERN, All rights reserved. * | |
4 | * * | |
5 | * Copyright (C) 2009 Matthias Kretz <kretz@kde.org> * | |
6 | * for The ALICE HLT Project. * | |
7 | * * | |
8 | * Permission to use, copy, modify and distribute this software and its * | |
9 | * documentation strictly for non-commercial purposes is hereby granted * | |
10 | * without fee, provided that the above copyright notice appears in all * | |
11 | * copies and that both the copyright notice and this permission notice * | |
12 | * appear in the supporting documentation. The authors make no claims * | |
13 | * about the suitability of this software for any purpose. It is * | |
14 | * provided "as is" without express or implied warranty. * | |
15 | ***************************************************************************/ | |
16 | ||
17 | /** | |
18 | * \file AliHLTArray.h | |
19 | * \author Matthias Kretz <kretz@kde.org> | |
20 | * | |
21 | * This file contains the classes AliHLTResizableArray and AliHLTFixedArray with AliHLTArray as base | |
22 | * class. It's a drop-in replacement for C-Arrays. It makes it easy to use variable sized arrays on | |
23 | * the stack and pass arrays as arguments to other functions with an optional bounds-checking | |
24 | * enabled for the whole time. | |
25 | */ | |
26 | ||
27 | #ifndef ALIHLTARRAY_H | |
28 | #define ALIHLTARRAY_H | |
29 | ||
30 | #ifndef assert | |
31 | #include <assert.h> | |
32 | #endif | |
33 | ||
34 | #if defined(__MMX__) || defined(__SSE__) | |
35 | #include <mm_malloc.h> | |
36 | #else | |
37 | #include <cstdlib> | |
38 | #endif | |
39 | ||
40 | namespace AliHLTArrayInternal | |
41 | { | |
42 | template<bool> class STATIC_ASSERT_FAILURE; | |
43 | template<> class STATIC_ASSERT_FAILURE<true> {}; | |
44 | } | |
45 | ||
46 | #define ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b | |
47 | #define ALIHLTARRAY_STATIC_ASSERT_CONCAT(a, b) ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) | |
48 | #define ALIHLTARRAY_STATIC_ASSERT(cond, msg) \ | |
49 | typedef AliHLTArrayInternal::STATIC_ASSERT_FAILURE<cond> ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \ | |
50 | ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg; \ | |
51 | (void) Error_##msg | |
52 | ||
53 | template<typename T, int Dim> class AliHLTArray; | |
54 | ||
55 | namespace AliHLTInternal | |
56 | { | |
57 | // XXX | |
58 | // The ArrayBoundsCheck and Allocator classes implement a virtual destructor only in order to | |
59 | // silence the -Weff-c++ warning. It really is not required for these classes to have a virtual | |
60 | // dtor since polymorphism is not used (AliHLTResizableArray and AliHLTFixedArray are allocated on | |
61 | // the stack only). The virtual dtor only adds an unnecessary vtable to the code. | |
62 | #ifndef ENABLE_ARRAY_BOUNDS_CHECKING | |
63 | /** | |
64 | * no-op implementation that for no-bounds-checking | |
65 | */ | |
66 | class ArrayBoundsCheck | |
67 | { | |
68 | protected: | |
69 | virtual inline ~ArrayBoundsCheck() {} | |
70 | inline bool IsInBounds( int ) const { return true; } | |
71 | inline void SetBounds( int, int ) {} | |
72 | inline void MoveBounds( int ) {} | |
73 | }; | |
74 | #define BOUNDS_CHECK(x, y) | |
75 | #else | |
76 | /** | |
77 | * implementation for bounds-checking. | |
78 | */ | |
79 | class ArrayBoundsCheck | |
80 | { | |
81 | protected: | |
82 | virtual inline ~ArrayBoundsCheck() {} | |
83 | /** | |
84 | * checks whether the given offset is valid | |
85 | */ | |
86 | inline bool IsInBounds( int x ) const; | |
87 | /** | |
88 | * set the start and end offsets that are still valid | |
89 | */ | |
90 | inline void SetBounds( int start, int end ) { fStart = start; fEnd = end; } | |
91 | /** | |
92 | * move the start and end offsets by the same amount | |
93 | */ | |
94 | inline void MoveBounds( int d ) { fStart += d; fEnd += d; } | |
95 | ||
96 | private: | |
97 | int fStart; | |
98 | int fEnd; | |
99 | }; | |
100 | #define BOUNDS_CHECK(x, y) if (AliHLTInternal::ArrayBoundsCheck::IsInBounds(x)) {} else return y | |
101 | #endif | |
102 | template<typename T, int alignment> class Allocator | |
103 | { | |
104 | protected: | |
105 | virtual inline ~Allocator() {} | |
106 | #if defined(__MMX__) || defined(__SSE__) | |
107 | static inline T *Alloc( int s ) { T *p = reinterpret_cast<T *>( _mm_malloc( s * sizeof( T ), alignment ) ); return new( p ) T[s]; } | |
108 | static inline void Free( const T *const p ) { /** p->~T(); */ _mm_free( p ); } // XXX: doesn't call dtor because it's an array | |
109 | #else | |
110 | static inline T *Alloc( int s ) { T *p; posix_memalign( &p, alignment, s * sizeof( T ) ); return new( p ) T[s]; } | |
111 | static inline void Free( const T *const p ) { std::free( p ); } // XXX: doesn't call dtor because it's an array | |
112 | #endif | |
113 | }; | |
114 | template<typename T> class Allocator<T, 0> | |
115 | { | |
116 | protected: | |
117 | virtual inline ~Allocator() {} | |
118 | static inline T *Alloc( int s ) { return new T[s]; } | |
119 | static inline void Free( const T *const p ) { delete[] p; } | |
120 | }; | |
121 | /** | |
122 | * Array base class for dimension dependent behavior | |
123 | */ | |
124 | template<typename T, int Dim> class ArrayBase; | |
125 | ||
126 | /** | |
127 | * 1-dim arrays only have operator[] | |
128 | */ | |
129 | template<typename T> | |
130 | class ArrayBase<T, 1> : public ArrayBoundsCheck | |
131 | { | |
132 | friend class ArrayBase<T, 2>; | |
133 | public: | |
134 | /** | |
135 | * return a reference to the value at the given index | |
136 | */ | |
137 | inline T &operator[]( int x ) { BOUNDS_CHECK( x, fData[0] ); return fData[x]; } | |
138 | /** | |
139 | * return a const reference to the value at the given index | |
140 | */ | |
141 | inline const T &operator[]( int x ) const { BOUNDS_CHECK( x, fData[0] ); return fData[x]; } | |
142 | ||
143 | protected: | |
144 | T *fData; | |
145 | inline void SetSize( int, int, int ) {} | |
146 | }; | |
147 | ||
148 | /** | |
149 | * 2-dim arrays should use operator(int, int) | |
150 | * operator[] can be used to return a 1-dim array | |
151 | */ | |
152 | template<typename T> | |
153 | class ArrayBase<T, 2> : public ArrayBoundsCheck | |
154 | { | |
155 | friend class ArrayBase<T, 3>; | |
156 | public: | |
157 | /** | |
158 | * return a reference to the value at the given indexes | |
159 | */ | |
160 | inline T &operator()( int x, int y ) { BOUNDS_CHECK( x * fStride + y, fData[0] ); return fData[x * fStride + y]; } | |
161 | /** | |
162 | * return a const reference to the value at the given indexes | |
163 | */ | |
164 | inline const T &operator()( int x, int y ) const { BOUNDS_CHECK( x * fStride + y, fData[0] ); return fData[x * fStride + y]; } | |
165 | /** | |
166 | * return a 1-dim array at the given index. This makes it behave like a 2-dim C-Array. | |
167 | */ | |
168 | inline AliHLTArray<T, 1> operator[]( int x ); | |
169 | /** | |
170 | * return a const 1-dim array at the given index. This makes it behave like a 2-dim C-Array. | |
171 | */ | |
172 | inline const AliHLTArray<T, 1> operator[]( int x ) const; | |
173 | ||
174 | protected: | |
175 | T *fData; | |
176 | int fStride; | |
177 | inline void SetSize( int, int y, int ) { fStride = y; } | |
178 | }; | |
179 | ||
180 | /** | |
181 | * 3-dim arrays should use operator(int, int, int) | |
182 | * operator[] can be used to return a 2-dim array | |
183 | */ | |
184 | template<typename T> | |
185 | class ArrayBase<T, 3> : public ArrayBoundsCheck | |
186 | { | |
187 | public: | |
188 | /** | |
189 | * return a reference to the value at the given indexes | |
190 | */ | |
191 | inline T &operator()( int x, int y, int z ); | |
192 | /** | |
193 | * return a const reference to the value at the given indexes | |
194 | */ | |
195 | inline const T &operator()( int x, int y, int z ) const; | |
196 | /** | |
197 | * return a 2-dim array at the given index. This makes it behave like a 3-dim C-Array. | |
198 | */ | |
199 | inline AliHLTArray<T, 2> operator[]( int x ); | |
200 | /** | |
201 | * return a const 2-dim array at the given index. This makes it behave like a 3-dim C-Array. | |
202 | */ | |
203 | inline const AliHLTArray<T, 2> operator[]( int x ) const; | |
204 | ||
205 | protected: | |
206 | T *fData; | |
207 | int fStrideX; | |
208 | int fStrideY; | |
209 | inline void SetSize( int, int y, int z ) { fStrideX = y * z; fStrideY = z; } | |
210 | }; | |
211 | ||
212 | // XXX AlignedData really is an internal struct, but the RuleChecker doesn't understand that | |
213 | template<typename T, unsigned int Size, int alignment> class AlignedData; | |
214 | template<typename T, unsigned int Size> class AlignedData<T, Size, 0> | |
215 | { | |
216 | protected: | |
217 | T d[Size]; | |
218 | }; | |
219 | #ifdef __GNUC__ | |
220 | #define ALIGN(n) __attribute__((aligned(n))) | |
221 | #else | |
222 | #define ALIGN(n) __declspec(align(n)) | |
223 | #endif | |
224 | template<typename T, unsigned int Size> class AlignedData<T, Size, 4> | |
225 | { | |
226 | protected: | |
227 | ALIGN( 4 ) T d[Size]; | |
228 | }; | |
229 | template<typename T, unsigned int Size> class AlignedData<T, Size, 8> | |
230 | { | |
231 | protected: | |
232 | ALIGN( 8 ) T d[Size]; | |
233 | }; | |
234 | template<typename T, unsigned int Size> class AlignedData<T, Size, 16> | |
235 | { | |
236 | protected: | |
237 | ALIGN( 16 ) T d[Size]; | |
238 | }; | |
239 | template<typename T, unsigned int Size> class AlignedData<T, Size, 32> | |
240 | { | |
241 | protected: | |
242 | ALIGN( 32 ) T d[Size]; | |
243 | }; | |
244 | template<typename T, unsigned int Size> class AlignedData<T, Size, 64> | |
245 | { | |
246 | protected: | |
247 | ALIGN( 64 ) T d[Size]; | |
248 | }; | |
249 | template<typename T, unsigned int Size> class AlignedData<T, Size, 128> | |
250 | { | |
251 | protected: | |
252 | ALIGN( 128 ) T d[Size]; | |
253 | }; | |
254 | #undef ALIGN | |
255 | } // namespace AliHLTInternal | |
256 | ||
257 | /** | |
258 | * C-Array like class with the dimension dependent behavior defined in the ArrayBase class | |
259 | */ | |
260 | template < typename T, int Dim = 1 > | |
261 | class AliHLTArray : public AliHLTInternal::ArrayBase<T, Dim> | |
262 | { | |
263 | public: | |
264 | typedef AliHLTInternal::ArrayBase<T, Dim> Parent; | |
265 | /** | |
266 | * allows you to check for validity of the array by casting to bool | |
267 | */ | |
268 | inline operator bool() const { return Parent::fData != 0; } | |
269 | /** | |
270 | * allows you to check for validity of the array | |
271 | */ | |
272 | inline bool IsValid() const { return Parent::fData != 0; } | |
273 | ||
274 | /** | |
275 | * returns a reference to the data at index 0 | |
276 | */ | |
277 | inline T &operator*() { BOUNDS_CHECK( 0, Parent::fData[0] ); return *Parent::fData; } | |
278 | /** | |
279 | * returns a const reference to the data at index 0 | |
280 | */ | |
281 | inline const T &operator*() const { BOUNDS_CHECK( 0, Parent::fData[0] ); return *Parent::fData; } | |
282 | ||
283 | /** | |
284 | * returns a pointer to the data | |
285 | * This circumvents bounds checking so it should not be used. | |
286 | */ | |
287 | inline T *Data() { return Parent::fData; } | |
288 | /** | |
289 | * returns a const pointer to the data | |
290 | * This circumvents bounds checking so it should not be used. | |
291 | */ | |
292 | inline const T *Data() const { return Parent::fData; } | |
293 | ||
294 | /** | |
295 | * moves the array base pointer so that the data that was once at index 0 will then be at index -x | |
296 | */ | |
297 | inline AliHLTArray operator+( int x ) const; | |
298 | /** | |
299 | * moves the array base pointer so that the data that was once at index 0 will then be at index x | |
300 | */ | |
301 | inline AliHLTArray operator-( int x ) const; | |
302 | }; | |
303 | ||
304 | /** | |
305 | * Owns the data. When it goes out of scope the data is freed. | |
306 | * | |
307 | * The memory is allocated on the heap. | |
308 | * | |
309 | * Instantiate this class on the stack. Allocation on the heap is disallowed. | |
310 | * | |
311 | * \param T type of the entries in the array. | |
312 | * \param Dim selects the operator[]/operator() behavior it should have. I.e. makes it behave like a | |
313 | * 1-, 2- or 3-dim array. (defaults to 1) | |
314 | * \param alignment Defaults to 0 (default alignment). Other valid values are any multiples of 2. | |
315 | * This is especially useful for aligning data for SIMD vectors. | |
316 | * | |
317 | * \warning when using alignment the type T may not have a destructor (well it may, but it won't be | |
318 | * called) | |
319 | * | |
320 | * Example: | |
321 | * \code | |
322 | * void init( AliHLTArray<int> a, int size ) | |
323 | * { | |
324 | * for ( int i = 0; i < size; ++i ) { | |
325 | * a[i] = i; | |
326 | * } | |
327 | * } | |
328 | * | |
329 | * int size = ...; | |
330 | * AliHLTResizableArray<int> foo( size ); // notice that size doesn't have to be a constant like it | |
331 | * // has to be for C-Arrays in ISO C++ | |
332 | * init( foo, size ); | |
333 | * // now foo[i] == i | |
334 | * | |
335 | * \endcode | |
336 | */ | |
337 | template < typename T, int Dim = 1, int alignment = 0 > | |
338 | class AliHLTResizableArray : public AliHLTArray<T, Dim>, public AliHLTInternal::Allocator<T, alignment> | |
339 | { | |
340 | public: | |
341 | typedef AliHLTInternal::ArrayBase<T, Dim> Parent; | |
342 | /** | |
343 | * does not allocate any memory | |
344 | */ | |
345 | inline AliHLTResizableArray(); | |
346 | /** | |
347 | * use for 1-dim arrays: allocates x * sizeof(T) bytes for the array | |
348 | */ | |
349 | inline AliHLTResizableArray( int x ); | |
350 | /** | |
351 | * use for 2-dim arrays: allocates x * y * sizeof(T) bytes for the array | |
352 | */ | |
353 | inline AliHLTResizableArray( int x, int y ); | |
354 | /** | |
355 | * use for 3-dim arrays: allocates x * y * z * sizeof(T) bytes for the array | |
356 | */ | |
357 | inline AliHLTResizableArray( int x, int y, int z ); | |
358 | ||
359 | /** | |
360 | * frees the data | |
361 | */ | |
362 | inline ~AliHLTResizableArray() { AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData ); } | |
363 | ||
364 | /** | |
365 | * use for 1-dim arrays: resizes the memory for the array to x * sizeof(T) bytes. | |
366 | * | |
367 | * \warning this does not keep your previous data. If you were looking for this you probably | |
368 | * want to use std::vector instead. | |
369 | */ | |
370 | inline void Resize( int x ); | |
371 | /** | |
372 | * use for 2-dim arrays: resizes the memory for the array to x * y * sizeof(T) bytes. | |
373 | * | |
374 | * \warning this does not keep your previous data. If you were looking for this you probably | |
375 | * want to use std::vector instead. | |
376 | */ | |
377 | inline void Resize( int x, int y ); | |
378 | /** | |
379 | * use for 3-dim arrays: resizes the memory for the array to x * y * z * sizeof(T) bytes. | |
380 | * | |
381 | * \warning this does not keep your previous data. If you were looking for this you probably | |
382 | * want to use std::vector instead. | |
383 | */ | |
384 | inline void Resize( int x, int y, int z ); | |
385 | ||
386 | private: | |
387 | // disable allocation on the heap | |
388 | void *operator new( size_t ); | |
389 | ||
390 | // disable copy | |
391 | AliHLTResizableArray( const AliHLTResizableArray & ); | |
392 | AliHLTResizableArray &operator=( const AliHLTResizableArray & ); | |
393 | }; | |
394 | ||
395 | /** | |
396 | * Owns the data. When it goes out of scope the data is freed. | |
397 | * | |
398 | * The memory is allocated on the stack. | |
399 | * | |
400 | * Instantiate this class on the stack. | |
401 | * | |
402 | * \param T type of the entries in the array. | |
403 | * \param Size number of entries in the array. | |
404 | * \param Dim selects the operator[]/operator() behavior it should have. I.e. makes it behave like a | |
405 | * 1-, 2- or 3-dim array. (defaults to 1) | |
406 | */ | |
407 | template < typename T, unsigned int Size, int Dim = 1, int alignment = 0 > | |
408 | class AliHLTFixedArray : public AliHLTArray<T, Dim> | |
409 | { | |
410 | public: | |
411 | typedef AliHLTInternal::ArrayBase<T, Dim> Parent; | |
412 | inline AliHLTFixedArray() { Parent::fData = &fDataOnStack.d[0]; Parent::SetBounds( 0, Size - 1 ); } | |
413 | ||
414 | private: | |
415 | // disable allocation on the heap | |
416 | void *operator new( size_t ); | |
417 | ||
418 | AliHLTInternal::AlignedData<T, Size, alignment> fDataOnStack; | |
419 | ||
420 | // disable copy | |
421 | AliHLTFixedArray( const AliHLTFixedArray & ); | |
422 | AliHLTFixedArray &operator=( const AliHLTFixedArray & ); | |
423 | }; | |
424 | ||
425 | ||
426 | ||
427 | ||
428 | ||
429 | //////////////////////// | |
430 | //// implementation //// | |
431 | //////////////////////// | |
432 | ||
433 | ||
434 | ||
435 | ||
436 | namespace AliHLTInternal | |
437 | { | |
438 | #ifdef ENABLE_ARRAY_BOUNDS_CHECKING | |
439 | inline bool ArrayBoundsCheck::IsInBounds( int x ) const | |
440 | { | |
441 | assert( x >= fStart ); | |
442 | assert( x <= fEnd ); | |
443 | return ( x >= fStart && x <= fEnd ); | |
444 | } | |
445 | #endif | |
446 | ||
447 | template<typename T> | |
448 | inline AliHLTArray<T, 1> ArrayBase<T, 2>::operator[]( int x ) | |
449 | { | |
450 | x *= fStride; | |
451 | typedef AliHLTArray<T, 1> AT1; | |
452 | BOUNDS_CHECK( x, AT1() ); | |
453 | AliHLTArray<T, 1> a; | |
454 | a.fData = &fData[x]; | |
455 | a.ArrayBoundsCheck::operator=( *this ); | |
456 | a.MoveBounds( -x ); | |
457 | return a; | |
458 | } | |
459 | ||
460 | template<typename T> | |
461 | inline const AliHLTArray<T, 1> ArrayBase<T, 2>::operator[]( int x ) const | |
462 | { | |
463 | x *= fStride; | |
464 | typedef AliHLTArray<T, 1> AT1; | |
465 | BOUNDS_CHECK( x, AT1() ); | |
466 | AliHLTArray<T, 1> a; | |
467 | a.fData = &fData[x]; | |
468 | a.ArrayBoundsCheck::operator=( *this ); | |
469 | a.MoveBounds( -x ); | |
470 | return a; | |
471 | } | |
472 | ||
473 | template<typename T> | |
474 | inline T &ArrayBase<T, 3>::operator()( int x, int y, int z ) | |
475 | { | |
476 | BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] ); | |
477 | return fData[x * fStrideX + y + fStrideY + z]; | |
478 | } | |
479 | template<typename T> | |
480 | inline const T &ArrayBase<T, 3>::operator()( int x, int y, int z ) const | |
481 | { | |
482 | BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] ); | |
483 | return fData[x * fStrideX + y + fStrideY + z]; | |
484 | } | |
485 | template<typename T> | |
486 | inline AliHLTArray<T, 2> ArrayBase<T, 3>::operator[]( int x ) | |
487 | { | |
488 | x *= fStrideX; | |
489 | typedef AliHLTArray<T, 2> AT2; | |
490 | BOUNDS_CHECK( x, AT2() ); | |
491 | AliHLTArray<T, 2> a; | |
492 | a.fData = &fData[x]; | |
493 | a.fStride = fStrideY; | |
494 | a.ArrayBoundsCheck::operator=( *this ); | |
495 | a.MoveBounds( -x ); | |
496 | return a; | |
497 | } | |
498 | template<typename T> | |
499 | inline const AliHLTArray<T, 2> ArrayBase<T, 3>::operator[]( int x ) const | |
500 | { | |
501 | x *= fStrideX; | |
502 | typedef AliHLTArray<T, 2> AT2; | |
503 | BOUNDS_CHECK( x, AT2() ); | |
504 | AliHLTArray<T, 2> a; | |
505 | a.fData = &fData[x]; | |
506 | a.fStride = fStrideY; | |
507 | a.ArrayBoundsCheck::operator=( *this ); | |
508 | a.MoveBounds( -x ); | |
509 | return a; | |
510 | } | |
511 | } // namespace AliHLTInternal | |
512 | ||
513 | ||
514 | template<typename T, int Dim> | |
515 | inline AliHLTArray<T, Dim> AliHLTArray<T, Dim>::operator+( int x ) const | |
516 | { | |
517 | AliHLTArray<T, Dim> r( *this ); | |
518 | r.fData += x; | |
519 | r.MoveBounds( -x ); | |
520 | return r; | |
521 | } | |
522 | template<typename T, int Dim> | |
523 | inline AliHLTArray<T, Dim> AliHLTArray<T, Dim>::operator-( int x ) const | |
524 | { | |
525 | AliHLTArray<T, Dim> r( *this ); | |
526 | r.fData -= x; | |
527 | r.MoveBounds( x ); | |
528 | return r; | |
529 | } | |
530 | ||
531 | template<typename T, int Dim, int alignment> | |
532 | inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray() | |
533 | { | |
534 | Parent::fData = 0; | |
535 | Parent::SetBounds( 0, -1 ); | |
536 | } | |
537 | template<typename T, int Dim, int alignment> | |
538 | inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x ) | |
539 | { | |
540 | ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_used_with_incorrect_dimension ); | |
541 | Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x ); | |
542 | Parent::SetBounds( 0, x - 1 ); | |
543 | } | |
544 | template<typename T, int Dim, int alignment> | |
545 | inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x, int y ) | |
546 | { | |
547 | ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_used_with_incorrect_dimension ); | |
548 | Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x * y ); | |
549 | Parent::SetSize( x, y, 0 ); | |
550 | Parent::SetBounds( 0, x * y - 1 ); | |
551 | } | |
552 | template<typename T, int Dim, int alignment> | |
553 | inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x, int y, int z ) | |
554 | { | |
555 | ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_used_with_incorrect_dimension ); | |
556 | Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x * y * z ); | |
557 | Parent::SetSize( x, y, z ); | |
558 | Parent::SetBounds( 0, x * y * z - 1 ); | |
559 | } | |
560 | template<typename T, int Dim, int alignment> | |
561 | inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x ) | |
562 | { | |
563 | ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_resize_used_with_incorrect_dimension ); | |
564 | AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData ); | |
565 | Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x ); | |
566 | Parent::SetBounds( 0, x - 1 ); | |
567 | } | |
568 | template<typename T, int Dim, int alignment> | |
569 | inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x, int y ) | |
570 | { | |
571 | ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_resize_used_with_incorrect_dimension ); | |
572 | AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData ); | |
573 | Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x * y ); | |
574 | Parent::SetSize( x, y, 0 ); | |
575 | Parent::SetBounds( 0, x * y - 1 ); | |
576 | } | |
577 | template<typename T, int Dim, int alignment> | |
578 | inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x, int y, int z ) | |
579 | { | |
580 | ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_resize_used_with_incorrect_dimension ); | |
581 | AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData ); | |
582 | Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x * y * z ); | |
583 | Parent::SetSize( x, y, z ); | |
584 | Parent::SetBounds( 0, x * y * z - 1 ); | |
585 | } | |
586 | ||
587 | #undef BOUNDS_CHECK | |
588 | ||
589 | #endif // ALIHLTARRAY_H |