]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTArray.h
adding a member for the active CTP trigger mask to the CTP data object and setting...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTArray.h
CommitLineData
e18739d0 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// ****************************************************************************
30122bae 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
84e050b7 34#if (defined(__MMX__) || defined(__SSE__))
35#if defined(__GNUC__)
36#if __GNUC__ > 3
37#define USE_MM_MALLOC
38#endif
39#else // not gcc, assume it can use _mm_malloc since it supports MMX/SSE
40#define USE_MM_MALLOC
41#endif
42#endif
43
44#ifdef USE_MM_MALLOC
30122bae 45#include <mm_malloc.h>
46#else
47#include <cstdlib>
48#endif
49
e18739d0 50enum {
51 AliHLTFullyCacheLineAligned = -1
52};
53
9e2dadc1 54#if defined(__CUDACC__) & 0
55#define ALIHLTARRAY_STATIC_ASSERT(a, b)
56#define ALIHLTARRAY_STATIC_ASSERT_NC(a, b)
57#else
30122bae 58namespace AliHLTArrayInternal
59{
60 template<bool> class STATIC_ASSERT_FAILURE;
61 template<> class STATIC_ASSERT_FAILURE<true> {};
62}
63
64#define ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b
65#define ALIHLTARRAY_STATIC_ASSERT_CONCAT(a, b) ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b)
e18739d0 66#define ALIHLTARRAY_STATIC_ASSERT_NC(cond, msg) \
30122bae 67 typedef AliHLTArrayInternal::STATIC_ASSERT_FAILURE<cond> ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \
e18739d0 68 ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg
69#define ALIHLTARRAY_STATIC_ASSERT(cond, msg) ALIHLTARRAY_STATIC_ASSERT_NC(cond, msg); (void) Error_##msg
9e2dadc1 70#endif
30122bae 71
72template<typename T, int Dim> class AliHLTArray;
73
74namespace AliHLTInternal
75{
e18739d0 76 template<unsigned int Size> struct Padding { char fPadding[Size]; };
77 template<> struct Padding<0> {};
78 template<typename T> struct CacheLineSizeHelperData { T fData; };
79 template<typename T> struct CacheLineSizeHelperEnums {
80 enum {
81 CacheLineSize = 64,
82 MaskedSize = sizeof( T ) & ( CacheLineSize - 1 ),
83 RequiredSize = MaskedSize == 0 ? sizeof( T ) : sizeof( T ) + CacheLineSize - MaskedSize,
84 PaddingSize = RequiredSize - sizeof( T )
85 };
86 };
87 template<typename T> class CacheLineSizeHelper : private CacheLineSizeHelperData<T>, private Padding<CacheLineSizeHelperEnums<T>::PaddingSize>
88 {
89 public:
90 operator T &() { return CacheLineSizeHelperData<T>::fData; }
91 operator const T &() const { return CacheLineSizeHelperData<T>::fData; }
92 //const T &operator=( const T &rhs ) { CacheLineSizeHelperData<T>::fData = rhs; }
93
94 private:
95 };
96 template<typename T, int alignment> struct TypeForAlignmentHelper { typedef T Type; };
97 template<typename T> struct TypeForAlignmentHelper<T, AliHLTFullyCacheLineAligned> { typedef CacheLineSizeHelper<T> Type; };
98
30122bae 99 // XXX
100 // The ArrayBoundsCheck and Allocator classes implement a virtual destructor only in order to
e18739d0 101 // silence the -Weffc++ warning. It really is not required for these classes to have a virtual
30122bae 102 // dtor since polymorphism is not used (AliHLTResizableArray and AliHLTFixedArray are allocated on
103 // the stack only). The virtual dtor only adds an unnecessary vtable to the code.
104#ifndef ENABLE_ARRAY_BOUNDS_CHECKING
105 /**
106 * no-op implementation that for no-bounds-checking
107 */
108 class ArrayBoundsCheck
109 {
110 protected:
111 virtual inline ~ArrayBoundsCheck() {}
112 inline bool IsInBounds( int ) const { return true; }
113 inline void SetBounds( int, int ) {}
114 inline void MoveBounds( int ) {}
e18739d0 115 inline void ReinterpretCast( const ArrayBoundsCheck &, int, int ) {}
30122bae 116 };
117#define BOUNDS_CHECK(x, y)
118#else
119 /**
120 * implementation for bounds-checking.
121 */
122 class ArrayBoundsCheck
123 {
124 protected:
125 virtual inline ~ArrayBoundsCheck() {}
126 /**
127 * checks whether the given offset is valid
128 */
129 inline bool IsInBounds( int x ) const;
130 /**
131 * set the start and end offsets that are still valid
132 */
133 inline void SetBounds( int start, int end ) { fStart = start; fEnd = end; }
134 /**
135 * move the start and end offsets by the same amount
136 */
137 inline void MoveBounds( int d ) { fStart += d; fEnd += d; }
138
e18739d0 139 inline void ReinterpretCast( const ArrayBoundsCheck &other, int sizeofOld, int sizeofNew ) {
140 fStart = other.fStart * sizeofNew / sizeofOld;
141 fEnd = other.fEnd * sizeofNew / sizeofOld;
142 }
143
30122bae 144 private:
145 int fStart;
146 int fEnd;
147 };
148#define BOUNDS_CHECK(x, y) if (AliHLTInternal::ArrayBoundsCheck::IsInBounds(x)) {} else return y
149#endif
150 template<typename T, int alignment> class Allocator
151 {
e18739d0 152 public:
84e050b7 153#ifdef USE_MM_MALLOC
30122bae 154 static inline T *Alloc( int s ) { T *p = reinterpret_cast<T *>( _mm_malloc( s * sizeof( T ), alignment ) ); return new( p ) T[s]; }
e18739d0 155 static inline void Free( T *const p, int size ) {
156 for ( int i = 0; i < size; ++i ) {
157 p[i].~T();
158 }
159 _mm_free( p );
160 }
30122bae 161#else
162 static inline T *Alloc( int s ) { T *p; posix_memalign( &p, alignment, s * sizeof( T ) ); return new( p ) T[s]; }
e18739d0 163 static inline void Free( T *const p, int size ) {
164 for ( int i = 0; i < size; ++i ) {
165 p[i].~T();
166 }
167 std::free( p );
168 }
169#endif
170 };
171 template<typename T> class Allocator<T, AliHLTFullyCacheLineAligned>
172 {
173 public:
174 typedef CacheLineSizeHelper<T> T2;
175#ifdef USE_MM_MALLOC
176 static inline T2 *Alloc( int s ) { T2 *p = reinterpret_cast<T2 *>( _mm_malloc( s * sizeof( T2 ), 128 ) ); return new( p ) T2[s]; }
177 static inline void Free( T2 *const p, int size ) {
178 for ( int i = 0; i < size; ++i ) {
9e2dadc1 179 p[i].~T2();
e18739d0 180 }
181 _mm_free( p );
182 }
183#else
184 static inline T2 *Alloc( int s ) { T2 *p; posix_memalign( &p, 128, s * sizeof( T2 ) ); return new( p ) T2[s]; }
185 static inline void Free( T2 *const p, int size ) {
186 for ( int i = 0; i < size; ++i ) {
9e2dadc1 187 p[i].~T2();
e18739d0 188 }
189 std::free( p );
190 }
30122bae 191#endif
192 };
193 template<typename T> class Allocator<T, 0>
194 {
e18739d0 195 public:
30122bae 196 static inline T *Alloc( int s ) { return new T[s]; }
e18739d0 197 static inline void Free( const T *const p, int ) { delete[] p; }
30122bae 198 };
e18739d0 199
200 template<typename T> struct ReturnTypeHelper { typedef T Type; };
201 template<typename T> struct ReturnTypeHelper<CacheLineSizeHelper<T> > { typedef T Type; };
30122bae 202 /**
203 * Array base class for dimension dependent behavior
204 */
205 template<typename T, int Dim> class ArrayBase;
206
207 /**
208 * 1-dim arrays only have operator[]
209 */
210 template<typename T>
211 class ArrayBase<T, 1> : public ArrayBoundsCheck
212 {
213 friend class ArrayBase<T, 2>;
214 public:
e18739d0 215 ArrayBase() : fData( 0 ), fSize( 0 ) {} // XXX really shouldn't be done. But -Weffc++ wants it so
216 ArrayBase( const ArrayBase &rhs ) : ArrayBoundsCheck( rhs ), fData( rhs.fData ), fSize( rhs.fSize ) {} // XXX
217 ArrayBase &operator=( const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; return *this; } // XXX
218 typedef typename ReturnTypeHelper<T>::Type R;
30122bae 219 /**
220 * return a reference to the value at the given index
221 */
e18739d0 222 inline R &operator[]( int x ) { BOUNDS_CHECK( x, fData[0] ); return fData[x]; }
30122bae 223 /**
224 * return a const reference to the value at the given index
225 */
e18739d0 226 inline const R &operator[]( int x ) const { BOUNDS_CHECK( x, fData[0] ); return fData[x]; }
30122bae 227
228 protected:
229 T *fData;
e18739d0 230 int fSize;
231 inline void SetSize( int x, int, int ) { fSize = x; }
30122bae 232 };
233
234 /**
235 * 2-dim arrays should use operator(int, int)
236 * operator[] can be used to return a 1-dim array
237 */
238 template<typename T>
239 class ArrayBase<T, 2> : public ArrayBoundsCheck
240 {
241 friend class ArrayBase<T, 3>;
242 public:
e18739d0 243 ArrayBase() : fData( 0 ), fSize( 0 ), fStride( 0 ) {} // XXX really shouldn't be done. But -Weffc++ wants it so
244 ArrayBase( const ArrayBase &rhs ) : ArrayBoundsCheck( rhs ), fData( rhs.fData ), fSize( rhs.fSize ), fStride( rhs.fStride ) {} // XXX
245 ArrayBase &operator=( const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStride = rhs.fStride; return *this; } // XXX
246 typedef typename ReturnTypeHelper<T>::Type R;
30122bae 247 /**
248 * return a reference to the value at the given indexes
249 */
e18739d0 250 inline R &operator()( int x, int y ) { BOUNDS_CHECK( x * fStride + y, fData[0] ); return fData[x * fStride + y]; }
30122bae 251 /**
252 * return a const reference to the value at the given indexes
253 */
e18739d0 254 inline const R &operator()( int x, int y ) const { BOUNDS_CHECK( x * fStride + y, fData[0] ); return fData[x * fStride + y]; }
30122bae 255 /**
256 * return a 1-dim array at the given index. This makes it behave like a 2-dim C-Array.
257 */
258 inline AliHLTArray<T, 1> operator[]( int x );
259 /**
260 * return a const 1-dim array at the given index. This makes it behave like a 2-dim C-Array.
261 */
262 inline const AliHLTArray<T, 1> operator[]( int x ) const;
263
264 protected:
265 T *fData;
e18739d0 266 int fSize;
30122bae 267 int fStride;
e18739d0 268 inline void SetSize( int x, int y, int ) { fStride = y; fSize = x * y; }
30122bae 269 };
270
271 /**
272 * 3-dim arrays should use operator(int, int, int)
273 * operator[] can be used to return a 2-dim array
274 */
275 template<typename T>
276 class ArrayBase<T, 3> : public ArrayBoundsCheck
277 {
278 public:
e18739d0 279 ArrayBase() : fData( 0 ), fSize( 0 ), fStrideX( 0 ), fStrideY( 0 ) {} // XXX really shouldn't be done. But -Weffc++ wants it so
280 ArrayBase( const ArrayBase &rhs ) : ArrayBoundsCheck( rhs ), fData( rhs.fData ), fSize( rhs.fSize ), fStrideX( rhs.fStrideX ), fStrideY( rhs.fStrideY ) {} // XXX
281 ArrayBase &operator=( const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStrideX = rhs.fStrideX; fStrideY = rhs.fStrideY; return *this; } // XXX
282 typedef typename ReturnTypeHelper<T>::Type R;
30122bae 283 /**
284 * return a reference to the value at the given indexes
285 */
e18739d0 286 inline R &operator()( int x, int y, int z );
30122bae 287 /**
288 * return a const reference to the value at the given indexes
289 */
e18739d0 290 inline const R &operator()( int x, int y, int z ) const;
30122bae 291 /**
292 * return a 2-dim array at the given index. This makes it behave like a 3-dim C-Array.
293 */
294 inline AliHLTArray<T, 2> operator[]( int x );
295 /**
296 * return a const 2-dim array at the given index. This makes it behave like a 3-dim C-Array.
297 */
298 inline const AliHLTArray<T, 2> operator[]( int x ) const;
299
300 protected:
301 T *fData;
e18739d0 302 int fSize;
30122bae 303 int fStrideX;
304 int fStrideY;
e18739d0 305 inline void SetSize( int x, int y, int z ) { fStrideX = y * z; fStrideY = z; fSize = fStrideX * x; }
30122bae 306 };
307
e18739d0 308 template<typename T, unsigned int Size, int _alignment> class AlignedData
30122bae 309 {
e18739d0 310 public:
311 T *ConstructAlignedData() {
312 const int offset = reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
313 void *mem = &fUnalignedArray[0] + ( Alignment - offset );
314 return new( mem ) T[Size];
315 }
316 ~AlignedData() {
317 const int offset = reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
318 T *mem = reinterpret_cast<T *>( &fUnalignedArray[0] + ( Alignment - offset ) );
319 for ( unsigned int i = 0; i < Size; ++i ) {
320 mem[i].~T();
321 }
322 }
323 private:
324 enum {
325 Alignment = _alignment == AliHLTFullyCacheLineAligned ? 128 : _alignment,
326 PaddedSize = Size * sizeof( T ) + Alignment
327 };
328 ALIHLTARRAY_STATIC_ASSERT_NC( ( Alignment & ( Alignment - 1 ) ) == 0, alignment_needs_to_be_a_multiple_of_2 );
329
330 char fUnalignedArray[PaddedSize];
30122bae 331 };
e18739d0 332 template<typename T, unsigned int Size> class AlignedData<T, Size, 0>
30122bae 333 {
e18739d0 334 public:
335 T *ConstructAlignedData() { return &fArray[0]; }
336 private:
337 T fArray[Size];
30122bae 338 };
30122bae 339} // namespace AliHLTInternal
340
341/**
342 * C-Array like class with the dimension dependent behavior defined in the ArrayBase class
343 */
344template < typename T, int Dim = 1 >
345class AliHLTArray : public AliHLTInternal::ArrayBase<T, Dim>
346{
347 public:
348 typedef AliHLTInternal::ArrayBase<T, Dim> Parent;
e18739d0 349
350 /**
351 * Returns the number of elements in the array. If it is a multi-dimensional array the size is
352 * the multiplication of the dimensions ( e.g. a 10 x 20 array returns 200 as its size ).
353 */
354 inline int Size() const { return Parent::fSize; }
355
30122bae 356 /**
357 * allows you to check for validity of the array by casting to bool
358 */
359 inline operator bool() const { return Parent::fData != 0; }
360 /**
361 * allows you to check for validity of the array
362 */
363 inline bool IsValid() const { return Parent::fData != 0; }
364
365 /**
366 * returns a reference to the data at index 0
367 */
368 inline T &operator*() { BOUNDS_CHECK( 0, Parent::fData[0] ); return *Parent::fData; }
369 /**
370 * returns a const reference to the data at index 0
371 */
372 inline const T &operator*() const { BOUNDS_CHECK( 0, Parent::fData[0] ); return *Parent::fData; }
373
374 /**
375 * returns a pointer to the data
376 * This circumvents bounds checking so it should not be used.
377 */
378 inline T *Data() { return Parent::fData; }
379 /**
380 * returns a const pointer to the data
381 * This circumvents bounds checking so it should not be used.
382 */
383 inline const T *Data() const { return Parent::fData; }
384
385 /**
386 * moves the array base pointer so that the data that was once at index 0 will then be at index -x
387 */
388 inline AliHLTArray operator+( int x ) const;
389 /**
390 * moves the array base pointer so that the data that was once at index 0 will then be at index x
391 */
392 inline AliHLTArray operator-( int x ) const;
e18739d0 393
9e2dadc1 394#ifndef HLTCA_GPUCODE
e18739d0 395 template<typename Other> inline AliHLTArray<Other, Dim> ReinterpretCast() const {
396 AliHLTArray<Other, Dim> r;
397 r.fData = reinterpret_cast<Other *>( Parent::fData );
398 r.ReinterpretCast( *this, sizeof( T ), sizeof( Other ) );
399 }
9e2dadc1 400#endif
30122bae 401};
402
403/**
404 * Owns the data. When it goes out of scope the data is freed.
405 *
406 * The memory is allocated on the heap.
407 *
408 * Instantiate this class on the stack. Allocation on the heap is disallowed.
409 *
410 * \param T type of the entries in the array.
411 * \param Dim selects the operator[]/operator() behavior it should have. I.e. makes it behave like a
412 * 1-, 2- or 3-dim array. (defaults to 1)
413 * \param alignment Defaults to 0 (default alignment). Other valid values are any multiples of 2.
414 * This is especially useful for aligning data for SIMD vectors.
415 *
416 * \warning when using alignment the type T may not have a destructor (well it may, but it won't be
417 * called)
418 *
419 * Example:
420 * \code
421 * void init( AliHLTArray<int> a, int size )
422 * {
423 * for ( int i = 0; i < size; ++i ) {
424 * a[i] = i;
425 * }
426 * }
427 *
428 * int size = ...;
429 * AliHLTResizableArray<int> foo( size ); // notice that size doesn't have to be a constant like it
430 * // has to be for C-Arrays in ISO C++
431 * init( foo, size );
432 * // now foo[i] == i
433 *
434 * \endcode
435 */
436template < typename T, int Dim = 1, int alignment = 0 >
e18739d0 437class AliHLTResizableArray : public AliHLTArray<typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type, Dim>
30122bae 438{
439 public:
e18739d0 440 typedef typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type T2;
441 typedef AliHLTInternal::ArrayBase<T2, Dim> Parent;
30122bae 442 /**
443 * does not allocate any memory
444 */
445 inline AliHLTResizableArray();
446 /**
447 * use for 1-dim arrays: allocates x * sizeof(T) bytes for the array
448 */
449 inline AliHLTResizableArray( int x );
450 /**
451 * use for 2-dim arrays: allocates x * y * sizeof(T) bytes for the array
452 */
453 inline AliHLTResizableArray( int x, int y );
454 /**
455 * use for 3-dim arrays: allocates x * y * z * sizeof(T) bytes for the array
456 */
457 inline AliHLTResizableArray( int x, int y, int z );
458
459 /**
460 * frees the data
461 */
e18739d0 462 inline ~AliHLTResizableArray() { AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize ); }
30122bae 463
464 /**
465 * use for 1-dim arrays: resizes the memory for the array to x * sizeof(T) bytes.
466 *
467 * \warning this does not keep your previous data. If you were looking for this you probably
468 * want to use std::vector instead.
469 */
470 inline void Resize( int x );
471 /**
472 * use for 2-dim arrays: resizes the memory for the array to x * y * sizeof(T) bytes.
473 *
474 * \warning this does not keep your previous data. If you were looking for this you probably
475 * want to use std::vector instead.
476 */
477 inline void Resize( int x, int y );
478 /**
479 * use for 3-dim arrays: resizes the memory for the array to x * y * z * sizeof(T) bytes.
480 *
481 * \warning this does not keep your previous data. If you were looking for this you probably
482 * want to use std::vector instead.
483 */
484 inline void Resize( int x, int y, int z );
485
486 private:
487 // disable allocation on the heap
488 void *operator new( size_t );
489
490 // disable copy
491 AliHLTResizableArray( const AliHLTResizableArray & );
492 AliHLTResizableArray &operator=( const AliHLTResizableArray & );
493};
494
e18739d0 495template < unsigned int x, unsigned int y = 0, unsigned int z = 0 > class AliHLTArraySize
496{
497 public:
498 enum {
499 Size = y == 0 ? x : ( z == 0 ? x * y : x * y * z ),
500 Dim = y == 0 ? 1 : ( z == 0 ? 2 : 3 ),
501 X = x, Y = y, Z = z
502 };
503};
504
30122bae 505/**
506 * Owns the data. When it goes out of scope the data is freed.
507 *
508 * The memory is allocated on the stack.
509 *
510 * Instantiate this class on the stack.
511 *
512 * \param T type of the entries in the array.
513 * \param Size number of entries in the array.
514 * \param Dim selects the operator[]/operator() behavior it should have. I.e. makes it behave like a
515 * 1-, 2- or 3-dim array. (defaults to 1)
516 */
e18739d0 517template < typename T, typename Size, int alignment = 0 >
518class AliHLTFixedArray : public AliHLTArray<typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type, Size::Dim>
30122bae 519{
520 public:
e18739d0 521 typedef typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type T2;
522 typedef AliHLTInternal::ArrayBase<T2, Size::Dim> Parent;
523 inline AliHLTFixedArray() {
524 Parent::fData = fFixedArray.ConstructAlignedData();
525 Parent::SetBounds( 0, Size::Size - 1 );
526 SetSize( Size::X, Size::Y, Size::Z );
527 }
30122bae 528
529 private:
e18739d0 530 AliHLTInternal::AlignedData<typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type, Size::Size, alignment> fFixedArray;
531
30122bae 532 // disable allocation on the heap
533 void *operator new( size_t );
534
30122bae 535 // disable copy
9e2dadc1 536#ifdef HLTCA_GPUCODE
537#else
30122bae 538 AliHLTFixedArray( const AliHLTFixedArray & );
539 AliHLTFixedArray &operator=( const AliHLTFixedArray & );
9e2dadc1 540#endif
30122bae 541};
542
543
544
545
30122bae 546////////////////////////
547//// implementation ////
548////////////////////////
549
550
551
552
553namespace AliHLTInternal
554{
555#ifdef ENABLE_ARRAY_BOUNDS_CHECKING
556 inline bool ArrayBoundsCheck::IsInBounds( int x ) const
557 {
558 assert( x >= fStart );
559 assert( x <= fEnd );
560 return ( x >= fStart && x <= fEnd );
561 }
562#endif
563
564 template<typename T>
565 inline AliHLTArray<T, 1> ArrayBase<T, 2>::operator[]( int x )
566 {
567 x *= fStride;
568 typedef AliHLTArray<T, 1> AT1;
569 BOUNDS_CHECK( x, AT1() );
570 AliHLTArray<T, 1> a;
571 a.fData = &fData[x];
572 a.ArrayBoundsCheck::operator=( *this );
573 a.MoveBounds( -x );
574 return a;
575 }
576
577 template<typename T>
578 inline const AliHLTArray<T, 1> ArrayBase<T, 2>::operator[]( int x ) const
579 {
580 x *= fStride;
581 typedef AliHLTArray<T, 1> AT1;
582 BOUNDS_CHECK( x, AT1() );
583 AliHLTArray<T, 1> a;
584 a.fData = &fData[x];
585 a.ArrayBoundsCheck::operator=( *this );
586 a.MoveBounds( -x );
587 return a;
588 }
589
590 template<typename T>
e18739d0 591 inline typename AliHLTInternal::ReturnTypeHelper<T>::Type &ArrayBase<T, 3>::operator()( int x, int y, int z )
30122bae 592 {
593 BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
594 return fData[x * fStrideX + y + fStrideY + z];
595 }
596 template<typename T>
e18739d0 597 inline const typename AliHLTInternal::ReturnTypeHelper<T>::Type &ArrayBase<T, 3>::operator()( int x, int y, int z ) const
30122bae 598 {
599 BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
600 return fData[x * fStrideX + y + fStrideY + z];
601 }
602 template<typename T>
603 inline AliHLTArray<T, 2> ArrayBase<T, 3>::operator[]( int x )
604 {
605 x *= fStrideX;
606 typedef AliHLTArray<T, 2> AT2;
607 BOUNDS_CHECK( x, AT2() );
608 AliHLTArray<T, 2> a;
609 a.fData = &fData[x];
610 a.fStride = fStrideY;
611 a.ArrayBoundsCheck::operator=( *this );
612 a.MoveBounds( -x );
613 return a;
614 }
615 template<typename T>
616 inline const AliHLTArray<T, 2> ArrayBase<T, 3>::operator[]( int x ) const
617 {
618 x *= fStrideX;
619 typedef AliHLTArray<T, 2> AT2;
620 BOUNDS_CHECK( x, AT2() );
621 AliHLTArray<T, 2> a;
622 a.fData = &fData[x];
623 a.fStride = fStrideY;
624 a.ArrayBoundsCheck::operator=( *this );
625 a.MoveBounds( -x );
626 return a;
627 }
628} // namespace AliHLTInternal
629
630
631template<typename T, int Dim>
632inline AliHLTArray<T, Dim> AliHLTArray<T, Dim>::operator+( int x ) const
633{
634 AliHLTArray<T, Dim> r( *this );
635 r.fData += x;
636 r.MoveBounds( -x );
637 return r;
638}
639template<typename T, int Dim>
640inline AliHLTArray<T, Dim> AliHLTArray<T, Dim>::operator-( int x ) const
641{
642 AliHLTArray<T, Dim> r( *this );
643 r.fData -= x;
644 r.MoveBounds( x );
645 return r;
646}
647
648template<typename T, int Dim, int alignment>
649inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray()
650{
651 Parent::fData = 0;
e18739d0 652 Parent::SetSize( 0, 0, 0 );
30122bae 653 Parent::SetBounds( 0, -1 );
654}
655template<typename T, int Dim, int alignment>
656inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x )
657{
658 ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_used_with_incorrect_dimension );
659 Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x );
e18739d0 660 Parent::SetSize( x, 0, 0 );
30122bae 661 Parent::SetBounds( 0, x - 1 );
662}
663template<typename T, int Dim, int alignment>
664inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x, int y )
665{
666 ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_used_with_incorrect_dimension );
667 Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x * y );
668 Parent::SetSize( x, y, 0 );
669 Parent::SetBounds( 0, x * y - 1 );
670}
671template<typename T, int Dim, int alignment>
672inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x, int y, int z )
673{
674 ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_used_with_incorrect_dimension );
675 Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x * y * z );
676 Parent::SetSize( x, y, z );
677 Parent::SetBounds( 0, x * y * z - 1 );
678}
679template<typename T, int Dim, int alignment>
680inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x )
681{
682 ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_resize_used_with_incorrect_dimension );
e18739d0 683 AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize );
30122bae 684 Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x );
e18739d0 685 Parent::SetSize( x, 0, 0 );
30122bae 686 Parent::SetBounds( 0, x - 1 );
687}
688template<typename T, int Dim, int alignment>
689inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x, int y )
690{
691 ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_resize_used_with_incorrect_dimension );
e18739d0 692 AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize );
30122bae 693 Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x * y );
694 Parent::SetSize( x, y, 0 );
695 Parent::SetBounds( 0, x * y - 1 );
696}
697template<typename T, int Dim, int alignment>
698inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x, int y, int z )
699{
700 ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_resize_used_with_incorrect_dimension );
e18739d0 701 AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize );
30122bae 702 Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x * y * z );
703 Parent::SetSize( x, y, z );
704 Parent::SetBounds( 0, x * y * z - 1 );
705}
706
707#undef BOUNDS_CHECK
708
709#endif // ALIHLTARRAY_H