PandaRoot
PndFTSArray.h
Go to the documentation of this file.
1 //****************************************************************************
2 //* This file is part of PandaRoot. *
3 //* *
4 //* PandaRoot is distributed under the terms of the *
5 //* GNU General Public License (GPL) version 3, *
6 //* copied verbatim in the file "LICENSE". *
7 //* *
8 //* Copyright (C) 2006 - 2024 FAIR GmbH and copyright holders of PandaRoot *
9 //* The copyright holders are listed in the file "COPYRIGHTHOLDERS". *
10 //* The authors are listed in the file "AUTHORS". *
11 //****************************************************************************
12 
13 /****************************************************************************
14  * This file is property of and copyright by the ALICE HLT Project *
15  * ALICE Experiment at CERN, All rights reserved. *
16  * *
17  * Copyright (C) 2009 Matthias Kretz <kretz@kde.org> *
18  * for The ALICE HLT Project. *
19  * *
20  * Permission to use, copy, modify and distribute this software and its *
21  * documentation strictly for non-commercial purposes is hereby granted *
22  * without fee, provided that the above copyright notice appears in all *
23  * copies and that both the copyright notice and this permission notice *
24  * appear in the supporting documentation. The authors make no claims *
25  * about the suitability of this software for any purpose. It is *
26  * provided "as is" without express or implied warranty. *
27  ***************************************************************************/
28 
39 #ifndef PNDFTSARRAY_H
40 #define PNDFTSARRAY_H
41 
42 #ifndef assert
43 #include <assert.h>
44 #endif
45 
46 #if (defined(__MMX__) || defined(__SSE__))
47 
48 #if defined(__GNUC__)
49 
50 #if __GNUC__ > 3
51 #define USE_MM_MALLOC
52 #endif // if __GNUC__ > 3
53 
54 #else // if defined(__GNUC__) // not gcc, assume it can use _mm_malloc since it supports MMX/SSE
55 
56 #define USE_MM_MALLOC
57 
58 #endif // if defined(__GNUC__)
59 #endif // if (defined(__MMX__) || defined(__SSE__))
60 
61 #ifdef USE_MM_MALLOC
62 #include <mm_malloc.h>
63 #else
64 #include <cstdlib>
65 #endif
66 #include <cstring>
67 
69 
71 template <bool>
73 template <>
74 class STATIC_ASSERT_FAILURE<true> {
75 };
76 } // namespace PndFTSArrayInternal
77 
78 #define PNDFTSARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b
79 #define PNDFTSARRAY_STATIC_ASSERT_CONCAT(a, b) PNDFTSARRAY_STATIC_ASSERT_CONCAT_HELPER(a, b)
80 #define PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg) \
81  typedef PndFTSArrayInternal::STATIC_ASSERT_FAILURE<cond> PNDFTSARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \
82  PNDFTSARRAY_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg
83 #define PNDFTSARRAY_STATIC_ASSERT(cond, msg) \
84  PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg); \
85  (void)Error_##msg
86 
87 template <typename T, int Dim>
89 
90 namespace PndFTSInternal {
91 template <unsigned int Size>
92 struct Padding {
93  char fPadding[Size];
94 };
95 template <>
96 struct Padding<0> {
97 };
98 template <typename T>
100  T fData;
101 };
102 template <typename T>
104  enum {
105  CacheLineSize = 64,
106  MaskedSize = sizeof(T) & (CacheLineSize - 1),
107  RequiredSize = MaskedSize == 0 ? sizeof(T) : sizeof(T) + CacheLineSize - MaskedSize,
108  PaddingSize = RequiredSize - sizeof(T)
109  };
110 };
111 template <typename T>
112 class CacheLineSizeHelper : private CacheLineSizeHelperData<T>, private Padding<CacheLineSizeHelperEnums<T>::PaddingSize> {
113  public:
114  operator T &() { return CacheLineSizeHelperData<T>::fData; }
115  operator const T &() const { return CacheLineSizeHelperData<T>::fData; }
116  // const T &operator=( const T &rhs ) { CacheLineSizeHelperData<T>::fData = rhs; }
117 
118  private:
119 };
120 template <typename T, int alignment>
122  typedef T Type;
123 };
124 template <typename T>
127 };
128 
129 // XXX
130 // The ArrayBoundsCheck and Allocator classes implement a virtual destructor only in order to
131 // silence the -Weffc++ warning. It really is not required for these classes to have a virtual
132 // dtor since polymorphism is not used (PndFTSResizableArray and PndFTSFixedArray are allocated on
133 // the stack only). The virtual dtor only adds an unnecessary vtable to the code.
134 #ifndef ENABLE_ARRAY_BOUNDS_CHECKING
135 
139  protected:
140  virtual inline ~ArrayBoundsCheck() {}
141  inline bool IsInBounds(int) const { return true; }
142  inline void SetBounds(int, int) {}
143  inline void MoveBounds(int) {}
144  inline void ReinterpretCast(const ArrayBoundsCheck &, int, int) {}
145 };
146 #define BOUNDS_CHECK(x, y)
147 #else
148 
151 class ArrayBoundsCheck {
152  protected:
153  virtual inline ~ArrayBoundsCheck() {}
157  inline bool IsInBounds(int x) const;
161  inline void SetBounds(int start, int end)
162  {
163  fStart = start;
164  fEnd = end;
165  }
169  inline void MoveBounds(int d)
170  {
171  fStart += d;
172  fEnd += d;
173  }
174 
175  inline void ReinterpretCast(const ArrayBoundsCheck &other, int sizeofOld, int sizeofNew)
176  {
177  fStart = other.fStart * sizeofNew / sizeofOld;
178  fEnd = other.fEnd * sizeofNew / sizeofOld;
179  }
180 
181  private:
182  int fStart;
183  int fEnd;
184 };
185 #define BOUNDS_CHECK(x, y) \
186  if (PndFTSInternal::ArrayBoundsCheck::IsInBounds(x)) { \
187  } else \
188  return y
189 #endif
190 template <typename T, int alignment>
191 class Allocator {
192  public:
193 #ifdef USE_MM_MALLOC
194  static inline T *Alloc(int s)
195  {
196  T *p = reinterpret_cast<T *>(_mm_malloc(s * sizeof(T), alignment));
197  return new (p) T[s];
198  }
199  static inline void Free(T *const p, int size)
200  {
201  for (int i = 0; i < size; ++i) {
202  p[i].~T();
203  }
204  _mm_free(p);
205  }
206 #else
207  static inline T *Alloc(int s)
208  {
209  T *p;
210  posix_memalign(&p, alignment, s * sizeof(T));
211  return new (p) T[s];
212  }
213  static inline void Free(T *const p, int size)
214  {
215  for (int i = 0; i < size; ++i) {
216  p[i].~T();
217  }
218  std::free(p);
219  }
220 #endif
221 };
222 template <typename T>
224  public:
226 #ifdef USE_MM_MALLOC
227  static inline T2 *Alloc(int s)
228  {
229  T2 *p = reinterpret_cast<T2 *>(_mm_malloc(s * sizeof(T2), 128));
230  return new (p) T2[s];
231  }
232  static inline void Free(T2 *const p, int size)
233  {
234  for (int i = 0; i < size; ++i) {
235  p[i].~T2();
236  }
237  _mm_free(p);
238  }
239 #else
240  static inline T2 *Alloc(int s)
241  {
242  T2 *p;
243  posix_memalign(&p, 128, s * sizeof(T2));
244  return new (p) T2[s];
245  }
246  static inline void Free(T2 *const p, int size)
247  {
248  for (int i = 0; i < size; ++i) {
249  p[i].~T2();
250  }
251  std::free(p);
252  }
253 #endif
254 };
255 template <typename T>
256 class Allocator<T, 0> {
257  public:
258 #ifdef USE_MM_MALLOC
259  static inline T *Alloc(int s)
260  {
261  T *p = reinterpret_cast<T *>(_mm_malloc(s * sizeof(T), 128));
262  return new (p) T[s];
263  }
264  static inline void Free(T *const p, int size)
265  {
266  for (int i = 0; i < size; ++i) {
267  p[i].~T();
268  }
269  _mm_free(p);
270  }
271 #else
272  static inline T *Alloc(int s)
273  {
274  T *p;
275  posix_memalign(&p, 128, s * sizeof(T));
276  return new (p) T[s];
277  }
278  static inline void Free(T *const p, int size)
279  {
280  for (int i = 0; i < size; ++i) {
281  p[i].~T();
282  }
283  std::free(p);
284  }
285 #endif
286 
287  // public:
288  // static inline T *Alloc( int s ) { return new T[s]; }
289  // static inline void Free( const T *const p, int ) { delete[] p; }
290 };
291 
292 template <typename T>
294  typedef T Type;
295 };
296 template <typename T>
298  typedef T Type;
299 };
303 template <typename T, int Dim>
304 class ArrayBase;
305 
309 template <typename T>
310 class ArrayBase<T, 1> : public ArrayBoundsCheck {
311  friend class ArrayBase<T, 2>;
312 
313  public:
314  ArrayBase() : fData(0) {} // XXX really shouldn't be done. But -Weffc++ wants it so
315  ArrayBase(const ArrayBase &rhs) : ArrayBoundsCheck(rhs), fData(rhs.fData), fSize(rhs.fSize) {} // XXX
317  {
318  ArrayBoundsCheck::operator=(rhs);
319  fData = rhs.fData;
320  fSize = rhs.fSize;
321  return *this;
322  } // XXX
323  typedef typename ReturnTypeHelper<T>::Type R;
327  inline R &operator[](int x)
328  {
329  BOUNDS_CHECK(x, fData[0]);
330  return fData[x];
331  }
335  inline const R &operator[](int x) const
336  {
337  BOUNDS_CHECK(x, fData[0]);
338  return fData[x];
339  }
340 
341  protected:
342  T *fData;
343  int fSize;
344  inline void SetSize(int x, int, int) { fSize = x; }
345 };
346 
351 template <typename T>
352 class ArrayBase<T, 2> : public ArrayBoundsCheck {
353  friend class ArrayBase<T, 3>;
354 
355  public:
356  ArrayBase() : fData(0), fSize(0), fStride(0) {} // XXX really shouldn't be done. But -Weffc++ wants it so
357  ArrayBase(const ArrayBase &rhs) : ArrayBoundsCheck(rhs), fData(rhs.fData), fSize(rhs.fSize), fStride(rhs.fStride) {} // XXX
359  {
360  ArrayBoundsCheck::operator=(rhs);
361  fData = rhs.fData;
362  fSize = rhs.fSize;
363  fStride = rhs.fStride;
364  return *this;
365  } // XXX
366  typedef typename ReturnTypeHelper<T>::Type R;
370  inline R &operator()(int x, int y)
371  {
372  BOUNDS_CHECK(x * fStride + y, fData[0]);
373  return fData[x * fStride + y];
374  }
378  inline const R &operator()(int x, int y) const
379  {
380  BOUNDS_CHECK(x * fStride + y, fData[0]);
381  return fData[x * fStride + y];
382  }
386  inline PndFTSArray<T, 1> operator[](int x);
390  inline const PndFTSArray<T, 1> operator[](int x) const;
391 
392  protected:
393  T *fData;
394  int fSize;
395  int fStride;
396  inline void SetSize(int x, int y, int)
397  {
398  fStride = y;
399  fSize = x * y;
400  }
401 };
402 
407 template <typename T>
408 class ArrayBase<T, 3> : public ArrayBoundsCheck {
409  public:
410  ArrayBase() : fData(0), fSize(0), fStrideX(0), fStrideY(0) {} // XXX really shouldn't be done. But -Weffc++ wants it so
411  ArrayBase(const ArrayBase &rhs) : ArrayBoundsCheck(rhs), fData(rhs.fData), fSize(rhs.fSize), fStrideX(rhs.fStrideX), fStrideY(rhs.fStrideY) {} // XXX
413  {
414  ArrayBoundsCheck::operator=(rhs);
415  fData = rhs.fData;
416  fSize = rhs.fSize;
417  fStrideX = rhs.fStrideX;
418  fStrideY = rhs.fStrideY;
419  return *this;
420  } // XXX
421  typedef typename ReturnTypeHelper<T>::Type R;
425  inline R &operator()(int x, int y, int z);
429  inline const R &operator()(int x, int y, int z) const;
433  inline PndFTSArray<T, 2> operator[](int x);
437  inline const PndFTSArray<T, 2> operator[](int x) const;
438 
439  protected:
440  T *fData;
441  int fSize;
442  int fStrideX;
443  int fStrideY;
444  inline void SetSize(int x, int y, int z)
445  {
446  fStrideX = y * z;
447  fStrideY = z;
448  fSize = fStrideX * x;
449  }
450 };
451 
452 template <typename T, unsigned int Size, int _alignment>
453 class AlignedData {
454  public:
456  {
457  const int offset = reinterpret_cast<unsigned long>(&fUnalignedArray[0]) & (Alignment - 1);
458  void *mem = &fUnalignedArray[0] + (Alignment - offset);
459  return new (mem) T[Size];
460  }
462  {
463  const int offset = reinterpret_cast<unsigned long>(&fUnalignedArray[0]) & (Alignment - 1);
464  T *mem = reinterpret_cast<T *>(&fUnalignedArray[0] + (Alignment - offset));
465  for (unsigned int i = 0; i < Size; ++i) {
466  mem[i].~T();
467  }
468  }
469 
470  private:
471  enum { Alignment = _alignment == PndFTSFullyCacheLineAligned ? 128 : _alignment, PaddedSize = Size * sizeof(T) + Alignment };
472  PNDFTSARRAY_STATIC_ASSERT_NC((Alignment & (Alignment - 1)) == 0, alignment_needs_to_be_a_multiple_of_2);
473 
474  char fUnalignedArray[PaddedSize];
475 };
476 template <typename T, unsigned int Size>
477 class AlignedData<T, Size, 0> {
478  public:
479  T *ConstructAlignedData() { return &fArray[0]; }
480 
481  private:
482  T fArray[Size];
483 };
484 } // namespace PndFTSInternal
485 
489 template <typename T, int Dim = 1>
490 class PndFTSArray : public PndFTSInternal::ArrayBase<T, Dim> {
491  public:
493 
498  inline int Size() const { return Parent::fSize; }
499 
503  inline operator bool() const { return Parent::fData != 0; }
507  inline bool IsValid() const { return Parent::fData != 0; }
508 
512  inline T &operator*()
513  {
514  BOUNDS_CHECK(0, Parent::fData[0]);
515  return *Parent::fData;
516  }
520  inline const T &operator*() const
521  {
522  BOUNDS_CHECK(0, Parent::fData[0]);
523  return *Parent::fData;
524  }
525 
530  inline T *Data() { return Parent::fData; }
535  inline const T *Data() const { return Parent::fData; }
536 
540  inline PndFTSArray operator+(int x) const;
544  inline PndFTSArray operator-(int x) const;
545 
546  template <typename Other>
548  {
550  r.fData = reinterpret_cast<Other *>(Parent::fData);
551  r.ReinterpretCast(*this, sizeof(T), sizeof(Other));
552  }
553 };
554 
588 template <typename T, int Dim = 1, int alignment = 0>
589 class PndFTSResizableArray : public PndFTSArray<typename PndFTSInternal::TypeForAlignmentHelper<T, alignment>::Type, Dim> {
590  public:
596  inline PndFTSResizableArray();
600  inline PndFTSResizableArray(int x);
604  inline PndFTSResizableArray(int x, int y);
608  inline PndFTSResizableArray(int x, int y, int z);
609 
613  inline ~PndFTSResizableArray() { PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize); }
614 
621  inline void Resize(int x);
628  inline void Resize(int x, int y);
635  inline void Resize(int x, int y, int z);
636 
637  private:
638  // disable allocation on the heap
639  void *operator new(size_t);
640 
641  // disable copy
643  PndFTSResizableArray &operator=(const PndFTSResizableArray &);
644 };
645 
646 template <unsigned int x, unsigned int y = 0, unsigned int z = 0>
648  public:
649  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 };
650 };
651 
664 template <typename T, typename Size, int alignment = 0>
665 class PndFTSFixedArray : public PndFTSArray<typename PndFTSInternal::TypeForAlignmentHelper<T, alignment>::Type, Size::Dim> {
666  public:
670  {
671  fData = fFixedArray.ConstructAlignedData();
672  Parent::SetBounds(0, Size::Size - 1);
673  SetSize(Size::X, Size::Y, Size::Z);
674  }
676  {
677  fData = fFixedArray.ConstructAlignedData();
678  Parent::SetBounds(0, Size::Size - 1);
679  SetSize(Size::X, Size::Y, Size::Z);
680  std::memcpy(fData, rhs.fData, Size::Size * sizeof(T));
681  }
682 
683  private:
685 
686  // disable allocation on the heap
687  void *operator new(size_t);
688 
689  using Parent::fData;
690 
691  // disable copy
692  PndFTSFixedArray &operator=(const PndFTSFixedArray &);
693 };
694 
698 
699 namespace PndFTSInternal {
700 #ifdef ENABLE_ARRAY_BOUNDS_CHECKING
701 inline bool ArrayBoundsCheck::IsInBounds(int x) const
702 {
703  assert(x >= fStart);
704  assert(x <= fEnd);
705  return (x >= fStart && x <= fEnd);
706 }
707 #endif
708 
709 template <typename T>
711 {
712  x *= fStride;
713  // typedef PndFTSArray<T, 1> AT1;
714  // BOUNDS_CHECK( x, AT1() );
716  a.fData = &fData[x];
717  a.ArrayBoundsCheck::operator=(*this);
718  a.MoveBounds(-x);
719  return a;
720 }
721 
722 template <typename T>
724 {
725  x *= fStride;
726  // typedef PndFTSArray<T, 1> AT1;
727  // BOUNDS_CHECK( x, AT1() );
729  a.fData = &fData[x];
730  a.ArrayBoundsCheck::operator=(*this);
731  a.MoveBounds(-x);
732  return a;
733 }
734 
735 template <typename T>
737 {
738  BOUNDS_CHECK(x * fStrideX + y + fStrideY + z, fData[0]);
739  return fData[x * fStrideX + y + fStrideY + z];
740 }
741 template <typename T>
742 inline const typename PndFTSInternal::ArrayBase<T, 3>::R &ArrayBase<T, 3>::operator()(int x, int y, int z) const
743 {
744  BOUNDS_CHECK(x * fStrideX + y + fStrideY + z, fData[0]);
745  return fData[x * fStrideX + y + fStrideY + z];
746 }
747 template <typename T>
749 {
750  x *= fStrideX;
751  // typedef PndFTSArray<T, 2> AT2;
752  // BOUNDS_CHECK( x, AT2() );
754  a.fData = &fData[x];
755  a.fStride = fStrideY;
756  a.ArrayBoundsCheck::operator=(*this);
757  a.MoveBounds(-x);
758  return a;
759 }
760 template <typename T>
762 {
763  x *= fStrideX;
764  // typedef PndFTSArray<T, 2> AT2;
765  // BOUNDS_CHECK( x, AT2() );
767  a.fData = &fData[x];
768  a.fStride = fStrideY;
769  a.ArrayBoundsCheck::operator=(*this);
770  a.MoveBounds(-x);
771  return a;
772 }
773 } // namespace PndFTSInternal
774 
775 template <typename T, int Dim>
777 {
778  PndFTSArray<T, Dim> r(*this);
779  r.fData += x;
780  r.MoveBounds(-x);
781  return r;
782 }
783 template <typename T, int Dim>
785 {
786  PndFTSArray<T, Dim> r(*this);
787  r.fData -= x;
788  r.MoveBounds(x);
789  return r;
790 }
791 
792 template <typename T, int Dim, int alignment>
794 {
795  Parent::fData = 0;
796  Parent::SetSize(0, 0, 0);
797  Parent::SetBounds(0, -1);
798 }
799 template <typename T, int Dim, int alignment>
801 {
802  PNDFTSARRAY_STATIC_ASSERT(Dim == 1, PndFTSResizableArray1_used_with_incorrect_dimension);
804  Parent::SetSize(x, 0, 0);
805  Parent::SetBounds(0, x - 1);
806 }
807 template <typename T, int Dim, int alignment>
809 {
810  PNDFTSARRAY_STATIC_ASSERT(Dim == 2, PndFTSResizableArray2_used_with_incorrect_dimension);
811  Parent::fData = PndFTSInternal::Allocator<T, alignment>::Alloc(x * y);
812  Parent::SetSize(x, y, 0);
813  Parent::SetBounds(0, x * y - 1);
814 }
815 template <typename T, int Dim, int alignment>
817 {
818  PNDFTSARRAY_STATIC_ASSERT(Dim == 3, PndFTSResizableArray3_used_with_incorrect_dimension);
819  Parent::fData = PndFTSInternal::Allocator<T, alignment>::Alloc(x * y * z);
820  Parent::SetSize(x, y, z);
821  Parent::SetBounds(0, x * y * z - 1);
822 }
823 // #include <iostream>
824 template <typename T, int Dim, int alignment>
826 {
827  PNDFTSARRAY_STATIC_ASSERT(Dim == 1, PndFTSResizableArray1_resize_used_with_incorrect_dimension);
828  PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize);
829  Parent::fData = (x == 0) ? 0 : PndFTSInternal::Allocator<T, alignment>::Alloc(x);
830  Parent::SetSize(x, 0, 0);
831  Parent::SetBounds(0, x - 1);
832 }
833 template <typename T, int Dim, int alignment>
835 {
836  PNDFTSARRAY_STATIC_ASSERT(Dim == 2, PndFTSResizableArray2_resize_used_with_incorrect_dimension);
837  PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize);
838  Parent::fData = (x == 0) ? 0 : PndFTSInternal::Allocator<T, alignment>::Alloc(x * y);
839  Parent::SetSize(x, y, 0);
840  Parent::SetBounds(0, x * y - 1);
841 }
842 template <typename T, int Dim, int alignment>
843 inline void PndFTSResizableArray<T, Dim, alignment>::Resize(int x, int y, int z)
844 {
845  PNDFTSARRAY_STATIC_ASSERT(Dim == 3, PndFTSResizableArray3_resize_used_with_incorrect_dimension);
846  PndFTSInternal::Allocator<T, alignment>::Free(Parent::fData, Parent::fSize);
847  Parent::fData = (x == 0) ? 0 : PndFTSInternal::Allocator<T, alignment>::Alloc(x * y * z);
848  Parent::SetSize(x, y, z);
849  Parent::SetBounds(0, x * y * z - 1);
850 }
851 
852 #undef BOUNDS_CHECK
853 
854 #endif // PNDFTSARRAY_H
#define PNDFTSARRAY_STATIC_ASSERT(cond, msg)
Definition: PndFTSArray.h:83
ReturnTypeHelper< T >::Type R
Definition: PndFTSArray.h:421
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2
Definition: PndFTSArray.h:591
ArrayBase(const ArrayBase &rhs)
Definition: PndFTSArray.h:315
static void Free(T *const p, int size)
Definition: PndFTSArray.h:213
PndFTSArray operator+(int x) const
Definition: PndFTSArray.h:776
const T * Data() const
Definition: PndFTSArray.h:535
RhoLorentzVectorErr operator+(const RhoLorentzVectorErr &, const RhoLorentzVectorErr &)
PndFTSInternal::ArrayBase< T2, Dim > Parent
Definition: PndFTSArray.h:592
ArrayBase(const ArrayBase &rhs)
Definition: PndFTSArray.h:357
unsigned int i
Definition: P4_F32vec4.h:33
static void Free(T *const p, int size)
Definition: PndFTSArray.h:278
PndFTSArray< Other, Dim > ReinterpretCast() const
Definition: PndFTSArray.h:547
PndFTSInternal::ArrayBase< T2, Size::Dim > Parent
Definition: PndFTSArray.h:668
ArrayBase(const ArrayBase &rhs)
Definition: PndFTSArray.h:411
void ReinterpretCast(const ArrayBoundsCheck &, int, int)
Definition: PndFTSArray.h:144
#define BOUNDS_CHECK(x, y)
Definition: PndFTSArray.h:146
ArrayBase & operator=(const ArrayBase &rhs)
Definition: PndFTSArray.h:358
ArrayBase & operator=(const ArrayBase &rhs)
Definition: PndFTSArray.h:316
T & operator*()
Definition: PndFTSArray.h:512
ReturnTypeHelper< T >::Type R
Definition: PndFTSArray.h:366
float & operator[](int i)
Definition: P4_F32vec4.h:17
const T & operator*() const
Definition: PndFTSArray.h:520
bool IsValid() const
Definition: PndFTSArray.h:507
const R & operator[](int x) const
Definition: PndFTSArray.h:335
PndFTSFixedArray(const PndFTSFixedArray &rhs)
Definition: PndFTSArray.h:675
static T * Alloc(int s)
Definition: PndFTSArray.h:207
void SetSize(int x, int y, int z)
Definition: PndFTSArray.h:444
int Size() const
Definition: PndFTSArray.h:498
ReturnTypeHelper< T >::Type R
Definition: PndFTSArray.h:323
PndFTSArray operator-(int x) const
Definition: PndFTSArray.h:784
#define PNDFTSARRAY_STATIC_ASSERT_NC(cond, msg)
Definition: PndFTSArray.h:80
void SetSize(int x, int, int)
Definition: PndFTSArray.h:344
ArrayBase & operator=(const ArrayBase &rhs)
Definition: PndFTSArray.h:412
RhoLorentzVectorErr operator-(const RhoLorentzVectorErr &, const RhoLorentzVectorErr &)
PndFTSInternal::ArrayBase< T, Dim > Parent
Definition: PndFTSArray.h:492
const R & operator()(int x, int y) const
Definition: PndFTSArray.h:378
void Resize(int x)
Definition: PndFTSArray.h:825
void SetSize(int x, int y, int)
Definition: PndFTSArray.h:396
PndFTSInternal::TypeForAlignmentHelper< T, alignment >::Type T2
Definition: PndFTSArray.h:667