1 // ****************************************************************************
2 // * This file is property of and copyright by the ALICE HLT Project *
3 // * ALICE Experiment at CERN, All rights reserved. *
5 // * Copyright (C) 2009 Matthias Kretz <kretz@kde.org> *
6 // * for The ALICE HLT Project. *
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 // ****************************************************************************
19 * \author Matthias Kretz <kretz@kde.org>
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.
34 #if (defined(__MMX__) || defined(__SSE__))
39 #else // not gcc, assume it can use _mm_malloc since it supports MMX/SSE
45 #include <mm_malloc.h>
51 AliHLTFullyCacheLineAligned = -1
54 namespace AliHLTArrayInternal
56 template<bool> class STATIC_ASSERT_FAILURE;
57 template<> class STATIC_ASSERT_FAILURE<true> {};
60 #define ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b
61 #define ALIHLTARRAY_STATIC_ASSERT_CONCAT(a, b) ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b)
62 #define ALIHLTARRAY_STATIC_ASSERT_NC(cond, msg) \
63 typedef AliHLTArrayInternal::STATIC_ASSERT_FAILURE<cond> ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \
64 ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg
65 #define ALIHLTARRAY_STATIC_ASSERT(cond, msg) ALIHLTARRAY_STATIC_ASSERT_NC(cond, msg); (void) Error_##msg
67 template<typename T, int Dim> class AliHLTArray;
69 namespace AliHLTInternal
71 template<unsigned int Size> struct Padding { char fPadding[Size]; };
72 template<> struct Padding<0> {};
73 template<typename T> struct CacheLineSizeHelperData { T fData; };
74 template<typename T> struct CacheLineSizeHelperEnums {
77 MaskedSize = sizeof( T ) & ( CacheLineSize - 1 ),
78 RequiredSize = MaskedSize == 0 ? sizeof( T ) : sizeof( T ) + CacheLineSize - MaskedSize,
79 PaddingSize = RequiredSize - sizeof( T )
82 template<typename T> class CacheLineSizeHelper : private CacheLineSizeHelperData<T>, private Padding<CacheLineSizeHelperEnums<T>::PaddingSize>
85 operator T &() { return CacheLineSizeHelperData<T>::fData; }
86 operator const T &() const { return CacheLineSizeHelperData<T>::fData; }
87 //const T &operator=( const T &rhs ) { CacheLineSizeHelperData<T>::fData = rhs; }
91 template<typename T, int alignment> struct TypeForAlignmentHelper { typedef T Type; };
92 template<typename T> struct TypeForAlignmentHelper<T, AliHLTFullyCacheLineAligned> { typedef CacheLineSizeHelper<T> Type; };
95 // The ArrayBoundsCheck and Allocator classes implement a virtual destructor only in order to
96 // silence the -Weffc++ warning. It really is not required for these classes to have a virtual
97 // dtor since polymorphism is not used (AliHLTResizableArray and AliHLTFixedArray are allocated on
98 // the stack only). The virtual dtor only adds an unnecessary vtable to the code.
99 #ifndef ENABLE_ARRAY_BOUNDS_CHECKING
101 * no-op implementation that for no-bounds-checking
103 class ArrayBoundsCheck
106 virtual inline ~ArrayBoundsCheck() {}
107 inline bool IsInBounds( int ) const { return true; }
108 inline void SetBounds( int, int ) {}
109 inline void MoveBounds( int ) {}
110 inline void ReinterpretCast( const ArrayBoundsCheck &, int, int ) {}
112 #define BOUNDS_CHECK(x, y)
115 * implementation for bounds-checking.
117 class ArrayBoundsCheck
120 virtual inline ~ArrayBoundsCheck() {}
122 * checks whether the given offset is valid
124 inline bool IsInBounds( int x ) const;
126 * set the start and end offsets that are still valid
128 inline void SetBounds( int start, int end ) { fStart = start; fEnd = end; }
130 * move the start and end offsets by the same amount
132 inline void MoveBounds( int d ) { fStart += d; fEnd += d; }
134 inline void ReinterpretCast( const ArrayBoundsCheck &other, int sizeofOld, int sizeofNew ) {
135 fStart = other.fStart * sizeofNew / sizeofOld;
136 fEnd = other.fEnd * sizeofNew / sizeofOld;
143 #define BOUNDS_CHECK(x, y) if (AliHLTInternal::ArrayBoundsCheck::IsInBounds(x)) {} else return y
145 template<typename T, int alignment> class Allocator
149 static inline T *Alloc( int s ) { T *p = reinterpret_cast<T *>( _mm_malloc( s * sizeof( T ), alignment ) ); return new( p ) T[s]; }
150 static inline void Free( T *const p, int size ) {
151 for ( int i = 0; i < size; ++i ) {
157 static inline T *Alloc( int s ) { T *p; posix_memalign( &p, alignment, s * sizeof( T ) ); return new( p ) T[s]; }
158 static inline void Free( T *const p, int size ) {
159 for ( int i = 0; i < size; ++i ) {
166 template<typename T> class Allocator<T, AliHLTFullyCacheLineAligned>
169 typedef CacheLineSizeHelper<T> T2;
171 static inline T2 *Alloc( int s ) { T2 *p = reinterpret_cast<T2 *>( _mm_malloc( s * sizeof( T2 ), 128 ) ); return new( p ) T2[s]; }
172 static inline void Free( T2 *const p, int size ) {
173 for ( int i = 0; i < size; ++i ) {
179 static inline T2 *Alloc( int s ) { T2 *p; posix_memalign( &p, 128, s * sizeof( T2 ) ); return new( p ) T2[s]; }
180 static inline void Free( T2 *const p, int size ) {
181 for ( int i = 0; i < size; ++i ) {
188 template<typename T> class Allocator<T, 0>
191 static inline T *Alloc( int s ) { return new T[s]; }
192 static inline void Free( const T *const p, int ) { delete[] p; }
195 template<typename T> struct ReturnTypeHelper { typedef T Type; };
196 template<typename T> struct ReturnTypeHelper<CacheLineSizeHelper<T> > { typedef T Type; };
198 * Array base class for dimension dependent behavior
200 template<typename T, int Dim> class ArrayBase;
203 * 1-dim arrays only have operator[]
206 class ArrayBase<T, 1> : public ArrayBoundsCheck
208 friend class ArrayBase<T, 2>;
210 ArrayBase() : fData( 0 ), fSize( 0 ) {} // XXX really shouldn't be done. But -Weffc++ wants it so
211 ArrayBase( const ArrayBase &rhs ) : ArrayBoundsCheck( rhs ), fData( rhs.fData ), fSize( rhs.fSize ) {} // XXX
212 ArrayBase &operator=( const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; return *this; } // XXX
213 typedef typename ReturnTypeHelper<T>::Type R;
215 * return a reference to the value at the given index
217 inline R &operator[]( int x ) { BOUNDS_CHECK( x, fData[0] ); return fData[x]; }
219 * return a const reference to the value at the given index
221 inline const R &operator[]( int x ) const { BOUNDS_CHECK( x, fData[0] ); return fData[x]; }
226 inline void SetSize( int x, int, int ) { fSize = x; }
230 * 2-dim arrays should use operator(int, int)
231 * operator[] can be used to return a 1-dim array
234 class ArrayBase<T, 2> : public ArrayBoundsCheck
236 friend class ArrayBase<T, 3>;
238 ArrayBase() : fData( 0 ), fSize( 0 ), fStride( 0 ) {} // XXX really shouldn't be done. But -Weffc++ wants it so
239 ArrayBase( const ArrayBase &rhs ) : ArrayBoundsCheck( rhs ), fData( rhs.fData ), fSize( rhs.fSize ), fStride( rhs.fStride ) {} // XXX
240 ArrayBase &operator=( const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStride = rhs.fStride; return *this; } // XXX
241 typedef typename ReturnTypeHelper<T>::Type R;
243 * return a reference to the value at the given indexes
245 inline R &operator()( int x, int y ) { BOUNDS_CHECK( x * fStride + y, fData[0] ); return fData[x * fStride + y]; }
247 * return a const reference to the value at the given indexes
249 inline const R &operator()( int x, int y ) const { BOUNDS_CHECK( x * fStride + y, fData[0] ); return fData[x * fStride + y]; }
251 * return a 1-dim array at the given index. This makes it behave like a 2-dim C-Array.
253 inline AliHLTArray<T, 1> operator[]( int x );
255 * return a const 1-dim array at the given index. This makes it behave like a 2-dim C-Array.
257 inline const AliHLTArray<T, 1> operator[]( int x ) const;
263 inline void SetSize( int x, int y, int ) { fStride = y; fSize = x * y; }
267 * 3-dim arrays should use operator(int, int, int)
268 * operator[] can be used to return a 2-dim array
271 class ArrayBase<T, 3> : public ArrayBoundsCheck
274 ArrayBase() : fData( 0 ), fSize( 0 ), fStrideX( 0 ), fStrideY( 0 ) {} // XXX really shouldn't be done. But -Weffc++ wants it so
275 ArrayBase( const ArrayBase &rhs ) : ArrayBoundsCheck( rhs ), fData( rhs.fData ), fSize( rhs.fSize ), fStrideX( rhs.fStrideX ), fStrideY( rhs.fStrideY ) {} // XXX
276 ArrayBase &operator=( const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStrideX = rhs.fStrideX; fStrideY = rhs.fStrideY; return *this; } // XXX
277 typedef typename ReturnTypeHelper<T>::Type R;
279 * return a reference to the value at the given indexes
281 inline R &operator()( int x, int y, int z );
283 * return a const reference to the value at the given indexes
285 inline const R &operator()( int x, int y, int z ) const;
287 * return a 2-dim array at the given index. This makes it behave like a 3-dim C-Array.
289 inline AliHLTArray<T, 2> operator[]( int x );
291 * return a const 2-dim array at the given index. This makes it behave like a 3-dim C-Array.
293 inline const AliHLTArray<T, 2> operator[]( int x ) const;
300 inline void SetSize( int x, int y, int z ) { fStrideX = y * z; fStrideY = z; fSize = fStrideX * x; }
303 template<typename T, unsigned int Size, int _alignment> class AlignedData
306 T *ConstructAlignedData() {
307 const int offset = reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
308 void *mem = &fUnalignedArray[0] + ( Alignment - offset );
309 return new( mem ) T[Size];
312 const int offset = reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
313 T *mem = reinterpret_cast<T *>( &fUnalignedArray[0] + ( Alignment - offset ) );
314 for ( unsigned int i = 0; i < Size; ++i ) {
320 Alignment = _alignment == AliHLTFullyCacheLineAligned ? 128 : _alignment,
321 PaddedSize = Size * sizeof( T ) + Alignment
323 ALIHLTARRAY_STATIC_ASSERT_NC( ( Alignment & ( Alignment - 1 ) ) == 0, alignment_needs_to_be_a_multiple_of_2 );
325 char fUnalignedArray[PaddedSize];
327 template<typename T, unsigned int Size> class AlignedData<T, Size, 0>
330 T *ConstructAlignedData() { return &fArray[0]; }
334 } // namespace AliHLTInternal
337 * C-Array like class with the dimension dependent behavior defined in the ArrayBase class
339 template < typename T, int Dim = 1 >
340 class AliHLTArray : public AliHLTInternal::ArrayBase<T, Dim>
343 typedef AliHLTInternal::ArrayBase<T, Dim> Parent;
346 * Returns the number of elements in the array. If it is a multi-dimensional array the size is
347 * the multiplication of the dimensions ( e.g. a 10 x 20 array returns 200 as its size ).
349 inline int Size() const { return Parent::fSize; }
352 * allows you to check for validity of the array by casting to bool
354 inline operator bool() const { return Parent::fData != 0; }
356 * allows you to check for validity of the array
358 inline bool IsValid() const { return Parent::fData != 0; }
361 * returns a reference to the data at index 0
363 inline T &operator*() { BOUNDS_CHECK( 0, Parent::fData[0] ); return *Parent::fData; }
365 * returns a const reference to the data at index 0
367 inline const T &operator*() const { BOUNDS_CHECK( 0, Parent::fData[0] ); return *Parent::fData; }
370 * returns a pointer to the data
371 * This circumvents bounds checking so it should not be used.
373 inline T *Data() { return Parent::fData; }
375 * returns a const pointer to the data
376 * This circumvents bounds checking so it should not be used.
378 inline const T *Data() const { return Parent::fData; }
381 * moves the array base pointer so that the data that was once at index 0 will then be at index -x
383 inline AliHLTArray operator+( int x ) const;
385 * moves the array base pointer so that the data that was once at index 0 will then be at index x
387 inline AliHLTArray operator-( int x ) const;
389 template<typename Other> inline AliHLTArray<Other, Dim> ReinterpretCast() const {
390 AliHLTArray<Other, Dim> r;
391 r.fData = reinterpret_cast<Other *>( Parent::fData );
392 r.ReinterpretCast( *this, sizeof( T ), sizeof( Other ) );
397 * Owns the data. When it goes out of scope the data is freed.
399 * The memory is allocated on the heap.
401 * Instantiate this class on the stack. Allocation on the heap is disallowed.
403 * \param T type of the 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 * \param alignment Defaults to 0 (default alignment). Other valid values are any multiples of 2.
407 * This is especially useful for aligning data for SIMD vectors.
409 * \warning when using alignment the type T may not have a destructor (well it may, but it won't be
414 * void init( AliHLTArray<int> a, int size )
416 * for ( int i = 0; i < size; ++i ) {
422 * AliHLTResizableArray<int> foo( size ); // notice that size doesn't have to be a constant like it
423 * // has to be for C-Arrays in ISO C++
429 template < typename T, int Dim = 1, int alignment = 0 >
430 class AliHLTResizableArray : public AliHLTArray<typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type, Dim>
433 typedef typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type T2;
434 typedef AliHLTInternal::ArrayBase<T2, Dim> Parent;
436 * does not allocate any memory
438 inline AliHLTResizableArray();
440 * use for 1-dim arrays: allocates x * sizeof(T) bytes for the array
442 inline AliHLTResizableArray( int x );
444 * use for 2-dim arrays: allocates x * y * sizeof(T) bytes for the array
446 inline AliHLTResizableArray( int x, int y );
448 * use for 3-dim arrays: allocates x * y * z * sizeof(T) bytes for the array
450 inline AliHLTResizableArray( int x, int y, int z );
455 inline ~AliHLTResizableArray() { AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize ); }
458 * use for 1-dim arrays: resizes the memory for the array to x * sizeof(T) bytes.
460 * \warning this does not keep your previous data. If you were looking for this you probably
461 * want to use std::vector instead.
463 inline void Resize( int x );
465 * use for 2-dim arrays: resizes the memory for the array to x * y * sizeof(T) bytes.
467 * \warning this does not keep your previous data. If you were looking for this you probably
468 * want to use std::vector instead.
470 inline void Resize( int x, int y );
472 * use for 3-dim arrays: resizes the memory for the array to x * y * z * sizeof(T) bytes.
474 * \warning this does not keep your previous data. If you were looking for this you probably
475 * want to use std::vector instead.
477 inline void Resize( int x, int y, int z );
480 // disable allocation on the heap
481 void *operator new( size_t );
484 AliHLTResizableArray( const AliHLTResizableArray & );
485 AliHLTResizableArray &operator=( const AliHLTResizableArray & );
488 template < unsigned int x, unsigned int y = 0, unsigned int z = 0 > class AliHLTArraySize
492 Size = y == 0 ? x : ( z == 0 ? x * y : x * y * z ),
493 Dim = y == 0 ? 1 : ( z == 0 ? 2 : 3 ),
499 * Owns the data. When it goes out of scope the data is freed.
501 * The memory is allocated on the stack.
503 * Instantiate this class on the stack.
505 * \param T type of the entries in the array.
506 * \param Size number of entries in the array.
507 * \param Dim selects the operator[]/operator() behavior it should have. I.e. makes it behave like a
508 * 1-, 2- or 3-dim array. (defaults to 1)
510 template < typename T, typename Size, int alignment = 0 >
511 class AliHLTFixedArray : public AliHLTArray<typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type, Size::Dim>
514 typedef typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type T2;
515 typedef AliHLTInternal::ArrayBase<T2, Size::Dim> Parent;
516 inline AliHLTFixedArray() {
517 Parent::fData = fFixedArray.ConstructAlignedData();
518 Parent::SetBounds( 0, Size::Size - 1 );
519 SetSize( Size::X, Size::Y, Size::Z );
523 AliHLTInternal::AlignedData<typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type, Size::Size, alignment> fFixedArray;
525 // disable allocation on the heap
526 void *operator new( size_t );
529 AliHLTFixedArray( const AliHLTFixedArray & );
530 AliHLTFixedArray &operator=( const AliHLTFixedArray & );
536 ////////////////////////
537 //// implementation ////
538 ////////////////////////
543 namespace AliHLTInternal
545 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
546 inline bool ArrayBoundsCheck::IsInBounds( int x ) const
548 assert( x >= fStart );
550 return ( x >= fStart && x <= fEnd );
555 inline AliHLTArray<T, 1> ArrayBase<T, 2>::operator[]( int x )
558 typedef AliHLTArray<T, 1> AT1;
559 BOUNDS_CHECK( x, AT1() );
562 a.ArrayBoundsCheck::operator=( *this );
568 inline const AliHLTArray<T, 1> ArrayBase<T, 2>::operator[]( int x ) const
571 typedef AliHLTArray<T, 1> AT1;
572 BOUNDS_CHECK( x, AT1() );
575 a.ArrayBoundsCheck::operator=( *this );
581 inline typename AliHLTInternal::ReturnTypeHelper<T>::Type &ArrayBase<T, 3>::operator()( int x, int y, int z )
583 BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
584 return fData[x * fStrideX + y + fStrideY + z];
587 inline const typename AliHLTInternal::ReturnTypeHelper<T>::Type &ArrayBase<T, 3>::operator()( int x, int y, int z ) const
589 BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
590 return fData[x * fStrideX + y + fStrideY + z];
593 inline AliHLTArray<T, 2> ArrayBase<T, 3>::operator[]( int x )
596 typedef AliHLTArray<T, 2> AT2;
597 BOUNDS_CHECK( x, AT2() );
600 a.fStride = fStrideY;
601 a.ArrayBoundsCheck::operator=( *this );
606 inline const AliHLTArray<T, 2> ArrayBase<T, 3>::operator[]( int x ) const
609 typedef AliHLTArray<T, 2> AT2;
610 BOUNDS_CHECK( x, AT2() );
613 a.fStride = fStrideY;
614 a.ArrayBoundsCheck::operator=( *this );
618 } // namespace AliHLTInternal
621 template<typename T, int Dim>
622 inline AliHLTArray<T, Dim> AliHLTArray<T, Dim>::operator+( int x ) const
624 AliHLTArray<T, Dim> r( *this );
629 template<typename T, int Dim>
630 inline AliHLTArray<T, Dim> AliHLTArray<T, Dim>::operator-( int x ) const
632 AliHLTArray<T, Dim> r( *this );
638 template<typename T, int Dim, int alignment>
639 inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray()
642 Parent::SetSize( 0, 0, 0 );
643 Parent::SetBounds( 0, -1 );
645 template<typename T, int Dim, int alignment>
646 inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x )
648 ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_used_with_incorrect_dimension );
649 Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x );
650 Parent::SetSize( x, 0, 0 );
651 Parent::SetBounds( 0, x - 1 );
653 template<typename T, int Dim, int alignment>
654 inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x, int y )
656 ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_used_with_incorrect_dimension );
657 Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x * y );
658 Parent::SetSize( x, y, 0 );
659 Parent::SetBounds( 0, x * y - 1 );
661 template<typename T, int Dim, int alignment>
662 inline AliHLTResizableArray<T, Dim, alignment>::AliHLTResizableArray( int x, int y, int z )
664 ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_used_with_incorrect_dimension );
665 Parent::fData = AliHLTInternal::Allocator<T, alignment>::Alloc( x * y * z );
666 Parent::SetSize( x, y, z );
667 Parent::SetBounds( 0, x * y * z - 1 );
669 template<typename T, int Dim, int alignment>
670 inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x )
672 ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_resize_used_with_incorrect_dimension );
673 AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize );
674 Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x );
675 Parent::SetSize( x, 0, 0 );
676 Parent::SetBounds( 0, x - 1 );
678 template<typename T, int Dim, int alignment>
679 inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x, int y )
681 ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_resize_used_with_incorrect_dimension );
682 AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize );
683 Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x * y );
684 Parent::SetSize( x, y, 0 );
685 Parent::SetBounds( 0, x * y - 1 );
687 template<typename T, int Dim, int alignment>
688 inline void AliHLTResizableArray<T, Dim, alignment>::Resize( int x, int y, int z )
690 ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_resize_used_with_incorrect_dimension );
691 AliHLTInternal::Allocator<T, alignment>::Free( Parent::fData, Parent::fSize );
692 Parent::fData = ( x == 0 ) ? 0 : AliHLTInternal::Allocator<T, alignment>::Alloc( x * y * z );
693 Parent::SetSize( x, y, z );
694 Parent::SetBounds( 0, x * y * z - 1 );
699 #endif // ALIHLTARRAY_H