34 #if (defined(__MMX__) || defined(__SSE__)) 
   40 #endif // if __GNUC__ > 3 
   42 #else // if defined(__GNUC__)  // not gcc, assume it can use _mm_malloc since it supports MMX/SSE 
   46 #endif // if defined(__GNUC__) 
   47 #endif // if (defined(__MMX__) || defined(__SSE__)) 
   50 #include <mm_malloc.h> 
   60 namespace PndFTSArrayInternal
 
   66 #define PNDFTSARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b 
   67 #define PNDFTSARRAY_STATIC_ASSERT_CONCAT(a, b) PNDFTSARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) 
   68 #define PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg) \ 
   69   typedef PndFTSArrayInternal::STATIC_ASSERT_FAILURE<cond> PNDFTSARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \ 
   70   PNDFTSARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg 
   71 #define PNDFTSARRAY_STATIC_ASSERT(cond, msg) PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg); (void) Error_##msg 
   75 namespace PndFTSInternal
 
  105 #ifndef ENABLE_ARRAY_BOUNDS_CHECKING 
  118 #define BOUNDS_CHECK(x, y) 
  123   class ArrayBoundsCheck
 
  126       virtual inline ~ArrayBoundsCheck() {}
 
  130       inline bool IsInBounds( 
int x ) 
const;
 
  134       inline void SetBounds( 
int start, 
int end ) { fStart = start; fEnd = end; }
 
  138       inline void MoveBounds( 
int d ) { fStart += 
d; fEnd += 
d; }
 
  140       inline void ReinterpretCast( 
const ArrayBoundsCheck &other, 
int sizeofOld, 
int sizeofNew ) {
 
  141         fStart = other.fStart * sizeofNew / sizeofOld;
 
  142         fEnd = other.fEnd * sizeofNew / sizeofOld;
 
  149 #define BOUNDS_CHECK(x, y) if (PndFTSInternal::ArrayBoundsCheck::IsInBounds(x)) {} else return y 
  155       static inline T *Alloc( 
int s ) { 
T *
p = 
reinterpret_cast<T *
>( _mm_malloc( s * 
sizeof( 
T ), alignment ) ); 
return new( 
p ) 
T[s]; }
 
  156       static inline void Free( 
T *
const p, 
int size ) {
 
  157         for ( 
int i = 0; 
i < size; ++
i ) {
 
  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 ) {
 
  177       static inline T2 *Alloc( 
int s ) { 
T2 *
p = 
reinterpret_cast<T2 *
>( _mm_malloc( s * 
sizeof( 
T2 ), 128 ) ); 
return new( 
p ) 
T2[s]; }
 
  178       static inline void Free( T2 *
const p, 
int size ) {
 
  179         for ( 
int i = 0; 
i < size; ++
i ) {
 
  185       static inline T2 *
Alloc( 
int s ) { 
T2 *
p; posix_memalign( &p, 128, s * 
sizeof( 
T2 ) ); 
return new( 
p ) 
T2[s]; }
 
  186       static inline void Free( 
T2 *
const p, 
int size ) {
 
  187         for ( 
int i = 0; 
i < size; ++
i ) {
 
  198       static inline T *Alloc( 
int s ) { 
T *p = 
reinterpret_cast<T *
>( _mm_malloc( s * 
sizeof( 
T ), 128 ) ); 
return new( 
p ) 
T[s]; }
 
  199       static inline void Free( 
T *
const p, 
int size ) {
 
  200         for ( 
int i = 0; 
i < size; ++
i ) {
 
  206       static inline T *
Alloc( 
int s ) { 
T *
p; posix_memalign( &p, 128, s * 
sizeof( 
T ) ); 
return new( 
p ) 
T[s]; }
 
  207       static inline void Free( 
T *
const p, 
int size ) {
 
  208         for ( 
int i = 0; 
i < size; ++
i ) {
 
  265       ArrayBase &
operator=( 
const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStride = rhs.fStride; 
return *
this; } 
 
  288       inline void SetSize( 
int x, 
int y, 
int ) { fStride = 
y; fSize = x * 
y; }
 
  299       ArrayBase() : fData( 0 ), fSize( 0 ), fStrideX( 0 ), fStrideY( 0 ) {} 
 
  301       ArrayBase &
operator=( 
const ArrayBase &rhs ) { ArrayBoundsCheck::operator=( rhs ); fData = rhs.fData; fSize = rhs.fSize; fStrideX = rhs.fStrideX; fStrideY = rhs.fStrideY; 
return *
this; } 
 
  306       inline R &operator()( 
int x, 
int y, 
int z );
 
  310       inline const R &operator()( 
int x, 
int y, 
int z ) 
const;
 
  325       inline void SetSize( 
int x, 
int y, 
int z ) { fStrideX = y * 
z; fStrideY = 
z; fSize = fStrideX * 
x; }
 
  328   template<
typename T, 
unsigned int Size, 
int _alignment> 
class AlignedData 
  332         const int offset = 
reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
 
  333         void *mem = &fUnalignedArray[0] + ( Alignment - 
offset );
 
  334         return new( mem ) 
T[Size];
 
  337         const int offset = 
reinterpret_cast<unsigned long>( &fUnalignedArray[0] ) & ( Alignment - 1 );
 
  338         T *mem = 
reinterpret_cast<T *
>( &fUnalignedArray[0] + ( Alignment - 
offset ) );
 
  339         for ( 
unsigned int i = 0; 
i < Size; ++
i ) {
 
  346         PaddedSize = Size * 
sizeof( 
T ) + Alignment
 
  350       char fUnalignedArray[PaddedSize];
 
  364 template < 
typename T, 
int Dim = 1 >
 
  374     inline int Size()
 const { 
return Parent::fSize; }
 
  379     inline operator bool()
 const { 
return Parent::fData != 0; }
 
  383     inline bool IsValid()
 const { 
return Parent::fData != 0; }
 
  398     inline T *
Data() { 
return Parent::fData; }
 
  403     inline const T *
Data()
 const { 
return Parent::fData; }
 
  416       r.fData = 
reinterpret_cast<Other *
>( Parent::fData );
 
  454 template < 
typename T, 
int Dim = 1, 
int alignment = 0 >
 
  488     inline void Resize( 
int x );
 
  495     inline void Resize( 
int x, 
int y );
 
  502     inline void Resize( 
int x, 
int y, 
int z );
 
  506     void *
operator new( size_t );
 
  513 template<
unsigned int x, 
unsigned int y = 0, 
unsigned int z = 0> 
class PndFTSArraySize 
  517       Size = 
y == 0 ? 
x : ( 
z == 0 ? 
x * 
y : 
x * 
y * 
z ),
 
  518       Dim = 
y == 0 ? 1 : ( 
z == 0 ? 2 : 3 ),
 
  535 template<
typename T, 
typename Size, 
int alignment = 0>
 
  542       fData = fFixedArray.ConstructAlignedData();
 
  543       Parent::SetBounds( 0, Size::Size - 1 );
 
  547       fData = fFixedArray.ConstructAlignedData();
 
  548       Parent::SetBounds( 0, Size::Size - 1 );
 
  550       std::memcpy( fData, rhs.fData, Size::Size * 
sizeof( 
T ) );
 
  557     void *
operator new( size_t );
 
  575 namespace PndFTSInternal
 
  577 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING 
  580     assert( x >= fStart );
 
  582     return ( x >= fStart && x <= fEnd );
 
  594     a.ArrayBoundsCheck::operator=( *this );
 
  607     a.ArrayBoundsCheck::operator=( *this );
 
  615     BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
 
  616     return fData[x * fStrideX + y + fStrideY + 
z];
 
  621     BOUNDS_CHECK( x * fStrideX + y + fStrideY + z, fData[0] );
 
  622     return fData[x * fStrideX + y + fStrideY + 
z];
 
  632     a.fStride = fStrideY;
 
  633     a.ArrayBoundsCheck::operator=( *this );
 
  645     a.fStride = fStrideY;
 
  646     a.ArrayBoundsCheck::operator=( *this );
 
  653 template<
typename T, 
int Dim>
 
  661 template<
typename T, 
int Dim>
 
  670 template<
typename T, 
int Dim, 
int alignment>
 
  674   Parent::SetSize( 0, 0, 0 );
 
  675   Parent::SetBounds( 0, -1 );
 
  677 template<
typename T, 
int Dim, 
int alignment>
 
  682   Parent::SetSize( x, 0, 0 );
 
  683   Parent::SetBounds( 0, x - 1 );
 
  685 template<
typename T, 
int Dim, 
int alignment>
 
  690   Parent::SetSize( x, y, 0 );
 
  691   Parent::SetBounds( 0, x * y - 1 );
 
  693 template<
typename T, 
int Dim, 
int alignment>
 
  698   Parent::SetSize( x, y, z );
 
  699   Parent::SetBounds( 0, x * y * z - 1 );
 
  702 template<
typename T, 
int Dim, 
int alignment>
 
  708   Parent::SetSize( x, 0, 0 );
 
  709   Parent::SetBounds( 0, x - 1 );
 
  711 template<
typename T, 
int Dim, 
int alignment>
 
  717   Parent::SetSize( x, y, 0 );
 
  718   Parent::SetBounds( 0, x * y - 1 );
 
  720 template<
typename T, 
int Dim, 
int alignment>
 
  726   Parent::SetSize( x, y, z );
 
  727   Parent::SetBounds( 0, x * y * z - 1 );
 
  732 #endif // PNDFTSARRAY_H 
R & operator()(int x, int y)
#define PNDFTSARRAY_STATIC_ASSERT(cond, msg)
RhoError operator-(const RhoError &m1, const RhoError &m2)
const T & operator*() const 
ReturnTypeHelper< T >::Type R
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2
bool IsInBounds(int) const 
ArrayBase(const ArrayBase &rhs)
CacheLineSizeHelper< T > T2
static void Free(T *const p, int size)
const R & operator()(int x, int y) const 
PndFTSInternal::ArrayBase< T2, Dim > Parent
virtual ~ArrayBoundsCheck()
ArrayBase(const ArrayBase &rhs)
CacheLineSizeHelper< T > Type
PndFTSArray< Other, Dim > ReinterpretCast() const 
static void Free(T *const p, int size)
PndFTSInternal::ArrayBase< T2, Size::Dim > Parent
const R & operator[](int x) const 
RhoError operator+(const RhoError &m1, const RhoError &m2)
T * ConstructAlignedData()
PndFTSArray operator-(int x) const 
ArrayBase(const ArrayBase &rhs)
void ReinterpretCast(const ArrayBoundsCheck &, int, int)
#define BOUNDS_CHECK(x, y)
ArrayBase & operator=(const ArrayBase &rhs)
PndFTSArray operator+(int x) const 
ArrayBase & operator=(const ArrayBase &rhs)
ReturnTypeHelper< T >::Type R
float & operator[](int i)
PndFTSFixedArray(const PndFTSFixedArray &rhs)
void SetSize(int x, int y, int z)
ReturnTypeHelper< T >::Type R
#define PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg)
static void Free(T2 *const p, int size)
void SetSize(int x, int, int)
ArrayBase & operator=(const ArrayBase &rhs)
PndFTSInternal::ArrayBase< T, Dim > Parent
PndFTSInternal::AlignedData< typename PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type, Size::Size, alignment > fFixedArray
T * ConstructAlignedData()
void SetSize(int x, int y, int)
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2