PandaRoot
PndFTSArray.h
Go to the documentation of this file.
1 /****************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project *
3  * ALICE Experiment at CERN, All rights reserved. *
4  * *
5  * Copyright (C) 2009 Matthias Kretz <kretz@kde.org> *
6  * for The ALICE HLT Project. *
7  * *
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  ***************************************************************************/
16 
27 #ifndef PNDFTSARRAY_H
28 #define PNDFTSARRAY_H
29 
30 #ifndef assert
31 #include <assert.h>
32 #endif
33 
34 #if (defined(__MMX__) || defined(__SSE__))
35 
36 #if defined(__GNUC__)
37 
38 #if __GNUC__ > 3
39 #define USE_MM_MALLOC
40 #endif // if __GNUC__ > 3
41 
42 #else // if defined(__GNUC__) // not gcc, assume it can use _mm_malloc since it supports MMX/SSE
43 
44 #define USE_MM_MALLOC
45 
46 #endif // if defined(__GNUC__)
47 #endif // if (defined(__MMX__) || defined(__SSE__))
48 
49 #ifdef USE_MM_MALLOC
50 #include <mm_malloc.h>
51 #else
52 #include <cstdlib>
53 #endif
54 #include <cstring>
55 
57 
59 template <bool>
61 template <>
62 class STATIC_ASSERT_FAILURE<true> {
63 };
64 } // namespace PndFTSArrayInternal
65 
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); \
73  (void)Error_##msg
74 
75 template <typename T, int Dim>
77 
78 namespace PndFTSInternal {
79 template <unsigned int Size>
80 struct Padding {
81  char fPadding[Size];
82 };
83 template <>
84 struct Padding<0> {
85 };
86 template <typename T>
88  T fData;
89 };
90 template <typename T>
92  enum {
93  CacheLineSize = 64,
94  MaskedSize = sizeof(T) & (CacheLineSize - 1),
95  RequiredSize = MaskedSize == 0 ? sizeof(T) : sizeof(T) + CacheLineSize - MaskedSize,
96  PaddingSize = RequiredSize - sizeof(T)
97  };
98 };
99 template <typename T>
100 class CacheLineSizeHelper : private CacheLineSizeHelperData<T>, private Padding<CacheLineSizeHelperEnums<T>::PaddingSize> {
101  public:
102  operator T &() { return CacheLineSizeHelperData<T>::fData; }
103  operator const T &() const { return CacheLineSizeHelperData<T>::fData; }
104  // const T &operator=( const T &rhs ) { CacheLineSizeHelperData<T>::fData = rhs; }
105 
106  private:
107 };
108 template <typename T, int alignment>
110  typedef T Type;
111 };
112 template <typename T>
115 };
116 
117 // XXX
118 // The ArrayBoundsCheck and Allocator classes implement a virtual destructor only in order to
119 // silence the -Weffc++ warning. It really is not required for these classes to have a virtual
120 // dtor since polymorphism is not used (PndFTSResizableArray and PndFTSFixedArray are allocated on
121 // the stack only). The virtual dtor only adds an unnecessary vtable to the code.
122 #ifndef ENABLE_ARRAY_BOUNDS_CHECKING
123 
127  protected:
128  virtual inline ~ArrayBoundsCheck() {}
129  inline bool IsInBounds(int) const { return true; }
130  inline void SetBounds(int, int) {}
131  inline void MoveBounds(int) {}
132  inline void ReinterpretCast(const ArrayBoundsCheck &, int, int) {}
133 };
134 #define BOUNDS_CHECK(x, y)
135 #else
136 
139 class ArrayBoundsCheck {
140  protected:
141  virtual inline ~ArrayBoundsCheck() {}
145  inline bool IsInBounds(int x) const;
149  inline void SetBounds(int start, int end)
150  {
151  fStart = start;
152  fEnd = end;
153  }
157  inline void MoveBounds(int d)
158  {
159  fStart += d;
160  fEnd += d;
161  }
162 
163  inline void ReinterpretCast(const ArrayBoundsCheck &other, int sizeofOld, int sizeofNew)
164  {
165  fStart = other.fStart * sizeofNew / sizeofOld;
166  fEnd = other.fEnd * sizeofNew / sizeofOld;
167  }
168 
169  private:
170  int fStart;
171  int fEnd;
172 };
173 #define BOUNDS_CHECK(x, y) \
174  if (PndFTSInternal::ArrayBoundsCheck::IsInBounds(x)) { \
175  } else \
176  return y
177 #endif
178 template <typename T, int alignment>
179 class Allocator {
180  public:
181 #ifdef USE_MM_MALLOC
182  static inline T *Alloc(int s)
183  {
184  T *p = reinterpret_cast<T *>(_mm_malloc(s * sizeof(T), alignment));
185  return new (p) T[s];
186  }
187  static inline void Free(T *const p, int size)
188  {
189  for (int i = 0; i < size; ++i) {
190  p[i].~T();
191  }
192  _mm_free(p);
193  }
194 #else
195  static inline T *Alloc(int s)
196  {
197  T *p;
198  posix_memalign(&p, alignment, s * sizeof(T));
199  return new (p) T[s];
200  }
201  static inline void Free(T *const p, int size)
202  {
203  for (int i = 0; i < size; ++i) {
204  p[i].~T();
205  }
206  std::free(p);
207  }
208 #endif
209 };
210 template <typename T>
212  public:
214 #ifdef USE_MM_MALLOC
215  static inline T2 *Alloc(int s)
216  {
217  T2 *p = reinterpret_cast<T2 *>(_mm_malloc(s * sizeof(T2), 128));
218  return new (p) T2[s];
219  }
220  static inline void Free(T2 *const p, int size)
221  {
222  for (int i = 0; i < size; ++i) {
223  p[i].~T2();
224  }
225  _mm_free(p);
226  }
227 #else
228  static inline T2 *Alloc(int s)
229  {
230  T2 *p;
231  posix_memalign(&p, 128, s * sizeof(T2));
232  return new (p) T2[s];
233  }
234  static inline void Free(T2 *const p, int size)
235  {
236  for (int i = 0; i < size; ++i) {
237  p[i].~T2();
238  }
239  std::free(p);
240  }
241 #endif
242 };
243 template <typename T>
244 class Allocator<T, 0> {
245  public:
246 #ifdef USE_MM_MALLOC
247  static inline T *Alloc(int s)
248  {
249  T *p = reinterpret_cast<T *>(_mm_malloc(s * sizeof(T), 128));
250  return new (p) T[s];
251  }
252  static inline void Free(T *const p, int size)
253  {
254  for (int i = 0; i < size; ++i) {
255  p[i].~T();
256  }
257  _mm_free(p);
258  }
259 #else
260  static inline T *Alloc(int s)
261  {
262  T *p;
263  posix_memalign(&p, 128, s * sizeof(T));
264  return new (p) T[s];
265  }
266  static inline void Free(T *const p, int size)
267  {
268  for (int i = 0; i < size; ++i) {
269  p[i].~T();
270  }
271  std::free(p);
272  }
273 #endif
274 
275  // public:
276  // static inline T *Alloc( int s ) { return new T[s]; }
277  // static inline void Free( const T *const p, int ) { delete[] p; }
278 };
279 
280 template <typename T>
282  typedef T Type;
283 };
284 template <typename T>
286  typedef T Type;
287 };
291 template <typename T, int Dim>
292 class ArrayBase;
293 
297 template <typename T>
298 class ArrayBase<T, 1> : public ArrayBoundsCheck {
299  friend class ArrayBase<T, 2>;
300 
301  public:
302  ArrayBase() : fData(0) {} // XXX really shouldn't be done. But -Weffc++ wants it so
303  ArrayBase(const ArrayBase &rhs) : ArrayBoundsCheck(rhs), fData(rhs.fData), fSize(rhs.fSize) {} // XXX
305  {
306  ArrayBoundsCheck::operator=(rhs);
307  fData = rhs.fData;
308  fSize = rhs.fSize;
309  return *this;
310  } // XXX
311  typedef typename ReturnTypeHelper<T>::Type R;
315  inline R &operator[](int x)
316  {
317  BOUNDS_CHECK(x, fData[0]);
318  return fData[x];
319  }
323  inline const R &operator[](int x) const
324  {
325  BOUNDS_CHECK(x, fData[0]);
326  return fData[x];
327  }
328 
329  protected:
330  T *fData;
331  int fSize;
332  inline void SetSize(int x, int, int) { fSize = x; }
333 };
334 
339 template <typename T>
340 class ArrayBase<T, 2> : public ArrayBoundsCheck {
341  friend class ArrayBase<T, 3>;
342 
343  public:
344  ArrayBase() : fData(0), fSize(0), fStride(0) {} // XXX really shouldn't be done. But -Weffc++ wants it so
345  ArrayBase(const ArrayBase &rhs) : ArrayBoundsCheck(rhs), fData(rhs.fData), fSize(rhs.fSize), fStride(rhs.fStride) {} // XXX
347  {
348  ArrayBoundsCheck::operator=(rhs);
349  fData = rhs.fData;
350  fSize = rhs.fSize;
351  fStride = rhs.fStride;
352  return *this;
353  } // XXX
354  typedef typename ReturnTypeHelper<T>::Type R;
358  inline R &operator()(int x, int y)
359  {
360  BOUNDS_CHECK(x * fStride + y, fData[0]);
361  return fData[x * fStride + y];
362  }
366  inline const R &operator()(int x, int y) const
367  {
368  BOUNDS_CHECK(x * fStride + y, fData[0]);
369  return fData[x * fStride + y];
370  }
374  inline PndFTSArray<T, 1> operator[](int x);
378  inline const PndFTSArray<T, 1> operator[](int x) const;
379 
380  protected:
381  T *fData;
382  int fSize;
383  int fStride;
384  inline void SetSize(int x, int y, int)
385  {
386  fStride = y;
387  fSize = x * y;
388  }
389 };
390 
395 template <typename T>
396 class ArrayBase<T, 3> : public ArrayBoundsCheck {
397  public:
398  ArrayBase() : fData(0), fSize(0), fStrideX(0), fStrideY(0) {} // XXX really shouldn't be done. But -Weffc++ wants it so
399  ArrayBase(const ArrayBase &rhs) : ArrayBoundsCheck(rhs), fData(rhs.fData), fSize(rhs.fSize), fStrideX(rhs.fStrideX), fStrideY(rhs.fStrideY) {} // XXX
401  {
402  ArrayBoundsCheck::operator=(rhs);
403  fData = rhs.fData;
404  fSize = rhs.fSize;
405  fStrideX = rhs.fStrideX;
406  fStrideY = rhs.fStrideY;
407  return *this;
408  } // XXX
409  typedef typename ReturnTypeHelper<T>::Type R;
413  inline R &operator()(int x, int y, int z);
417  inline const R &operator()(int x, int y, int z) const;
421  inline PndFTSArray<T, 2> operator[](int x);
425  inline const PndFTSArray<T, 2> operator[](int x) const;
426 
427  protected:
428  T *fData;
429  int fSize;
430  int fStrideX;
431  int fStrideY;
432  inline void SetSize(int x, int y, int z)
433  {
434  fStrideX = y * z;
435  fStrideY = z;
436  fSize = fStrideX * x;
437  }
438 };
439 
440 template <typename T, unsigned int Size, int _alignment>
441 class AlignedData {
442  public:
444  {
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];
448  }
450  {
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) {
454  mem[i].~T();
455  }
456  }
457 
458  private:
459  enum { Alignment = _alignment == PndFTSFullyCacheLineAligned ? 128 : _alignment, PaddedSize = Size * sizeof(T) + Alignment };
460  PNDFTSARRAY_STATIC_ASSERT_NC((Alignment & (Alignment - 1)) == 0, alignment_needs_to_be_a_multiple_of_2);
461 
462  char fUnalignedArray[PaddedSize];
463 };
464 template <typename T, unsigned int Size>
465 class AlignedData<T, Size, 0> {
466  public:
467  T *ConstructAlignedData() { return &fArray[0]; }
468 
469  private:
470  T fArray[Size];
471 };
472 } // namespace PndFTSInternal
473 
477 template <typename T, int Dim = 1>
478 class PndFTSArray : public PndFTSInternal::ArrayBase<T, Dim> {
479  public:
481 
486  inline int Size() const { return Parent::fSize; }
487 
491  inline operator bool() const { return Parent::fData != 0; }
495  inline bool IsValid() const { return Parent::fData != 0; }
496 
500  inline T &operator*()
501  {
502  BOUNDS_CHECK(0, Parent::fData[0]);
503  return *Parent::fData;
504  }
508  inline const T &operator*() const
509  {
510  BOUNDS_CHECK(0, Parent::fData[0]);
511  return *Parent::fData;
512  }
513 
518  inline T *Data() { return Parent::fData; }
523  inline const T *Data() const { return Parent::fData; }
524 
528  inline PndFTSArray operator+(int x) const;
532  inline PndFTSArray operator-(int x) const;
533 
534  template <typename Other>
536  {
538  r.fData = reinterpret_cast<Other *>(Parent::fData);
539  r.ReinterpretCast(*this, sizeof(T), sizeof(Other));
540  }
541 };
542 
576 template <typename T, int Dim = 1, int alignment = 0>
577 class PndFTSResizableArray : public PndFTSArray<typename PndFTSInternal::TypeForAlignmentHelper<T, alignment>::Type, Dim> {
578  public:
584  inline PndFTSResizableArray();
588  inline PndFTSResizableArray(int x);
592  inline PndFTSResizableArray(int x, int y);
596  inline PndFTSResizableArray(int x, int y, int z);
597 
601  inline ~PndFTSResizableArray() { PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize); }
602 
609  inline void Resize(int x);
616  inline void Resize(int x, int y);
623  inline void Resize(int x, int y, int z);
624 
625  private:
626  // disable allocation on the heap
627  void *operator new(size_t);
628 
629  // disable copy
631  PndFTSResizableArray &operator=(const PndFTSResizableArray &);
632 };
633 
634 template <unsigned int x, unsigned int y = 0, unsigned int z = 0>
636  public:
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 };
638 };
639 
652 template <typename T, typename Size, int alignment = 0>
653 class PndFTSFixedArray : public PndFTSArray<typename PndFTSInternal::TypeForAlignmentHelper<T, alignment>::Type, Size::Dim> {
654  public:
658  {
659  fData = fFixedArray.ConstructAlignedData();
660  Parent::SetBounds(0, Size::Size - 1);
661  SetSize(Size::X, Size::Y, Size::Z);
662  }
664  {
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));
669  }
670 
671  private:
673 
674  // disable allocation on the heap
675  void *operator new(size_t);
676 
677  using Parent::fData;
678 
679  // disable copy
680  PndFTSFixedArray &operator=(const PndFTSFixedArray &);
681 };
682 
686 
687 namespace PndFTSInternal {
688 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
689 inline bool ArrayBoundsCheck::IsInBounds(int x) const
690 {
691  assert(x >= fStart);
692  assert(x <= fEnd);
693  return (x >= fStart && x <= fEnd);
694 }
695 #endif
696 
697 template <typename T>
699 {
700  x *= fStride;
701  // typedef PndFTSArray<T, 1> AT1;
702  // BOUNDS_CHECK( x, AT1() );
704  a.fData = &fData[x];
705  a.ArrayBoundsCheck::operator=(*this);
706  a.MoveBounds(-x);
707  return a;
708 }
709 
710 template <typename T>
712 {
713  x *= fStride;
714  // typedef PndFTSArray<T, 1> AT1;
715  // BOUNDS_CHECK( x, AT1() );
717  a.fData = &fData[x];
718  a.ArrayBoundsCheck::operator=(*this);
719  a.MoveBounds(-x);
720  return a;
721 }
722 
723 template <typename T>
725 {
726  BOUNDS_CHECK(x * fStrideX + y + fStrideY + z, fData[0]);
727  return fData[x * fStrideX + y + fStrideY + z];
728 }
729 template <typename T>
730 inline const typename PndFTSInternal::ArrayBase<T, 3>::R &ArrayBase<T, 3>::operator()(int x, int y, int z) const
731 {
732  BOUNDS_CHECK(x * fStrideX + y + fStrideY + z, fData[0]);
733  return fData[x * fStrideX + y + fStrideY + z];
734 }
735 template <typename T>
737 {
738  x *= fStrideX;
739  // typedef PndFTSArray<T, 2> AT2;
740  // BOUNDS_CHECK( x, AT2() );
742  a.fData = &fData[x];
743  a.fStride = fStrideY;
744  a.ArrayBoundsCheck::operator=(*this);
745  a.MoveBounds(-x);
746  return a;
747 }
748 template <typename T>
750 {
751  x *= fStrideX;
752  // typedef PndFTSArray<T, 2> AT2;
753  // BOUNDS_CHECK( x, AT2() );
755  a.fData = &fData[x];
756  a.fStride = fStrideY;
757  a.ArrayBoundsCheck::operator=(*this);
758  a.MoveBounds(-x);
759  return a;
760 }
761 } // namespace PndFTSInternal
762 
763 template <typename T, int Dim>
765 {
766  PndFTSArray<T, Dim> r(*this);
767  r.fData += x;
768  r.MoveBounds(-x);
769  return r;
770 }
771 template <typename T, int Dim>
773 {
774  PndFTSArray<T, Dim> r(*this);
775  r.fData -= x;
776  r.MoveBounds(x);
777  return r;
778 }
779 
780 template <typename T, int Dim, int alignment>
782 {
783  Parent::fData = 0;
784  Parent::SetSize(0, 0, 0);
785  Parent::SetBounds(0, -1);
786 }
787 template <typename T, int Dim, int alignment>
789 {
790  PNDFTSARRAY_STATIC_ASSERT(Dim == 1, PndFTSResizableArray1_used_with_incorrect_dimension);
792  Parent::SetSize(x, 0, 0);
793  Parent::SetBounds(0, x - 1);
794 }
795 template <typename T, int Dim, int alignment>
797 {
798  PNDFTSARRAY_STATIC_ASSERT(Dim == 2, PndFTSResizableArray2_used_with_incorrect_dimension);
799  Parent::fData = PndFTSInternal::Allocator<T, alignment>::Alloc(x * y);
800  Parent::SetSize(x, y, 0);
801  Parent::SetBounds(0, x * y - 1);
802 }
803 template <typename T, int Dim, int alignment>
805 {
806  PNDFTSARRAY_STATIC_ASSERT(Dim == 3, PndFTSResizableArray3_used_with_incorrect_dimension);
807  Parent::fData = PndFTSInternal::Allocator<T, alignment>::Alloc(x * y * z);
808  Parent::SetSize(x, y, z);
809  Parent::SetBounds(0, x * y * z - 1);
810 }
811 // #include <iostream>
812 template <typename T, int Dim, int alignment>
814 {
815  PNDFTSARRAY_STATIC_ASSERT(Dim == 1, PndFTSResizableArray1_resize_used_with_incorrect_dimension);
816  PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize);
817  Parent::fData = (x == 0) ? 0 : PndFTSInternal::Allocator<T, alignment>::Alloc(x);
818  Parent::SetSize(x, 0, 0);
819  Parent::SetBounds(0, x - 1);
820 }
821 template <typename T, int Dim, int alignment>
823 {
824  PNDFTSARRAY_STATIC_ASSERT(Dim == 2, PndFTSResizableArray2_resize_used_with_incorrect_dimension);
825  PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize);
826  Parent::fData = (x == 0) ? 0 : PndFTSInternal::Allocator<T, alignment>::Alloc(x * y);
827  Parent::SetSize(x, y, 0);
828  Parent::SetBounds(0, x * y - 1);
829 }
830 template <typename T, int Dim, int alignment>
831 inline void PndFTSResizableArray<T, Dim, alignment>::Resize(int x, int y, int z)
832 {
833  PNDFTSARRAY_STATIC_ASSERT(Dim == 3, PndFTSResizableArray3_resize_used_with_incorrect_dimension);
834  PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize);
835  Parent::fData = (x == 0) ? 0 : PndFTSInternal::Allocator<T, alignment>::Alloc(x * y * z);
836  Parent::SetSize(x, y, z);
837  Parent::SetBounds(0, x * y * z - 1);
838 }
839 
840 #undef BOUNDS_CHECK
841 
842 #endif // PNDFTSARRAY_H
#define PNDFTSARRAY_STATIC_ASSERT(cond, msg)
Definition: PndFTSArray.h:71
ReturnTypeHelper< T >::Type R
Definition: PndFTSArray.h:409
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2
Definition: PndFTSArray.h:579
ArrayBase(const ArrayBase &rhs)
Definition: PndFTSArray.h:303
static void Free(T *const p, int size)
Definition: PndFTSArray.h:201
PndFTSArray operator+(int x) const
Definition: PndFTSArray.h:764
const T * Data() const
Definition: PndFTSArray.h:523
RhoLorentzVectorErr operator+(const RhoLorentzVectorErr &, const RhoLorentzVectorErr &)
PndFTSInternal::ArrayBase< T2, Dim > Parent
Definition: PndFTSArray.h:580
ArrayBase(const ArrayBase &rhs)
Definition: PndFTSArray.h:345
unsigned int i
Definition: P4_F32vec4.h:21
static void Free(T *const p, int size)
Definition: PndFTSArray.h:266
PndFTSArray< Other, Dim > ReinterpretCast() const
Definition: PndFTSArray.h:535
PndFTSInternal::ArrayBase< T2, Size::Dim > Parent
Definition: PndFTSArray.h:656
ArrayBase(const ArrayBase &rhs)
Definition: PndFTSArray.h:399
void ReinterpretCast(const ArrayBoundsCheck &, int, int)
Definition: PndFTSArray.h:132
#define BOUNDS_CHECK(x, y)
Definition: PndFTSArray.h:134
ArrayBase & operator=(const ArrayBase &rhs)
Definition: PndFTSArray.h:346
ArrayBase & operator=(const ArrayBase &rhs)
Definition: PndFTSArray.h:304
T & operator*()
Definition: PndFTSArray.h:500
ReturnTypeHelper< T >::Type R
Definition: PndFTSArray.h:354
float & operator[](int i)
Definition: P4_F32vec4.h:5
const T & operator*() const
Definition: PndFTSArray.h:508
bool IsValid() const
Definition: PndFTSArray.h:495
const R & operator[](int x) const
Definition: PndFTSArray.h:323
PndFTSFixedArray(const PndFTSFixedArray &rhs)
Definition: PndFTSArray.h:663
static T * Alloc(int s)
Definition: PndFTSArray.h:195
void SetSize(int x, int y, int z)
Definition: PndFTSArray.h:432
int Size() const
Definition: PndFTSArray.h:486
ReturnTypeHelper< T >::Type R
Definition: PndFTSArray.h:311
PndFTSArray operator-(int x) const
Definition: PndFTSArray.h:772
#define PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg)
Definition: PndFTSArray.h:68
void SetSize(int x, int, int)
Definition: PndFTSArray.h:332
ArrayBase & operator=(const ArrayBase &rhs)
Definition: PndFTSArray.h:400
RhoLorentzVectorErr operator-(const RhoLorentzVectorErr &, const RhoLorentzVectorErr &)
PndFTSInternal::ArrayBase< T, Dim > Parent
Definition: PndFTSArray.h:480
const R & operator()(int x, int y) const
Definition: PndFTSArray.h:366
void Resize(int x)
Definition: PndFTSArray.h:813
void SetSize(int x, int y, int)
Definition: PndFTSArray.h:384
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2
Definition: PndFTSArray.h:655