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> 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) \ 72 PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg); \ 75 template <
typename T,
int Dim>
79 template <
unsigned int Size>
94 MaskedSize =
sizeof(T) & (CacheLineSize - 1),
95 RequiredSize = MaskedSize == 0 ?
sizeof(T) :
sizeof(T) + CacheLineSize - MaskedSize,
96 PaddingSize = RequiredSize -
sizeof(T)
108 template <
typename T,
int alignment>
112 template <
typename T>
122 #ifndef ENABLE_ARRAY_BOUNDS_CHECKING 134 #define BOUNDS_CHECK(x, y) 139 class ArrayBoundsCheck {
141 virtual inline ~ArrayBoundsCheck() {}
145 inline bool IsInBounds(
int x)
const;
149 inline void SetBounds(
int start,
int end)
157 inline void MoveBounds(
int d)
163 inline void ReinterpretCast(
const ArrayBoundsCheck &other,
int sizeofOld,
int sizeofNew)
165 fStart = other.fStart * sizeofNew / sizeofOld;
166 fEnd = other.fEnd * sizeofNew / sizeofOld;
173 #define BOUNDS_CHECK(x, y) \ 174 if (PndFTSInternal::ArrayBoundsCheck::IsInBounds(x)) { \ 178 template <
typename T,
int alignment>
182 static inline T *Alloc(
int s)
184 T *p =
reinterpret_cast<T *
>(_mm_malloc(s *
sizeof(T), alignment));
187 static inline void Free(T *
const p,
int size)
189 for (
int i = 0;
i < size; ++
i) {
198 posix_memalign(&p, alignment, s *
sizeof(T));
201 static inline void Free(T *
const p,
int size)
203 for (
int i = 0;
i < size; ++
i) {
210 template <
typename T>
215 static inline T2 *Alloc(
int s)
217 T2 *p =
reinterpret_cast<T2 *
>(_mm_malloc(s *
sizeof(T2), 128));
218 return new (p) T2[s];
220 static inline void Free(T2 *
const p,
int size)
222 for (
int i = 0;
i < size; ++
i) {
231 posix_memalign(&p, 128, s *
sizeof(T2));
232 return new (p) T2[s];
234 static inline void Free(T2 *
const p,
int size)
236 for (
int i = 0;
i < size; ++
i) {
243 template <
typename T>
247 static inline T *Alloc(
int s)
249 T *p =
reinterpret_cast<T *
>(_mm_malloc(s *
sizeof(T), 128));
252 static inline void Free(T *
const p,
int size)
254 for (
int i = 0;
i < size; ++
i) {
263 posix_memalign(&p, 128, s *
sizeof(T));
266 static inline void Free(T *
const p,
int size)
268 for (
int i = 0;
i < size; ++
i) {
280 template <
typename T>
284 template <
typename T>
291 template <
typename T,
int Dim>
297 template <
typename T>
306 ArrayBoundsCheck::operator=(rhs);
332 inline void SetSize(
int x,
int,
int) { fSize = x; }
339 template <
typename T>
348 ArrayBoundsCheck::operator=(rhs);
351 fStride = rhs.fStride;
361 return fData[x * fStride + y];
369 return fData[x * fStride + y];
395 template <
typename T>
398 ArrayBase() : fData(0), fSize(0), fStrideX(0), fStrideY(0) {}
402 ArrayBoundsCheck::operator=(rhs);
405 fStrideX = rhs.fStrideX;
406 fStrideY = rhs.fStrideY;
413 inline R &operator()(
int x,
int y,
int z);
417 inline const R &operator()(
int x,
int y,
int z)
const;
436 fSize = fStrideX * x;
440 template <
typename T,
unsigned int Size,
int _alignment>
445 const int offset =
reinterpret_cast<unsigned long>(&fUnalignedArray[0]) & (Alignment - 1);
446 void *mem = &fUnalignedArray[0] + (Alignment - offset);
447 return new (mem) T[Size];
451 const int offset =
reinterpret_cast<unsigned long>(&fUnalignedArray[0]) & (Alignment - 1);
452 T *mem =
reinterpret_cast<T *
>(&fUnalignedArray[0] + (Alignment - offset));
453 for (
unsigned int i = 0;
i < Size; ++
i) {
462 char fUnalignedArray[PaddedSize];
464 template <
typename T,
unsigned int Size>
477 template <
typename T,
int Dim = 1>
486 inline int Size()
const {
return Parent::fSize; }
491 inline operator bool()
const {
return Parent::fData != 0; }
495 inline bool IsValid()
const {
return Parent::fData != 0; }
503 return *Parent::fData;
511 return *Parent::fData;
518 inline T *
Data() {
return Parent::fData; }
523 inline const T *
Data()
const {
return Parent::fData; }
534 template <
typename Other>
538 r.fData =
reinterpret_cast<Other *
>(Parent::fData);
576 template <
typename T,
int Dim = 1,
int alignment = 0>
609 inline void Resize(
int x);
616 inline void Resize(
int x,
int y);
623 inline void Resize(
int x,
int y,
int z);
627 void *
operator new(size_t);
631 PndFTSResizableArray &operator=(
const PndFTSResizableArray &);
634 template <
unsigned int x,
unsigned int y = 0,
unsigned int z = 0>
637 enum { Size = y == 0 ? x : (z == 0 ? x * y : x * y * z), Dim = y == 0 ? 1 : (z == 0 ? 2 : 3), X = x, Y = y, Z = z };
652 template <
typename T,
typename Size,
int alignment = 0>
659 fData = fFixedArray.ConstructAlignedData();
660 Parent::SetBounds(0, Size::Size - 1);
661 SetSize(Size::X, Size::Y, Size::Z);
665 fData = fFixedArray.ConstructAlignedData();
666 Parent::SetBounds(0, Size::Size - 1);
667 SetSize(Size::X, Size::Y, Size::Z);
668 std::memcpy(fData, rhs.fData, Size::Size *
sizeof(T));
675 void *
operator new(size_t);
688 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING 689 inline bool ArrayBoundsCheck::IsInBounds(
int x)
const 693 return (x >= fStart && x <= fEnd);
697 template <
typename T>
705 a.ArrayBoundsCheck::operator=(*this);
710 template <
typename T>
718 a.ArrayBoundsCheck::operator=(*this);
723 template <
typename T>
726 BOUNDS_CHECK(x * fStrideX + y + fStrideY + z, fData[0]);
727 return fData[x * fStrideX + y + fStrideY + z];
729 template <
typename T>
732 BOUNDS_CHECK(x * fStrideX + y + fStrideY + z, fData[0]);
733 return fData[x * fStrideX + y + fStrideY + z];
735 template <
typename T>
743 a.fStride = fStrideY;
744 a.ArrayBoundsCheck::operator=(*this);
748 template <
typename T>
756 a.fStride = fStrideY;
757 a.ArrayBoundsCheck::operator=(*this);
763 template <
typename T,
int Dim>
771 template <
typename T,
int Dim>
780 template <
typename T,
int Dim,
int alignment>
784 Parent::SetSize(0, 0, 0);
785 Parent::SetBounds(0, -1);
787 template <
typename T,
int Dim,
int alignment>
792 Parent::SetSize(x, 0, 0);
793 Parent::SetBounds(0, x - 1);
795 template <
typename T,
int Dim,
int alignment>
800 Parent::SetSize(x, y, 0);
801 Parent::SetBounds(0, x * y - 1);
803 template <
typename T,
int Dim,
int alignment>
808 Parent::SetSize(x, y, z);
809 Parent::SetBounds(0, x * y * z - 1);
812 template <
typename T,
int Dim,
int alignment>
818 Parent::SetSize(x, 0, 0);
819 Parent::SetBounds(0, x - 1);
821 template <
typename T,
int Dim,
int alignment>
827 Parent::SetSize(x, y, 0);
828 Parent::SetBounds(0, x * y - 1);
830 template <
typename T,
int Dim,
int alignment>
836 Parent::SetSize(x, y, z);
837 Parent::SetBounds(0, x * y * z - 1);
842 #endif // PNDFTSARRAY_H R & operator()(int x, int y)
#define PNDFTSARRAY_STATIC_ASSERT(cond, msg)
ReturnTypeHelper< T >::Type R
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2
ArrayBase(const ArrayBase &rhs)
CacheLineSizeHelper< T > T2
bool IsInBounds(int) const
static void Free(T *const p, int size)
PndFTSArray operator+(int x) const
RhoLorentzVectorErr operator+(const RhoLorentzVectorErr &, const RhoLorentzVectorErr &)
PndFTSInternal::ArrayBase< T2, Dim > Parent
virtual ~ArrayBoundsCheck()
ArrayBase(const ArrayBase &rhs)
CacheLineSizeHelper< T > Type
static void Free(T *const p, int size)
PndFTSArray< Other, Dim > ReinterpretCast() const
PndFTSInternal::ArrayBase< T2, Size::Dim > Parent
T * ConstructAlignedData()
ArrayBase(const ArrayBase &rhs)
void ReinterpretCast(const ArrayBoundsCheck &, int, int)
#define BOUNDS_CHECK(x, y)
ArrayBase & operator=(const ArrayBase &rhs)
ArrayBase & operator=(const ArrayBase &rhs)
ReturnTypeHelper< T >::Type R
float & operator[](int i)
const T & operator*() const
const R & operator[](int x) const
PndFTSFixedArray(const PndFTSFixedArray &rhs)
void SetSize(int x, int y, int z)
ReturnTypeHelper< T >::Type R
PndFTSArray operator-(int x) const
#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)
RhoLorentzVectorErr operator-(const RhoLorentzVectorErr &, const RhoLorentzVectorErr &)
PndFTSInternal::ArrayBase< T, Dim > Parent
const R & operator()(int x, int y) const
T * ConstructAlignedData()
void SetSize(int x, int y, int)
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2