35 #if 1//(defined(__MMX__) || defined(__SSE__))
41 #endif // if __GNUC__ > 3
43 #else // if defined(__GNUC__) // not gcc, assume it can use _mm_malloc since it supports MMX/SSE
47 #endif // if defined(__GNUC__)
48 #endif // if (defined(__MMX__) || defined(__SSE__))
52 #if defined(__INTEL_COMPILER)
55 #include <mm_malloc.h>
56 #endif // defined(__GNUC__)
64 AliHLTFullyCacheLineAligned = -1
67 namespace AliHLTArrayInternal
73 #define ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b
74 #define ALIHLTARRAY_STATIC_ASSERT_CONCAT(a, b) ALIHLTARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b)
75 #define ALIHLTARRAY_STATIC_ASSERT_NC(cond, msg) \
76 typedef AliHLTArrayInternal::STATIC_ASSERT_FAILURE<cond> ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \
77 ALIHLTARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg
78 #define ALIHLTARRAY_STATIC_ASSERT(cond, msg) ALIHLTARRAY_STATIC_ASSERT_NC(cond, msg); (void) Error_##msg
82 namespace AliHLTInternal
84 template<
unsigned int Size>
struct Padding {
char fPadding[Size]; };
90 MaskedSize =
sizeof( T ) & ( CacheLineSize - 1 ),
91 RequiredSize = MaskedSize == 0 ?
sizeof( T ) :
sizeof( T ) + CacheLineSize - MaskedSize,
92 PaddingSize = RequiredSize -
sizeof( T )
112 #ifndef ENABLE_ARRAY_BOUNDS_CHECKING
120 inline bool IsInBounds(
int )
const {
return true; }
121 inline void SetBounds(
int,
int ) {}
122 inline void MoveBounds(
int ) {}
125 #define BOUNDS_CHECK(x, y)
137 inline bool IsInBounds(
int x )
const;
141 inline void SetBounds(
int start,
int end ) { fStart = start; fEnd = end; }
145 inline void MoveBounds(
int d ) { fStart += d; fEnd += d; }
147 inline void ReinterpretCast(
const ArrayBoundsCheck &other,
int sizeofOld,
int sizeofNew ) {
148 fStart = other.fStart * sizeofNew / sizeofOld;
149 fEnd = other.fEnd * sizeofNew / sizeofOld;
156 #define BOUNDS_CHECK(x, y) if (AliHLTInternal::ArrayBoundsCheck::IsInBounds(x)) {} else return y
162 static inline T *Alloc(
int s ) { T *p =
reinterpret_cast<T *
>( _mm_malloc( s *
sizeof( T ), alignment ) );
return new( p ) T[s]; }
163 static inline void Free( T *
const p,
int size ) {
164 for (
int i = 0; i < size; ++i ) {
170 static inline T *Alloc(
int s ) { T *p; posix_memalign( &p, alignment, s *
sizeof( T ) );
return new( p ) T[s]; }
171 static inline void Free( T *
const p,
int size ) {
172 for (
int i = 0; i < size; ++i ) {
179 template<
typename T>
class Allocator<T, AliHLTFullyCacheLineAligned>
184 static inline T2 *Alloc(
int s ) {
T2 *p =
reinterpret_cast<T2 *
>( _mm_malloc( s *
sizeof(
T2 ), 128 ) );
return new( p )
T2[s]; }
185 static inline void Free(
T2 *
const p,
int size ) {
186 for (
int i = 0; i < size; ++i ) {
192 static inline T2 *Alloc(
int s ) {
T2 *p; posix_memalign( &p, 128, s *
sizeof(
T2 ) );
return new( p )
T2[s]; }
193 static inline void Free(
T2 *
const p,
int size ) {
194 for (
int i = 0; i < size; ++i ) {
205 static inline T *Alloc(
int s ) { T *p =
reinterpret_cast<T *
>( _mm_malloc( s *
sizeof( T ), 128 ) );
return new( p ) T[s]; }
206 static inline void Free( T *
const p,
int size ) {
207 for (
int i = 0; i < size; ++i ) {
213 static inline T *Alloc(
int s ) { T *p; posix_memalign( &p, 128, s *
sizeof( T ) );
return new( p ) T[s]; }
214 static inline void Free( T *
const p,
int size ) {
215 for (
int i = 0; i < size; ++i ) {
244 ArrayBase &operator=(
const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize;
return *
this; }
245 typedef typename ReturnTypeHelper<T>::Type R;
249 inline R &
operator[](
int x ) { BOUNDS_CHECK( x, fData[0] );
return fData[x]; }
253 inline const R &
operator[](
int x )
const { BOUNDS_CHECK( x, fData[0] );
return fData[x]; }
258 inline void SetSize(
int x,
int,
int ) { fSize = x; }
270 ArrayBase() : fData( 0 ), fSize( 0 ), fStride( 0 ) {}
272 ArrayBase &operator=(
const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStride = rhs.fStride;
return *
this; }
273 typedef typename ReturnTypeHelper<T>::Type R;
277 inline R &
operator()(
int x,
int y ) { BOUNDS_CHECK( x * fStride + y, fData[0] );
return fData[x * fStride + y]; }
281 inline const R &
operator()(
int x,
int y )
const { BOUNDS_CHECK( x * fStride + y, fData[0] );
return fData[x * fStride + y]; }
295 inline void SetSize(
int x,
int y,
int ) { fStride = y; fSize = x * y; }
306 ArrayBase() : fData( 0 ), fSize( 0 ), fStrideX( 0 ), fStrideY( 0 ) {}
308 ArrayBase &operator=(
const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStrideX = rhs.fStrideX; fStrideY = rhs.fStrideY;
return *
this; }
309 typedef typename ReturnTypeHelper<T>::Type R;
313 inline R &operator()(
int x,
int y,
int z );
317 inline const R &operator()(
int x,
int y,
int z )
const;
332 inline void SetSize(
int x,
int y,
int z ) { fStrideX = y * z; fStrideY = z; fSize = fStrideX * x; }
335 template<
typename T,
unsigned int Size,
int _alignment>
class AlignedData
338 T *ConstructAlignedData() {
339 const int offset =
reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
340 void *mem = &fUnalignedArray[0] + ( Alignment - offset );
341 return new( mem ) T[Size];
344 const int offset =
reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
345 T *mem =
reinterpret_cast<T *
>( &fUnalignedArray[0] + ( Alignment - offset ) );
346 for (
unsigned int i = 0; i < Size; ++i ) {
352 Alignment = _alignment == AliHLTFullyCacheLineAligned ? 128 : _alignment,
353 PaddedSize = Size *
sizeof( T ) + Alignment
355 ALIHLTARRAY_STATIC_ASSERT_NC( ( Alignment & ( Alignment - 1 ) ) == 0, alignment_needs_to_be_a_multiple_of_2 );
357 char fUnalignedArray[PaddedSize];
359 template<
typename T,
unsigned int Size>
class AlignedData<T, Size, 0>
362 T *ConstructAlignedData() {
return &fArray[0]; }
371 template <
typename T,
int Dim = 1 >
381 inline int Size()
const {
return Parent::fSize; }
386 inline operator bool()
const {
return Parent::fData != 0; }
390 inline bool IsValid()
const {
return Parent::fData != 0; }
395 inline T &
operator*() { BOUNDS_CHECK( 0, Parent::fData[0] );
return *Parent::fData; }
399 inline const T &
operator*()
const { BOUNDS_CHECK( 0, Parent::fData[0] );
return *Parent::fData; }
405 inline T *
Data() {
return Parent::fData; }
410 inline const T *
Data()
const {
return Parent::fData; }
423 r.fData =
reinterpret_cast<Other *
>( Parent::fData );
424 r.ReinterpretCast( *
this,
sizeof( T ),
sizeof( Other ) );
461 template <
typename T,
int Dim = 1,
int alignment = 0 >
465 typedef typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type T2;
495 inline void Resize(
int x );
502 inline void Resize(
int x,
int y );
509 inline void Resize(
int x,
int y,
int z );
513 void *
operator new( size_t );
520 template<
unsigned int x,
unsigned int y = 0,
unsigned int z = 0>
class AliHLTArraySize
524 Size = y == 0 ? x : ( z == 0 ? x * y : x * y * z ),
525 Dim = y == 0 ? 1 : ( z == 0 ? 2 : 3 ),
542 template<
typename T,
typename Size,
int alignment = 0>
546 typedef typename AliHLTInternal::TypeForAlignmentHelper<T, alignment>::Type T2;
549 fData = fFixedArray.ConstructAlignedData();
550 Parent::SetBounds( 0, Size::Size - 1 );
554 fData = fFixedArray.ConstructAlignedData();
555 Parent::SetBounds( 0, Size::Size - 1 );
556 SetSize( Size::X, Size::Y, Size::Z );
557 std::memcpy( fData, rhs.fData, Size::Size *
sizeof( T ) );
564 void *
operator new( size_t );
582 namespace AliHLTInternal
584 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
585 inline bool ArrayBoundsCheck::IsInBounds(
int x )
const
587 assert( x >= fStart );
589 return ( x >= fStart && x <= fEnd );
597 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
599 BOUNDS_CHECK( x, AT1() );
603 a.ArrayBoundsCheck::operator=( *this );
612 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
614 BOUNDS_CHECK( x, AT1() );
618 a.ArrayBoundsCheck::operator=( *this );
626 BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
627 return fData[x * fStrideX + y + fStrideY + z];
632 BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
633 return fData[x * fStrideX + y + fStrideY + z];
639 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
641 BOUNDS_CHECK( x, AT2() );
645 a.fStride = fStrideY;
646 a.ArrayBoundsCheck::operator=( *this );
654 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
656 BOUNDS_CHECK( x, AT2() );
660 a.fStride = fStrideY;
661 a.ArrayBoundsCheck::operator=( *this );
668 template<
typename T,
int Dim>
676 template<
typename T,
int Dim>
685 template<
typename T,
int Dim,
int alignment>
689 Parent::SetSize( 0, 0, 0 );
690 Parent::SetBounds( 0, -1 );
692 template<
typename T,
int Dim,
int alignment>
695 ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_used_with_incorrect_dimension );
697 Parent::SetSize( x, 0, 0 );
698 Parent::SetBounds( 0, x - 1 );
700 template<
typename T,
int Dim,
int alignment>
703 ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_used_with_incorrect_dimension );
705 Parent::SetSize( x, y, 0 );
706 Parent::SetBounds( 0, x * y - 1 );
708 template<
typename T,
int Dim,
int alignment>
711 ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_used_with_incorrect_dimension );
713 Parent::SetSize( x, y, z );
714 Parent::SetBounds( 0, x * y * z - 1 );
717 template<
typename T,
int Dim,
int alignment>
720 ALIHLTARRAY_STATIC_ASSERT( Dim == 1, AliHLTResizableArray1_resize_used_with_incorrect_dimension );
723 Parent::SetSize( x, 0, 0 );
724 Parent::SetBounds( 0, x - 1 );
726 template<
typename T,
int Dim,
int alignment>
729 ALIHLTARRAY_STATIC_ASSERT( Dim == 2, AliHLTResizableArray2_resize_used_with_incorrect_dimension );
732 Parent::SetSize( x, y, 0 );
733 Parent::SetBounds( 0, x * y - 1 );
735 template<
typename T,
int Dim,
int alignment>
738 ALIHLTARRAY_STATIC_ASSERT( Dim == 3, AliHLTResizableArray3_resize_used_with_incorrect_dimension );
741 Parent::SetSize( x, y, z );
742 Parent::SetBounds( 0, x * y * z - 1 );
747 #endif // ALIHLTARRAY_H
AliHLTArray operator+(int x) const
R & operator()(int x, int y)
const T & operator*() const
const R & operator[](int x) const
const R & operator()(int x, int y) const
AliHLTArray operator-(int x) const