LCOV - code coverage report
Current view: top level - HLT/BASE - AliHLTArray.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 30 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 78 0.0 %

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

Generated by: LCOV version 1.11