Chombo + EB + MF  3.2
CHArray.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _CHARRAY_H_
12 #define _CHARRAY_H_
13 
14 /******************************************************************************/
15 /**
16  * \file
17  *
18  * \brief A multi-dimensional array class for Chombo
19  *
20  *//***************************************************************************/
21 // search for 'class CHArray'
22 
23 #include <iomanip>
24 
25 #include "CHArray_fwd.H"
26 
27 #ifdef CH_SPACEDIM
28 // In Chombo land
29  #include "REAL.H"
30  #include "Misc.H"
31  #include "Box.H"
32  #include "NamespaceHeader.H"
33 #else
34 // Probably testing land
35  #include <cassert>
36 // #define CH_assert(cond) (void)0
37  #define CH_assert(cond) assert(cond)
38  #define SpaceDim 2
39  #define D_DECL6(a,b,c,d,e,f) a,b
40  #define D_TERM6(a,b,c,d,e,f) a b
41  typedef double Real;
42  class IntVect
43  {
44  public:
45  IntVect(D_DECL6(const int i0, const int i1, const int i2,
46  const int i3, const int i4, const int i5))
47  {
48  D_TERM6(vec[0] = i0;, vec[1] = i1;, vec[2] = i2;,
49  vec[3] = i3;, vec[4] = i4;, vec[5] = i5;)
50  }
51  IntVect(const IntVect &iv)
52  {
53  D_TERM6(vec[0] = iv.vec[0];, vec[1] = iv.vec[1];, vec[2] = iv.vec[2];,
54  vec[3] = iv.vec[3];, vec[4] = iv.vec[4];, vec[5] = iv.vec[5];)
55  }
56  int &operator[](const int i)
57  {
58  return vec[i];
59  }
60  const int &operator[](const int i) const
61  {
62  return vec[i];
63  }
64  int product() const
65  {
66  int prod = 1;
67  for (int i = 0; i != SpaceDim; ++i) prod *= vec[i];
68  return prod;
69  }
70  int vec[SpaceDim];
71  };
72  class Box
73  {
74  public:
75  Box(const IntVect &lb, const IntVect &ub)
76  : m_lb(lb), m_ub(ub)
77  { }
78  int smallEnd(const int dir) const
79  {
80  return m_lb[dir];
81  }
82  int bigEnd(const int dir) const
83  {
84  return m_ub[dir];
85  }
86  IntVect size() const
87  {
88  return IntVect(D_DECL6(m_ub[0] - m_lb[0] + 1,
89  m_ub[1] - m_lb[1] + 1,
90  m_ub[2] - m_lb[2] + 1,
91  m_ub[3] - m_lb[3] + 1,
92  m_ub[4] - m_lb[4] + 1,
93  m_ub[5] - m_lb[5] + 1));
94  }
97  };
98  // Test for class type
99  namespace Misc {
100  template <typename T>
101  class TypeTr
102  {
103  private:
104  typedef char One;
105  typedef struct
106  {
107  char a[2];
108  } Two;
109  template <typename C> static One test(int C::*);
110  template <typename C> static Two test(...);
111  public:
112  enum
113  {
114  IsClass = sizeof(TypeTr<T>::template test<T>(0)) == 1
115  };
116  };
117  }
118 #endif
119 
120 // How to index an IntVect. May evaluate to, e.g., iv[0], iv[1], iv[2] or
121 // iv[2], iv[1], iv[0]
122 # define D_DEFIV D_DECL6(DimT(iv[Indexer::ixIV(0)]), \
123  DimT(iv[Indexer::ixIV(1)]), \
124  DimT(iv[Indexer::ixIV(2)]), \
125  DimT(iv[Indexer::ixIV(3)]), \
126  DimT(iv[Indexer::ixIV(4)]), \
127  DimT(iv[Indexer::ixIV(5)]))
128 
129 // How to index a Box. Same as above but determines a range.
130 # define D_DEFBOX D_DECL6(DimT(box.smallEnd(Indexer::ixIV(0)), \
131  box.bigEnd(Indexer::ixIV(0))), \
132  DimT(box.smallEnd(Indexer::ixIV(1)), \
133  box.bigEnd(Indexer::ixIV(1))), \
134  DimT(box.smallEnd(Indexer::ixIV(2)), \
135  box.bigEnd(Indexer::ixIV(2))), \
136  DimT(box.smallEnd(Indexer::ixIV(3)), \
137  box.bigEnd(Indexer::ixIV(3))), \
138  DimT(box.smallEnd(Indexer::ixIV(4)), \
139  box.bigEnd(Indexer::ixIV(4))), \
140  DimT(box.smallEnd(Indexer::ixIV(5)), \
141  box.bigEnd(Indexer::ixIV(5))))
142 
143 // How to index an IntVect. May evaluate to, e.g., iv[0], iv[1], iv[2] or
144 // iv[2], iv[1], iv[0]
145 # define D_IXIV D_DECL6(iv[Indexer::ixIV(0)], \
146  iv[Indexer::ixIV(1)], \
147  iv[Indexer::ixIV(2)], \
148  iv[Indexer::ixIV(3)], \
149  iv[Indexer::ixIV(4)], \
150  iv[Indexer::ixIV(5)])
151 
152 namespace ArSp // CHArray support
153 {
154 
155 // An index refers to a single dimension and a size to the overall
156 // size of the array. Except for 1D arrays, indexes are smaller than
157 // sizes by division by at least 1 stride.
158 
159 typedef int IIx_t; ///< Type of int for an index. Must be
160  ///< signed to allow for lower bounds != 0
161 typedef unsigned USz_t; ///< Type of unsigned int for a size
162 }
163 
164 /* This enum had to be put in CHArray_fwd.H because it is used for default
165  * template parameters. Repeated here for informational purposes
166 /|/ Array configuration parameters
167 enum
168 {
169  ArZeroRow, /|/< Zero lower bound and row-storage
170  ArZeroCol, /|/< Zero lower bound and column-storage
171  ArRangeRow, /|/< Range of subscripts and row-storage
172  ArRangeCol /|/< Range of subscripts and column-
173  /|/< storage
174 };
175  */
176 
177 /*====================================================================*/
178 /// Defines a range of subscripts
179 /*====================================================================*/
180 
181 struct CHRange
182 {
183  CHRange(const ArSp::IIx_t a_dimE)
184  : dimB(0), dimE(a_dimE - 1)
185  {
186  CH_assert(a_dimE >= 0);
187  }
188  CHRange(const ArSp::IIx_t a_dimB, const ArSp::IIx_t a_dimE)
189  : dimB(a_dimB), dimE(a_dimE)
190  {
191  CH_assert(a_dimE >= a_dimB);
192  }
195 };
196 
197 /*====================================================================*/
198 /** \name Support for describing dimensions by a range of subscripts
199  *//*=================================================================*/
200 //@{
201 
202 namespace ArSp // CHArray support
203 {
204 
205 /// Get the size of a dimension
206 template <typename T>
207 inline USz_t sizeOfDim(const T &dim)
208 {
209  return (USz_t)dim;
210 }
211 
212 ///
213 template <>
215 {
216  return (USz_t)(dim.dimE - dim.dimB + 1);
217 }
218 }
219 
220 /// Multiply two dimensions
221 inline ArSp::USz_t operator*(const CHRange &a, const CHRange &b)
222 {
223  return (ArSp::sizeOfDim(a)*ArSp::sizeOfDim(b));
224 }
225 
226 ///
227 inline ArSp::USz_t operator*(const ArSp::USz_t &i, const CHRange &a)
228 {
229  return i*ArSp::sizeOfDim(a);
230 }
231 
232 ///
233 inline ArSp::USz_t operator*(const CHRange &a, const ArSp::USz_t &i)
234 {
235  return ArSp::sizeOfDim(a)*i;
236 }
237 //@}
238 
239 namespace ArSp // CHArray support
240 {
241 
242 /*====================================================================*/
243 /** \name Raw address allocation policy
244  *//*=================================================================*/
245 //@{
246 
247 template <typename T, bool IsClass = Misc::TypeTr<T>::IsClass>
249 
250 /// If elements are class type, allocate using placement new
251 template <typename T>
252 struct AllocRawPolicy<T, true>
253 {
254  static T *eval(void *const addr, const USz_t size)
255  {
256  return new(addr) T[size];
257  }
258 };
259 
260 /// If element are not class type, just assign the address
261 template <typename T>
262 struct AllocRawPolicy<T, false>
263 {
264  static T *eval(void *const addr, const USz_t size)
265  {
266  return static_cast<T*>(addr);
267  }
268 };
269 //@}
270 
271 /*====================================================================*/
272 /** \name Raw address release policy
273  *//*=================================================================*/
274 //@{
275 
276 template <typename T, bool IsClass = Misc::TypeTr<T>::IsClass>
278 
279 /// If elements are class type, invoke destructor on each element
280 template <typename T>
281 struct ReleaseRawPolicy<T, true>
282 {
283  static void eval(T *p, USz_t size)
284  {
285  while (size--) p++->~T();
286  }
287 };
288 
289 /// If elements are not class type, do nothing
290 template <typename T>
291 struct ReleaseRawPolicy<T, false>
292 {
293  static void eval(T *p, USz_t size)
294  {
295  }
296 };
297 //@}
298 
299 /*====================================================================*/
300 /// Default allocator
301 /** Allocators used by class array are simplified versions of the
302  * std::allocator and may contain member data.
303  * The following members are required:
304  * <ul>
305  * <li> allocate(const USz_t size)
306  * - Allocate and construct 'size' objects
307  * <li> deallocate(void *const addr, const USz_t size)
308  * - Deallocate and destroy 'size' objects at 'addr'
309  * </ul>
310  * The following members are optional:
311  * <ul>
312  * <li> allocate(void *const addr, const USz_t size)
313  * - Construct 'size' objects at 'addr'. If provided,
314  * CHArray::define(void *const addr, ...) can be used to
315  * construct on preallocated memory. In this case,
316  * deallocate should only destroy the created objects,
317  * not delete the memory.
318  * </ul>
319  *//*=================================================================*/
320 
321 template <typename T>
323 {
324 private:
325  enum AllocBy
326  {
329  AllocRaw
330  };
332 
333 public:
335  : m_allocBy(AllocUndefined)
336  { }
337 
338  T* allocate(const USz_t size)
339  {
340  T *const p = new(std::nothrow) T[size];
341  CH_assert(p != 0);
342  m_allocBy = AllocNew;
343  return p;
344  }
345 
346  T* allocate(void *const addr, const USz_t size)
347  {
348  m_allocBy = AllocRaw;
349  return AllocRawPolicy<T>::eval(addr, size);
350  }
351 
352  void deallocate(T *p, const USz_t size)
353  {
354  switch (m_allocBy)
355  {
356  case AllocNew:
357  delete[] p;
358  break;
359  case AllocRaw:
360  ReleaseRawPolicy<T>::eval(p, size);
361  break;
362  case AllocUndefined:
363  break;
364  }
365  }
366 };
367 
368 /*====================================================================*/
369 /** \name Data for the indexer classes. This may vary in size
370  * depending on if the subscripts are zero-based or ranges.
371  *//*=================================================================*/
372 //@{
373 
374 /*--------------------------------------------------------------------*/
375 /// Any rank and a zero-based subscript
376 /*--------------------------------------------------------------------*/
377 
378 template <unsigned Rank, typename DimT>
380 {
381 protected:
383  : m_ixStride(0)
384  { }
385  IndexerData(const USz_t stride, const DimT &dim)
386  : m_ixStride(stride)
387  { }
388  void ixDefineLowerBound(const DimT &dim)
389  { }
391  {
392  return 0;
393  }
394  bool ixValidBounds(const IIx_t i, const USz_t size) const
395  {
396  return (((USz_t)i) < size/m_ixStride);
397  }
399  {
400  return 0;
401  }
402  USz_t m_ixStride; ///< Stride for this dimension
403 };
404 
405 /*--------------------------------------------------------------------*/
406 /// Any rank and a subscript range
407 /*--------------------------------------------------------------------*/
408 
409 template <unsigned Rank>
410 class IndexerData<Rank, CHRange>
411 {
412 protected:
414  : m_ixStride(0), m_ixIB(0)
415  { }
416  IndexerData(const USz_t stride, const CHRange &dim)
417  : m_ixStride(stride), m_ixIB(dim.dimB)
418  { }
420  {
421  m_ixIB = dim.dimB;
422  }
424  {
425  return m_ixIB;
426  }
427  bool ixValidBounds(const IIx_t i, const USz_t size) const
428  {
429  return (i >= m_ixIB && i < m_ixIB + (IIx_t)(size/m_ixStride));
430  }
432  {
433  return m_ixIB*m_ixStride;
434  }
435  USz_t m_ixStride; ///< Stride for this dimension
436 private:
437  IIx_t m_ixIB; ///< Lower bound for this dimension
438 };
439 
440 /*--------------------------------------------------------------------*/
441 /// Rank 1 and a zero-based subscript (no data)
442 /*--------------------------------------------------------------------*/
443 
444 template <typename DimT>
445 class IndexerData<1, DimT>
446 {
447 protected:
449  { }
450  IndexerData(const DimT &dim)
451  { }
452  void ixDefineLowerBound(const DimT &dim)
453  { }
455  {
456  return 0;
457  }
458  bool ixValidBounds(const IIx_t i, const USz_t size) const
459  {
460  return (((USz_t)i) < size);
461  }
462  void ixDefineTotalOffset(const IIx_t offset)
463  { }
465  {
466  return 0;
467  }
468 };
469 
470 /*--------------------------------------------------------------------*/
471 /// Rank 1 and a subscript range
472 /*--------------------------------------------------------------------*/
473 
474 template <>
476 {
477 protected:
479  : m_ixIB(0)
480  { }
482  : m_ixIB(dim.dimB)
483  { }
485  {
486  m_ixIB = dim.dimB;
487  }
489  {
490  return m_ixIB;
491  }
492  bool ixValidBounds(const IIx_t i, const USz_t size) const
493  {
494  return (i >= m_ixIB && i < m_ixIB + (IIx_t)size);
495  }
496  void ixDefineTotalOffset(const IIx_t offset)
497  {
498  m_ixOffset = offset;
499  }
501  {
502  return m_ixOffset;
503  }
504 private:
505  IIx_t m_ixIB; ///< Lower bound for this dimension
506  IIx_t m_ixOffset; ///< Total offset to an index because of
507  ///< non-zero lower bounds for this and
508  ///< all higher dimensions
509 };
510 
511 /*====================================================================*/
512 /** \name Provides indexing for row ordered (C) storage.
513  *//*=================================================================*/
514 //@{
515 
516 /*--------------------------------------------------------------------*/
517 /// Rank > 2 for zero-based subscripts and > 1 for subscript ranges
518 /*--------------------------------------------------------------------*/
519 
520 template <unsigned Rank, typename DimT>
521 class RSIndexer : private IndexerData<Rank, DimT>
522 {
524 public:
526  : IxData(), m_ixNext()
527  { }
528 
529  RSIndexer(const IIx_t offset,
530  const DimT &dim6, const DimT &dim5, const DimT &dim4,
531  const DimT &dim3, const DimT &dim2, const DimT &dim1,
532  const DimT &dim0)
533  : IxData(dim5*dim4*dim3*dim2*dim1*dim0, dim6),
534  m_ixNext(offset - IxData::ixDimOffset(),
535  dim5, dim4, dim3, dim2, dim1, dim0)
536  { }
537  RSIndexer(const IIx_t offset,
538  const DimT &dim5, const DimT &dim4, const DimT &dim3,
539  const DimT &dim2, const DimT &dim1, const DimT &dim0)
540  : IxData(dim4*dim3*dim2*dim1*dim0, dim5),
541  m_ixNext(offset - IxData::ixDimOffset(), dim4, dim3, dim2, dim1, dim0)
542  { }
543  RSIndexer(const IIx_t offset,
544  const DimT &dim4, const DimT &dim3, const DimT &dim2,
545  const DimT &dim1, const DimT &dim0)
546  : IxData(dim3*dim2*dim1*dim0, dim4),
547  m_ixNext(offset - IxData::ixDimOffset(), dim3, dim2, dim1, dim0)
548  { }
549  RSIndexer(const IIx_t offset,
550  const DimT &dim3, const DimT &dim2, const DimT &dim1,
551  const DimT &dim0)
552  : IxData(dim2*dim1*dim0, dim3),
553  m_ixNext(offset - IxData::ixDimOffset(), dim2, dim1, dim0)
554  { }
555  RSIndexer(const IIx_t offset,
556  const DimT &dim2, const DimT &dim1, const DimT &dim0)
557  : IxData(dim1*dim0, dim2),
558  m_ixNext(offset - IxData::ixDimOffset(), dim1, dim0)
559  { }
560  RSIndexer(const IIx_t offset,
561  const DimT &dim1, const DimT &dim0)
562  : IxData(sizeOfDim(dim0), dim1),
563  m_ixNext(offset - IxData::ixDimOffset(), dim0)
564  { }
565 
566  void ixDefine(const IIx_t offset,
567  const DimT &dim6, const DimT &dim5, const DimT &dim4,
568  const DimT &dim3, const DimT &dim2, const DimT &dim1,
569  const DimT &dim0)
570  {
571  IxData::m_ixStride = dim5*dim4*dim3*dim2*dim1*dim0;
572  IxData::ixDefineLowerBound(dim6);
573  m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
574  dim5, dim4, dim3, dim2, dim1, dim0);
575  }
576  void ixDefine(const IIx_t offset,
577  const DimT &dim5, const DimT &dim4, const DimT &dim3,
578  const DimT &dim2, const DimT &dim1, const DimT &dim0)
579  {
580  IxData::m_ixStride = dim4*dim3*dim2*dim1*dim0;
581  IxData::ixDefineLowerBound(dim5);
582  m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
583  dim4, dim3, dim2, dim1, dim0);
584  }
585  void ixDefine(const IIx_t offset,
586  const DimT &dim4, const DimT &dim3, const DimT &dim2,
587  const DimT &dim1, const DimT &dim0)
588  {
589  IxData::m_ixStride = dim3*dim2*dim1*dim0;
590  IxData::ixDefineLowerBound(dim4);
591  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim3, dim2, dim1, dim0);
592  }
593  void ixDefine(const IIx_t offset,
594  const DimT &dim3, const DimT &dim2, const DimT &dim1,
595  const DimT &dim0)
596  {
597  IxData::m_ixStride = dim2*dim1*dim0;
598  IxData::ixDefineLowerBound(dim3);
599  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim2, dim1, dim0);
600  }
601  void ixDefine(const IIx_t offset,
602  const DimT &dim2, const DimT &dim1, const DimT &dim0)
603  {
604  IxData::m_ixStride = dim1*dim0;
605  IxData::ixDefineLowerBound(dim2);
606  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim1, dim0);
607  }
608  void ixDefine(const IIx_t offset,
609  const DimT &dim1, const DimT &dim0)
610  {
611  IxData::m_ixStride = sizeOfDim(dim0);
612  IxData::ixDefineLowerBound(dim1);
613  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0);
614  }
615 
616  USz_t ixIndex1D(const USz_t size,
617  const IIx_t i6, const IIx_t i5, const IIx_t i4,
618  const IIx_t i3, const IIx_t i2, const IIx_t i1,
619  const IIx_t i0) const
620  {
621  CH_assert((IxData::ixValidBounds(i6, size)));
622  return IxData::m_ixStride*i6 +
623  m_ixNext.ixIndex1D(IxData::m_ixStride, i5, i4, i3, i2, i1, i0);
624  }
625  USz_t ixIndex1D(const USz_t size,
626  const IIx_t i5, const IIx_t i4, const IIx_t i3,
627  const IIx_t i2, const IIx_t i1, const IIx_t i0) const
628  {
629  CH_assert((IxData::ixValidBounds(i5, size)));
630  return IxData::m_ixStride*i5 +
631  m_ixNext.ixIndex1D(IxData::m_ixStride, i4, i3, i2, i1, i0);
632  }
633  USz_t ixIndex1D(const USz_t size,
634  const IIx_t i4, const IIx_t i3, const IIx_t i2,
635  const IIx_t i1, const IIx_t i0) const
636  {
637  CH_assert((IxData::ixValidBounds(i4, size)));
638  return IxData::m_ixStride*i4 +
639  m_ixNext.ixIndex1D(IxData::m_ixStride, i3, i2, i1, i0);
640  }
641  USz_t ixIndex1D(const USz_t size,
642  const IIx_t i3, const IIx_t i2, const IIx_t i1,
643  const IIx_t i0) const
644  {
645  CH_assert((IxData::ixValidBounds(i3, size)));
646  return IxData::m_ixStride*i3 +
647  m_ixNext.ixIndex1D(IxData::m_ixStride, i2, i1, i0);
648  }
649  USz_t ixIndex1D(const USz_t size,
650  const IIx_t i2, const IIx_t i1, const IIx_t i0) const
651  {
652  CH_assert((IxData::ixValidBounds(i2, size)));
653  return IxData::m_ixStride*i2 +
654  m_ixNext.ixIndex1D(IxData::m_ixStride, i1, i0);
655  }
656  USz_t ixIndex1D(const USz_t size,
657  const IIx_t i1, const IIx_t i0) const
658  {
659  CH_assert((IxData::ixValidBounds(i1, size)));
660  return IxData::m_ixStride*i1 +
661  m_ixNext.ixIndex1D(IxData::m_ixStride, i0);
662  }
663 
664  USz_t ixDimSize(const USz_t size, const unsigned dim) const
665  {
666  return (dim == Rank) ?
667  size/IxData::m_ixStride :
668  m_ixNext.ixDimSize(IxData::m_ixStride, dim);
669  }
670  IIx_t ixLowerBound(const unsigned dim) const
671  {
672  return (dim == Rank) ?
673  IxData::ixLowerBound() :
674  m_ixNext.ixLowerBound(dim);
675  }
676  IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
677  {
678  return (dim == Rank) ?
679  IxData::ixLowerBound() + size/IxData::m_ixStride - 1 :
680  m_ixNext.ixUpperBound(IxData::m_ixStride, dim);
681  }
682 
683  unsigned ixIV(const unsigned i) const
684  {
685  return SpaceDim - 1 - i;
686  }
687 
688 private:
689  RSIndexer<Rank-1, DimT> m_ixNext; ///< Next lower rank
690 };
691 
692 /*--------------------------------------------------------------------*/
693 /// Specialization for Rank 1 (any type of subscript)
694 /*--------------------------------------------------------------------*/
695 
696 template <typename DimT>
697 class RSIndexer<1, DimT> : private IndexerData<1, DimT>
698 {
700 public:
702  : IxData()
703  { }
704 
705  RSIndexer(const IIx_t offset,
706  const DimT &dim0)
707  : IxData(dim0)
708  {
709  IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
710  }
711 
712  void ixDefine(const IIx_t offset,
713  const DimT &dim0)
714  {
715  IxData::ixDefineLowerBound(dim0);
716  IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
717  }
718 
719  USz_t ixIndex1D(const USz_t size,
720  const IIx_t i0) const
721  {
722  CH_assert((IxData::ixValidBounds(i0, size)));
723  return i0 + IxData::ixTotalOffset();
724  }
725 
726  USz_t ixDimSize(const USz_t size, const unsigned dim) const
727  {
728  return size;
729  }
730  IIx_t ixLowerBound(const unsigned dim) const
731  {
732  return IxData::ixLowerBound();
733  }
734  IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
735  {
736  return IxData::ixLowerBound() + size - 1;
737  }
738 
739  unsigned ixIV(const unsigned i) const
740  {
741  return SpaceDim - 1 - i;
742  }
743 };
744 
745 /*--------------------------------------------------------------------*/
746 /// Full specialization for Rank 2 and zero-based subscripts
747 /** Saves the byte required to store the rank1 indexer (which itself
748  * holds no data if DimT=USz_t)
749  *//*-----------------------------------------------------------------*/
750 
751 template <>
752 class RSIndexer<2, USz_t> : private IndexerData<2, USz_t>
753 {
755 public:
757  : IxData()
758  { }
759 
760  RSIndexer(const IIx_t offset,
761  const USz_t &dim1, const USz_t &dim0)
762  : IxData(dim0, dim1)
763  { }
764 
765  void ixDefine(const IIx_t offset,
766  const USz_t &dim1, const USz_t &dim0)
767  {
768  IxData::m_ixStride = dim0;
769  }
770 
771  USz_t ixIndex1D(const USz_t size,
772  const IIx_t i1, const IIx_t i0) const
773  {
774  CH_assert((IxData::ixValidBounds(i1, size)));
775  CH_assert((i0 < IxData::m_ixStride));
776  return IxData::m_ixStride*i1 + i0;
777  }
778 
779  USz_t ixDimSize(const USz_t size, const unsigned dim) const
780  {
781  return (dim == 2) ? size/IxData::m_ixStride :
782  IxData::m_ixStride;
783  }
784  IIx_t ixLowerBound(const unsigned dim) const
785  {
786  return 0;
787  }
788  IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
789  {
790  return ixDimSize(size, dim) - 1;
791  }
792 
793  unsigned ixIV(const unsigned i) const
794  {
795  return SpaceDim - 1 - i;
796  }
797 };
798 //@}
799 
800 /*====================================================================*/
801 /** \name Provides indexing for column ordered (Fortran) storage.
802  *//*=================================================================*/
803 //@{
804 
805 /*--------------------------------------------------------------------*/
806 /// Rank > 2 for zero-based subscripts and > 1 for subscript ranges
807 /*--------------------------------------------------------------------*/
808 
809 template <unsigned Rank, typename DimT>
810 class CSIndexer : private IndexerData<Rank, DimT>
811 {
813 public:
815  : IxData(), m_ixNext()
816  { }
817 
818  CSIndexer(const IIx_t offset,
819  const DimT &dim0, const DimT &dim1, const DimT &dim2,
820  const DimT &dim3, const DimT &dim4, const DimT &dim5,
821  const DimT &dim6)
822  : IxData(dim0*dim1*dim2*dim3*dim4*dim5, dim6),
823  m_ixNext(offset - IxData::ixDimOffset(),
824  dim0, dim1, dim2, dim3, dim4, dim5)
825  { }
826  CSIndexer(const IIx_t offset,
827  const DimT &dim0, const DimT &dim1, const DimT &dim2,
828  const DimT &dim3, const DimT &dim4, const DimT &dim5)
829  : IxData(dim0*dim1*dim2*dim3*dim4, dim5),
830  m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1, dim2, dim3, dim4)
831  { }
832  CSIndexer(const IIx_t offset,
833  const DimT &dim0, const DimT &dim1, const DimT &dim2,
834  const DimT &dim3, const DimT &dim4)
835  : IxData(dim0*dim1*dim2*dim3, dim4),
836  m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1, dim2, dim3)
837  { }
838  CSIndexer(const IIx_t offset,
839  const DimT &dim0, const DimT &dim1, const DimT &dim2,
840  const DimT &dim3)
841  : IxData(dim0*dim1*dim2, dim3),
842  m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1, dim2)
843  { }
844  CSIndexer(const IIx_t offset,
845  const DimT &dim0, const DimT &dim1, const DimT &dim2)
846  : IxData(dim0*dim1, dim2),
847  m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1)
848  { }
849  CSIndexer(const IIx_t offset,
850  const DimT &dim0, const DimT &dim1)
851  : IxData(sizeOfDim(dim0), dim1),
852  m_ixNext(offset - IxData::ixDimOffset(), dim0)
853  { }
854 
855  void ixDefine(const IIx_t offset,
856  const DimT &dim0, const DimT &dim1, const DimT &dim2,
857  const DimT &dim3, const DimT &dim4, const DimT &dim5,
858  const DimT &dim6)
859  {
860  IxData::m_ixStride = dim0*dim1*dim2*dim3*dim4*dim5;
861  IxData::ixDefineLowerBound(dim6);
862  m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
863  dim0, dim1, dim2, dim3, dim4, dim5);
864  }
865  void ixDefine(const IIx_t offset,
866  const DimT &dim0, const DimT &dim1, const DimT &dim2,
867  const DimT &dim3, const DimT &dim4, const DimT &dim5)
868  {
869  IxData::m_ixStride = dim0*dim1*dim2*dim3*dim4;
870  IxData::ixDefineLowerBound(dim5);
871  m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
872  dim0, dim1, dim2, dim3, dim4);
873  }
874  void ixDefine(const IIx_t offset,
875  const DimT &dim0, const DimT &dim1, const DimT &dim2,
876  const DimT &dim3, const DimT &dim4)
877  {
878  IxData::m_ixStride = dim0*dim1*dim2*dim3;
879  IxData::ixDefineLowerBound(dim4);
880  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0, dim1, dim2, dim3);
881  }
882  void ixDefine(const IIx_t offset,
883  const DimT &dim0, const DimT &dim1, const DimT &dim2,
884  const DimT &dim3)
885  {
886  IxData::m_ixStride = dim0*dim1*dim2;
887  IxData::ixDefineLowerBound(dim3);
888  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0, dim1, dim2);
889  }
890  void ixDefine(const IIx_t offset,
891  const DimT &dim0, const DimT &dim1, const DimT &dim2)
892  {
893  IxData::m_ixStride = dim0*dim1;
894  IxData::ixDefineLowerBound(dim2);
895  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0, dim1);
896  }
897  void ixDefine(const IIx_t offset,
898  const DimT &dim0, const DimT &dim1)
899  {
900  IxData::m_ixStride = sizeOfDim(dim0);
901  IxData::ixDefineLowerBound(dim1);
902  m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0);
903  }
904 
905  USz_t ixIndex1D(const USz_t size,
906  const IIx_t i0, const IIx_t i1, const IIx_t i2,
907  const IIx_t i3, const IIx_t i4, const IIx_t i5,
908  const IIx_t i6) const
909  {
910  CH_assert((IxData::ixValidBounds(i6, size)));
911  return IxData::m_ixStride*i6 +
912  m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2, i3, i4, i5);
913  }
914  USz_t ixIndex1D(const USz_t size,
915  const IIx_t i0, const IIx_t i1, const IIx_t i2,
916  const IIx_t i3, const IIx_t i4, const IIx_t i5) const
917  {
918  CH_assert((IxData::ixValidBounds(i5, size)));
919  return IxData::m_ixStride*i5 +
920  m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2, i3, i4);
921  }
922  USz_t ixIndex1D(const USz_t size,
923  const IIx_t i0, const IIx_t i1, const IIx_t i2,
924  const IIx_t i3, const IIx_t i4) const
925  {
926  CH_assert((IxData::ixValidBounds(i4, size)));
927  return IxData::m_ixStride*i4 +
928  m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2, i3);
929  }
930  USz_t ixIndex1D(const USz_t size,
931  const IIx_t i0, const IIx_t i1, const IIx_t i2,
932  const IIx_t i3) const
933  {
934  CH_assert((IxData::ixValidBounds(i3, size)));
935  return IxData::m_ixStride*i3 +
936  m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2);
937  }
938  USz_t ixIndex1D(const USz_t size,
939  const IIx_t i0, const IIx_t i1, const IIx_t i2) const
940  {
941  CH_assert((IxData::ixValidBounds(i2, size)));
942  return IxData::m_ixStride*i2 +
943  m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1);
944  }
945  USz_t ixIndex1D(const USz_t size,
946  const IIx_t i0, const IIx_t i1) const
947  {
948  CH_assert((IxData::ixValidBounds(i1, size)));
949  return IxData::m_ixStride*i1 +
950  m_ixNext.ixIndex1D(IxData::m_ixStride, i0);
951  }
952 
953  USz_t ixDimSize(const USz_t size, const unsigned dim) const
954  {
955  return (dim == Rank) ?
956  size/IxData::m_ixStride :
957  m_ixNext.ixDimSize(IxData::m_ixStride, dim);
958  }
959  IIx_t ixLowerBound(const unsigned dim) const
960  {
961  return (dim == Rank) ?
962  IxData::ixLowerBound() :
963  m_ixNext.ixLowerBound(dim);
964  }
965  IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
966  {
967  return (dim == Rank) ?
968  IxData::ixLowerBound() + size/IxData::m_ixStride - 1 :
969  m_ixNext.ixUpperBound(IxData::m_ixStride, dim);
970  }
971 
972  unsigned ixIV(const unsigned i) const
973  {
974  return i;
975  }
976 
977 private:
978  CSIndexer<Rank-1, DimT> m_ixNext; ///< Next lower rank
979 };
980 
981 /*--------------------------------------------------------------------*/
982 /// Specialization for Rank 1 (any type of subscript)
983 /*--------------------------------------------------------------------*/
984 
985 template <typename DimT>
986 class CSIndexer<1, DimT> : private IndexerData<1, DimT>
987 {
989 public:
991  : IxData()
992  { }
993 
994  CSIndexer(const IIx_t offset,
995  const DimT &dim0)
996  : IxData(dim0)
997  {
998  IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
999  }
1000 
1001  void ixDefine(const IIx_t offset, const DimT &dim0)
1002  {
1003  IxData::ixDefineLowerBound(dim0);
1004  IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
1005  }
1006 
1007  USz_t ixIndex1D(const USz_t size,
1008  const IIx_t i0) const
1009  {
1010  CH_assert((IxData::ixValidBounds(i0, size)));
1011  return i0 + IxData::ixTotalOffset();
1012  }
1013 
1014  USz_t ixDimSize(const USz_t size, const unsigned dim) const
1015  {
1016  return size;
1017  }
1018  IIx_t ixLowerBound(const unsigned dim) const
1019  {
1020  return IxData::ixLowerBound();
1021  }
1022  IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
1023  {
1024  return IxData::ixLowerBound() + size - 1;
1025  }
1026 
1027  unsigned ixIV(const unsigned i) const
1028  {
1029  return i;
1030  }
1031 };
1032 
1033 /*--------------------------------------------------------------------*/
1034 /// Full specialization for Rank 2 and zero-based subscripts
1035 /** Saves the byte required to store the rank1 indexer (which itself
1036  * holds no data if DimT=USz_t)
1037  *//*-----------------------------------------------------------------*/
1038 
1039 template <>
1040 class CSIndexer<2, USz_t> : private IndexerData<2, USz_t>
1041 {
1043 public:
1045  : IxData()
1046  { }
1047 
1048  CSIndexer(const IIx_t offset,
1049  const USz_t dim0, const USz_t dim1)
1050  : IxData(dim0, dim1)
1051  { }
1052 
1053  void ixDefine(const IIx_t offset,
1054  const USz_t dim0, const USz_t dim1)
1055  {
1056  IxData::m_ixStride = dim0;
1057  }
1058 
1059  USz_t ixIndex1D(const USz_t size,
1060  const IIx_t i0, const IIx_t i1) const
1061  {
1062  CH_assert((IxData::ixValidBounds(i1, size)));
1063  CH_assert((i0 < IxData::m_ixStride));
1064  return IxData::m_ixStride*i1 + i0;
1065  }
1066 
1067  IIx_t ixDimSize(const USz_t size, const unsigned dim) const
1068  {
1069  return (dim == 2) ? size/IxData::m_ixStride :
1070  IxData::m_ixStride;
1071  }
1072  IIx_t ixLowerBound(const unsigned dim) const
1073  {
1074  return 0;
1075  }
1076  IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
1077  {
1078  return ixDimSize(size, dim) - 1;
1079  }
1080 
1081  unsigned ixIV(const unsigned i) const
1082  {
1083  return i;
1084  }
1085 };
1086 //@}
1087 
1088 /*====================================================================*/
1089 /** \name Array configuration. Select types based on 'ArConf'
1090  *//*=================================================================*/
1091 //@{
1092 
1093 template <unsigned Rank, int ArConf>
1094 struct ArTr;
1095 template <unsigned Rank>
1096 struct ArTr<Rank, ArZeroRow>
1097 {
1100 };
1101 template <unsigned Rank>
1102 struct ArTr<Rank, ArZeroCol>
1103 {
1106 };
1107 template <unsigned Rank>
1108 struct ArTr<Rank, ArRangeRow>
1109 {
1110  typedef CHRange DimT;
1112  typedef int BoxAllowed;
1113 };
1114 template <unsigned Rank>
1115 struct ArTr<Rank, ArRangeCol>
1116 {
1117  typedef CHRange DimT;
1119  typedef int BoxAllowed;
1120 };
1121 //@}
1122 
1123 } // End of namespace ArSp
1124 
1125 /*******************************************************************************
1126  */
1127 /// Multidimensional array class
1128 /**
1129  * \tparam T Type of element
1130  * \tparam Rank Rank of the array
1131  * \tparam ArConf Configuration of the indexing. Allowable values are:
1132  * ArZeroRow - Row-ordered indexing with lower bound = 0
1133  * ArZeroCol - Column-ordered indexing with lower
1134  * bound = 0 (DEFAULT)
1135  * ArRangeRow - Row-ordered indexing with subscript ranges
1136  * ArRangeCol - Column-ordered indexing with subscript
1137  * ranges
1138  * \tparam Alloc Allocator for the array
1139  *
1140  * \note
1141  * <ul>
1142  * <li> Default template arguments specify column-ordered arrays since it
1143  * is expected that this class will be mostly used as storage for
1144  * data used in Fortran routines.
1145  * <li> When an assertion fails, note that the indexers label the contiguous
1146  * dimension as i0 or dim0 and the others from there. This class
1147  * labels all dimensions assuming row-ordered (C) storage.
1148  * <li> Currently supports up to rank 7, matching the maximum permitted by
1149  * the Fortran 2003 standard (the 2008 standard extends this to 15 and
1150  * this class will be extended once that is commonplace). With
1151  * IntVects or Boxes used to specify some of the dimensions, 2 extra
1152  * dimensions are supported, allowing a matrix in each cell. This
1153  * implies a rank of SpaceDim+2 so you can only add 1 extra dimension
1154  * if you want to support SpaceDim=6.
1155  * <li> Empty base-class optimizations are frequently used. On 32-bit arch,
1156  * sizeof(CHArray<int, 1, ArZeroRow, ArSp::NewArrayAlloc<int> >) = 8
1157  * sizeof(CHArray<int, 2, ArZeroRow, ArSp::NewArrayAlloc<int> >) = 12
1158  * <li> There is support for passing these arrays to Fortran -- see Chombo
1159  * design doc
1160  * <li> CHMatrix will define a real, rank 2, column-ordered matrix
1161  * <li> You can also allocate an array of matrices, continguous in memory,
1162  * using the ArrayOfMatrixAlloc allocator.
1163  * </ul>
1164  *
1165  * Example \verbatim
1166  *
1167  * CHArray<int, 3> A(2, 2, 2);
1168  * A = 2;
1169  * A(0, 0, 0) = 4;
1170  * std::cout << A << std::endl;
1171  * CHArray<double, 2> B;
1172  * B.define(3, 4);
1173  * B(2, 3) = 5.5;
1174  * \endverbatim
1175  * One can also use subscript ranges but the array has to be configured to
1176  * support this. Ranges are specified with CHRange in place of a size. Any
1177  * integer types are converted to CHRange(0, int-1). E.g.,
1178  * \verbatim
1179  * CHArray<int, 3, ArRangeRow> C(CHRange(-1,0), 2, 2);
1180  * C = 2;
1181  * C(-1, 0, 0) = 4;
1182  * \endverbatim
1183  * IntVects are allowed for specifying some of the dimensions so that this
1184  * class can be used with boxes, e.g: \verbatim
1185  *
1186  * CHArray<int, SpaceDim+1> A(box.size(), 1)
1187  * \endverbatim
1188  * The indices of the IntVect are rearranged so that the first index is always
1189  * closest to contiguous memory no matter if the actual memory layout is row-
1190  * ordered or column-ordered. In other words, the first index of the IntVect
1191  * always has the lowest stride. As such, the allocated memory can be
1192  * accessed by iterating over the box in Chombo Fortran. Whether the
1193  * remaining indices (or components) are left or right of the IntVect and the
1194  * storage order determine if the components are distributed across the
1195  * IntVects (like with a BaseFab) or are contiguous in each IntVect. The
1196  * effect is natural; for row storage, components on the right will lead to
1197  * contigous memory. E.g.,
1198  * \verbatim
1199  * typedef CHArray<int, SpaceDim+1, ArZeroRow> CHArrayRS;
1200  * typedef CHArray<int, SpaceDim+1, ArZeroCol> CHArrayCS;
1201  * const IntVect iv(2, 2);
1202  * CHArrayRS ARS_IVComp(iv, 2);
1203  * CHArrayRS ARS_CompIV(2, iv);
1204  * CHArrayCS ACS_IVComp(iv, 2);
1205  * CHArrayCS ACS_CompIV(2, iv);
1206  * int ic = 1;
1207  * for (int j = 0; j != 2; ++j)
1208  * for (int i = 0; i != 2; ++i) // Column storage!
1209  * {
1210  * const IntVect ixv(i, j);
1211  * ARS_IVComp(ixv, 0) = ic;
1212  * ARS_IVComp(ixv, 1) = -ic;
1213  * ARS_CompIV(0, ixv) = ic;
1214  * ARS_CompIV(1, ixv) = -ic;
1215  * ACS_IVComp(ixv, 0) = ic;
1216  * ACS_IVComp(ixv, 1) = -ic;
1217  * ACS_CompIV(0, ixv) = ic;
1218  * ACS_CompIV(1, ixv) = -ic;
1219  * ++ic;
1220  * }
1221  *
1222  * std::cout << "ARS_IVComp: " << ARS_IVComp << std::endl;
1223  * std::cout << "ARS_CompIV: " << ARS_CompIV << std::endl;
1224  * std::cout << "ACS_IVComp: " << ACS_IVComp << std::endl;
1225  * std::cout << "ACS_CompIV: " << ACS_CompIV << std::endl;
1226  * \endverbatim
1227  * will produce
1228  * \verbatim
1229  * $ ARS_IVComp: 1 -1 2 -2 3 -3 4 -4
1230  * $ ARS_CompIV: 1 2 3 4 -1 -2 -3 -4
1231  * $ ACS_IVComp: 1 2 3 4 -1 -2 -3 -4
1232  * $ ACS_CompIV: 1 -1 2 -2 3 -3 4 -4
1233  * \endverbatim
1234  * Note that the IntVects simply expand to dimensions and there is nothing to
1235  * ensure that you access in the array in the same manner you defined it
1236  * (i.e., switching the order of the IntVect and the component)!
1237  *
1238  * IntVects are always zero-based and there is no way to specify a range of
1239  * IntVects. However, one can use Boxes instead of IntVects to define the
1240  * array but only if the array is configured with subscript ranges
1241  * (ArConf = ArRangeRow or ArRangeCol)
1242  * \verbatim
1243  * Box box(IntVect(-1,-1), IntVect(1, 1));
1244  * CHArray<int, SpaceDim+1, ArRangeRow> AB(box, 2);
1245  * AB = 1;
1246  * AB(IntVect(-1, -1), 0) = 2;
1247  * std::cout << AB << std::endl;
1248  * \endverbatim
1249  *
1250  ******************************************************************************/
1251 
1252 template <typename T,
1253  unsigned Rank,
1254  int ArConf, // Default ArZeroCol
1255  typename Alloc> // Default ArSp::DefaultArrayAlloc<T>
1256 class CHArray : private ArSp::ArTr<Rank, ArConf>::IndexerT
1257 {
1260 public:
1261 
1262  /// Default constructor
1264  : Indexer(), m_arrayImpl()
1265  { }
1266 
1267  /// Construct with dimensions
1268  CHArray(const DimT &dim6, const DimT &dim5, const DimT &dim4,
1269  const DimT &dim3, const DimT &dim2, const DimT &dim1,
1270  const DimT &dim0)
1271  : Indexer(0, dim6, dim5, dim4, dim3, dim2, dim1, dim0),
1272  m_arrayImpl(dim6*dim5*dim4*dim3*dim2*dim1*dim0)
1273  { }
1274  CHArray(const DimT &dim5, const DimT &dim4, const DimT &dim3,
1275  const DimT &dim2, const DimT &dim1, const DimT &dim0)
1276  : Indexer(0, dim5, dim4, dim3, dim2, dim1, dim0),
1277  m_arrayImpl(dim5*dim4*dim3*dim2*dim1*dim0)
1278  { }
1279  CHArray(const DimT &dim4, const DimT &dim3, const DimT &dim2,
1280  const DimT &dim1, const DimT &dim0)
1281  : Indexer(0, dim4, dim3, dim2, dim1, dim0),
1282  m_arrayImpl(dim4*dim3*dim2*dim1*dim0)
1283  { }
1284  CHArray(const DimT &dim3, const DimT &dim2, const DimT &dim1,
1285  const DimT &dim0)
1286  : Indexer(0, dim3, dim2, dim1, dim0), m_arrayImpl(dim3*dim2*dim1*dim0)
1287  { }
1288  CHArray(const DimT &dim2, const DimT &dim1, const DimT &dim0)
1289  : Indexer(0, dim2, dim1, dim0), m_arrayImpl(dim2*dim1*dim0)
1290  { }
1291  CHArray(const DimT &dim1, const DimT &dim0)
1292  : Indexer(0, dim1, dim0), m_arrayImpl(dim1*dim0)
1293  { }
1294  CHArray(const DimT &dim0)
1295  : Indexer(0, dim0), m_arrayImpl(ArSp::sizeOfDim(dim0))
1296  { }
1297  // With IntVect
1298  CHArray(const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
1299  : Indexer(0, D_DEFIV, dimc1, dimc0), m_arrayImpl(iv.product()*dimc1*dimc0)
1300  { }
1301  CHArray(const IntVect &iv, const DimT &dimc0)
1302  : Indexer(0, D_DEFIV, dimc0), m_arrayImpl(iv.product()*dimc0)
1303  { }
1304  CHArray(const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
1305  : Indexer(0, dimc1, dimc0, D_DEFIV), m_arrayImpl(dimc1*dimc0*iv.product())
1306  { }
1307  CHArray(const DimT &dimc0, const IntVect &iv)
1308  : Indexer(0, dimc0, D_DEFIV), m_arrayImpl(dimc0*iv.product())
1309  { }
1310  // With Box
1311  CHArray(const Box &box, const DimT &dimc1, const DimT &dimc0)
1312  : Indexer(0, D_DEFBOX, dimc1, dimc0),
1313  m_arrayImpl(box.size().product()*dimc1*dimc0)
1314  {
1315  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1316  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1317  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1318  }
1319  CHArray(const Box &box, const DimT &dimc0)
1320  : Indexer(0, D_DEFBOX, dimc0), m_arrayImpl(box.size().product()*dimc0)
1321  {
1322  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1323  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1324  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1325  }
1326  CHArray(const DimT &dimc1, const DimT &dimc0, const Box &box)
1327  : Indexer(0, dimc1, dimc0, D_DEFBOX),
1328  m_arrayImpl(dimc1*dimc0*box.size().product())
1329  {
1330  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1331  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1332  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1333  }
1334  CHArray(const DimT &dimc0, const Box &box)
1335  : Indexer(0, dimc0, D_DEFBOX), m_arrayImpl(dimc0*box.size().product())
1336  {
1337  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1338  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1339  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1340  }
1341 
1342  /// Define the dimensions
1343  void define(const DimT &dim6, const DimT &dim5, const DimT &dim4,
1344  const DimT &dim3, const DimT &dim2, const DimT &dim1,
1345  const DimT &dim0)
1346  {
1347  Indexer::ixDefine(0, dim6, dim5, dim4, dim3, dim2, dim1, dim0);
1348  m_arrayImpl.define(dim6*dim5*dim4*dim3*dim2*dim1*dim0);
1349  }
1350  void define(const DimT &dim5, const DimT &dim4, const DimT &dim3,
1351  const DimT &dim2, const DimT &dim1, const DimT &dim0)
1352  {
1353  Indexer::ixDefine(0, dim5, dim4, dim3, dim2, dim1, dim0);
1354  m_arrayImpl.define(dim5*dim4*dim3*dim2*dim1*dim0);
1355  }
1356  void define(const DimT &dim4, const DimT &dim3, const DimT &dim2,
1357  const DimT &dim1, const DimT &dim0)
1358  {
1359  Indexer::ixDefine(0, dim4, dim3, dim2, dim1, dim0);
1360  m_arrayImpl.define(dim4*dim3*dim2*dim1*dim0);
1361  }
1362  void define(const DimT &dim3, const DimT &dim2, const DimT &dim1,
1363  const DimT &dim0)
1364  {
1365  Indexer::ixDefine(0, dim3, dim2, dim1, dim0);
1366  m_arrayImpl.define(dim3*dim2*dim1*dim0);
1367  }
1368  void define(const DimT &dim2, const DimT &dim1, const DimT &dim0)
1369  {
1370  Indexer::ixDefine(0, dim2, dim1, dim0);
1371  m_arrayImpl.define(dim2*dim1*dim0);
1372  }
1373  void define(const DimT &dim1, const DimT &dim0)
1374  {
1375  Indexer::ixDefine(0, dim1, dim0);
1376  m_arrayImpl.define(dim1*dim0);
1377  }
1378  void define(const DimT &dim0)
1379  {
1380  Indexer::ixDefine(0, dim0);
1381  m_arrayImpl.define(ArSp::sizeOfDim(dim0));
1382  }
1383  // With IntVect
1384  void define(const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
1385  {
1386  Indexer::ixDefine(0, D_DEFIV, dimc1, dimc0);
1387  m_arrayImpl.define(iv.product()*dimc1*dimc0);
1388  }
1389  void define(const IntVect &iv, const DimT &dimc0)
1390  {
1391  Indexer::ixDefine(0, D_DEFIV, dimc0);
1392  m_arrayImpl.define(iv.product()*dimc0);
1393  }
1394  void define(const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
1395  {
1396  Indexer::ixDefine(0, dimc1, dimc0, D_DEFIV);
1397  m_arrayImpl.define(dimc1*dimc0*iv.product());
1398  }
1399  void define(const DimT &dimc0, const IntVect &iv)
1400  {
1401  Indexer::ixDefine(0, dimc0, D_DEFIV);
1402  m_arrayImpl.define(dimc0*iv.product());
1403  }
1404  // With Box
1405  void define(const Box &box, const DimT &dimc1, const DimT &dimc0)
1406  {
1407  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1408  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1409  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1410  Indexer::ixDefine(0, D_DEFBOX, dimc1, dimc0);
1411  m_arrayImpl.define(box.size().product()*dimc1*dimc0);
1412  }
1413  void define(const Box &box, const DimT &dimc0)
1414  {
1415  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1416  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1417  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1418  Indexer::ixDefine(0, D_DEFBOX, dimc0);
1419  m_arrayImpl.define(box.size().product()*dimc0);
1420  }
1421  void define(const DimT &dimc1, const DimT &dimc0, const Box &box)
1422  {
1423  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1424  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1425  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1426  Indexer::ixDefine(0, dimc1, dimc0, D_DEFBOX);
1427  m_arrayImpl.define(dimc1*dimc0*box.size().product());
1428  }
1429  void define(const DimT &dimc0, const Box &box)
1430  {
1431  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1432  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1433  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1434  Indexer::ixDefine(0, dimc0, D_DEFBOX);
1435  m_arrayImpl.define(dimc0*box.size().product());
1436  }
1437 
1438  /// Define the dimensions and allocate on 'addr'
1439  void define(void *const addr,
1440  const DimT &dim6, const DimT &dim5, const DimT &dim4,
1441  const DimT &dim3, const DimT &dim2, const DimT &dim1,
1442  const DimT &dim0)
1443  {
1444  Indexer::ixDefine(0, dim6, dim5, dim4, dim3, dim2, dim1, dim0);
1445  m_arrayImpl.define(addr, dim6*dim5*dim4*dim3*dim2*dim1*dim0);
1446  }
1447  void define(void *const addr,
1448  const DimT &dim5, const DimT &dim4, const DimT &dim3,
1449  const DimT &dim2, const DimT &dim1, const DimT &dim0)
1450  {
1451  Indexer::ixDefine(0, dim5, dim4, dim3, dim2, dim1, dim0);
1452  m_arrayImpl.define(addr, dim5*dim4*dim3*dim2*dim1*dim0);
1453  }
1454  void define(void *const addr,
1455  const DimT &dim4, const DimT &dim3, const DimT &dim2,
1456  const DimT &dim1, const DimT &dim0)
1457  {
1458  Indexer::ixDefine(0, dim4, dim3, dim2, dim1, dim0);
1459  m_arrayImpl.define(addr, dim4*dim3*dim2*dim1*dim0);
1460  }
1461  void define(void *const addr,
1462  const DimT &dim3, const DimT &dim2, const DimT &dim1,
1463  const DimT &dim0)
1464  {
1465  Indexer::ixDefine(0, dim3, dim2, dim1, dim0);
1466  m_arrayImpl.define(addr, dim3*dim2*dim1*dim0);
1467  }
1468  void define(void *const addr,
1469  const DimT &dim2, const DimT &dim1, const DimT &dim0)
1470  {
1471  Indexer::ixDefine(0, dim2, dim1, dim0);
1472  m_arrayImpl.define(addr, dim2*dim1*dim0);
1473  }
1474  void define(void *const addr,
1475  const DimT &dim1, const DimT &dim0)
1476  {
1477  Indexer::ixDefine(0, dim1, dim0);
1478  m_arrayImpl.define(addr, dim1*dim0);
1479  }
1480  void define(void *const addr,
1481  const DimT &dim0)
1482  {
1483  Indexer::ixDefine(0, dim0);
1484  m_arrayImpl.define(addr, ArSp::sizeOfDim(dim0));
1485  }
1486  // With IntVect
1487  void define(void *const addr, const IntVect &iv,
1488  const DimT &dimc1, const DimT &dimc0)
1489  {
1490  Indexer::ixDefine(0, D_DEFIV, dimc1, dimc0);
1491  m_arrayImpl.define(addr, iv.product()*dimc1*dimc0);
1492  }
1493  void define(void *const addr, const IntVect &iv, const DimT &dimc0)
1494  {
1495  Indexer::ixDefine(0, D_DEFIV, dimc0);
1496  m_arrayImpl.define(addr, iv.product()*dimc0);
1497  }
1498  void define(void *const addr, const DimT &dimc1, const DimT &dimc0,
1499  const IntVect &iv)
1500  {
1501  Indexer::ixDefine(0, dimc1, dimc0, D_DEFIV);
1502  m_arrayImpl.define(addr, dimc1*dimc0*iv.product());
1503  }
1504  void define(void *const addr, const DimT &dimc0, const IntVect &iv)
1505  {
1506  Indexer::ixDefine(0, dimc0, D_DEFIV);
1507  m_arrayImpl.define(addr, dimc0*iv.product());
1508  }
1509  // With Box
1510  void define(void *const addr, const Box &box,
1511  const DimT &dimc1, const DimT &dimc0)
1512  {
1513  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1514  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1515  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1516  Indexer::ixDefine(0, D_DEFBOX, dimc1, dimc0);
1517  m_arrayImpl.define(addr, box.size().product()*dimc1*dimc0);
1518  }
1519  void define(void *const addr, const Box &box, const DimT &dimc0)
1520  {
1521  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1522  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1523  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1524  Indexer::ixDefine(0, D_DEFBOX, dimc0);
1525  m_arrayImpl.define(addr, box.size().product()*dimc0);
1526  }
1527  void define(void *const addr, const DimT &dimc1, const DimT &dimc0,
1528  const Box &box)
1529  {
1530  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1531  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1532  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1533  Indexer::ixDefine(0, dimc1, dimc0, D_DEFBOX);
1534  m_arrayImpl.define(addr, dimc1*dimc0*box.size().product());
1535  }
1536  void define(void *const addr, const DimT &dimc0, const Box &box)
1537  {
1538  // Any error with "BoxAllowed" means you are not allowed to use boxes with
1539  // zero-based lower bounds. Use ArConf=ArRangeRow or ArConf=ArRangeCol.
1540  typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
1541  Indexer::ixDefine(0, dimc0, D_DEFBOX);
1542  m_arrayImpl.define(addr, dimc0*box.size().product());
1543  }
1544 
1545  /// Deallocate the array
1546  void undefine()
1547  {
1548  CH_assert(isAllocated());
1549  m_arrayImpl.undefine();
1550  }
1551 
1552  /// Assign a constant to the array
1553  template <typename T2>
1554  CHArray &operator=(const T2 &val)
1555  {
1556  CH_assert(isAllocated());
1557  T Tval = val;
1558  const T *const pEnd = end();
1559  for (T *p = begin(); p != pEnd;) *p++ = Tval;
1560  return *this;
1561  }
1562 
1563  /// Access an element
1564  T &operator()(const ArSp::IIx_t i6, const ArSp::IIx_t i5,
1565  const ArSp::IIx_t i4, const ArSp::IIx_t i3,
1566  const ArSp::IIx_t i2, const ArSp::IIx_t i1,
1567  const ArSp::IIx_t i0)
1568  {
1569  CH_assert(isUsable());
1570  return m_arrayImpl.data[
1571  Indexer::ixIndex1D(size(), i6, i5, i4, i3, i2, i1, i0)];
1572  }
1573  T &operator()(const ArSp::IIx_t i5, const ArSp::IIx_t i4,
1574  const ArSp::IIx_t i3, const ArSp::IIx_t i2,
1575  const ArSp::IIx_t i1, const ArSp::IIx_t i0)
1576  {
1577  CH_assert(isUsable());
1578  return m_arrayImpl.data[
1579  Indexer::ixIndex1D(size(), i5, i4, i3, i2, i1, i0)];
1580  }
1581  T &operator()(const ArSp::IIx_t i4, const ArSp::IIx_t i3,
1582  const ArSp::IIx_t i2, const ArSp::IIx_t i1,
1583  const ArSp::IIx_t i0)
1584  {
1585  CH_assert(isUsable());
1586  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i4, i3, i2, i1, i0)];
1587  }
1588  T &operator()(const ArSp::IIx_t i3, const ArSp::IIx_t i2,
1589  const ArSp::IIx_t i1, const ArSp::IIx_t i0)
1590  {
1591  CH_assert(isUsable());
1592  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i3, i2, i1, i0)];
1593  }
1594  T &operator()(const ArSp::IIx_t i2, const ArSp::IIx_t i1,
1595  const ArSp::IIx_t i0)
1596  {
1597  CH_assert(isUsable());
1598  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i2, i1, i0)];
1599  }
1600  T &operator()(const ArSp::IIx_t i1, const ArSp::IIx_t i0)
1601  {
1602  CH_assert(isUsable());
1603  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i1, i0)];
1604  }
1606  {
1607  CH_assert(isUsable());
1608  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i0)];
1609  }
1610  T &operator()(const IntVect& iv, const ArSp::IIx_t c1, const ArSp::IIx_t c0)
1611  {
1612  CH_assert(isUsable());
1613  return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c1, c0)];
1614  }
1615  T &operator()(const IntVect& iv, const ArSp::IIx_t c0)
1616  {
1617  CH_assert(isUsable());
1618  return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c0)];
1619  }
1620  T &operator()(const ArSp::IIx_t c1, const ArSp::IIx_t c0, const IntVect& iv)
1621  {
1622  CH_assert(isUsable());
1623  return m_arrayImpl.data[Indexer::ixIndex1D(size(), c1, c0, D_IXIV)];
1624  }
1625  T &operator()(const ArSp::IIx_t c0, const IntVect& iv)
1626  {
1627  CH_assert(isUsable());
1628  return m_arrayImpl.data[Indexer::ixIndex1D(size(), c0, D_IXIV)];
1629  }
1630 
1631  /// Constant access to an element
1632  const T &operator()(const ArSp::IIx_t i6, const ArSp::IIx_t i5,
1633  const ArSp::IIx_t i4, const ArSp::IIx_t i3,
1634  const ArSp::IIx_t i2, const ArSp::IIx_t i1,
1635  const ArSp::IIx_t i0) const
1636  {
1637  CH_assert(isUsable());
1638  return m_arrayImpl.data[
1639  Indexer::ixIndex1D(size(), i6, i5, i4, i3, i2, i1, i0)];
1640  }
1641  const T &operator()(const ArSp::IIx_t i5, const ArSp::IIx_t i4,
1642  const ArSp::IIx_t i3, const ArSp::IIx_t i2,
1643  const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
1644  {
1645  CH_assert(isUsable());
1646  return m_arrayImpl.data[
1647  Indexer::ixIndex1D(size(), i5, i4, i3, i2, i1, i0)];
1648  }
1649  const T &operator()(const ArSp::IIx_t i4, const ArSp::IIx_t i3,
1650  const ArSp::IIx_t i2, const ArSp::IIx_t i1,
1651  const ArSp::IIx_t i0) const
1652  {
1653  CH_assert(isUsable());
1654  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i4, i3, i2, i1, i0)];
1655  }
1656  const T &operator()(const ArSp::IIx_t i3, const ArSp::IIx_t i2,
1657  const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
1658  {
1659  CH_assert(isUsable());
1660  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i3, i2, i1, i0)];
1661  }
1662  const T &operator()(const ArSp::IIx_t i2, const ArSp::IIx_t i1,
1663  const ArSp::IIx_t i0) const
1664  {
1665  CH_assert(isUsable());
1666  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i2, i1, i0)];
1667  }
1668  const T &operator()(const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
1669  {
1670  CH_assert(isUsable());
1671  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i1, i0)];
1672  }
1673  const T &operator()(const ArSp::IIx_t i0) const
1674  {
1675  CH_assert(isUsable());
1676  return m_arrayImpl.data[Indexer::ixIndex1D(size(), i0)];
1677  }
1678  const T &operator()(const IntVect& iv,
1679  const ArSp::IIx_t c1, const ArSp::IIx_t c0) const
1680  {
1681  CH_assert(isUsable());
1682  return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c1, c0)];
1683  }
1684  const T &operator()(const IntVect& iv, const ArSp::IIx_t c0) const
1685  {
1686  CH_assert(isUsable());
1687  return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c0)];
1688  }
1689  const T &operator()(const ArSp::IIx_t c1, const ArSp::IIx_t c0,
1690  const IntVect& iv) const
1691  {
1692  CH_assert(isUsable());
1693  return m_arrayImpl.data[Indexer::ixIndex1D(size(), c1, c0, D_IXIV)];
1694  }
1695  const T &operator()(const ArSp::IIx_t c0, const IntVect& iv) const
1696  {
1697  CH_assert(isUsable());
1698  return m_arrayImpl.data[Indexer::ixIndex1D(size(), c0, D_IXIV)];
1699  }
1700 
1701  /// Get the allocator
1702  Alloc& getAllocator()
1703  {
1704  return *static_cast<Alloc*>(&m_arrayImpl);
1705  }
1706 
1707  /// Access extents of the memory allocated for the array
1708  T* begin()
1709  {
1710  return m_arrayImpl.data;
1711  }
1712  const T* begin() const
1713  {
1714  return m_arrayImpl.data;
1715  }
1716  T* end()
1717  {
1718  return m_arrayImpl.data + size();
1719  }
1720  const T* end() const
1721  {
1722  return m_arrayImpl.data + size();
1723  }
1724 
1725  /// Overall size of the array
1727  {
1728  return m_arrayImpl.size;
1729  }
1730 
1731  /// Size of a dimension (0 is dimension with contiguous storage)
1732  ArSp::USz_t size(const unsigned dim) const
1733  {
1734  CH_assert(isUsable());
1735  CH_assert(dim < Rank);
1736  return Indexer::ixDimSize(size(), dim+1);
1737  }
1738 
1739  /// Lower bound of a dimension (0 is dimension with contiguous storage)
1740  ArSp::IIx_t lowerBound(const unsigned dim) const
1741  {
1742  CH_assert(isUsable());
1743  CH_assert(dim < Rank);
1744  return Indexer::ixLowerBound(dim+1);
1745  }
1746 
1747  /// Upper bound of a dimension (0 is dimension with contiguous storage)
1748  ArSp::IIx_t upperBound(const unsigned dim) const
1749  {
1750  CH_assert(isUsable());
1751  CH_assert(dim < Rank);
1752  return Indexer::ixUpperBound(size(), dim+1);
1753  }
1754 
1755  /// Memory has been allocated
1756  bool isAllocated() const
1757  {
1758  return (m_arrayImpl.data != 0);
1759  }
1760 
1761  /// Memory has been allocated and size is > 0
1762  bool isUsable() const
1763  {
1764  return isAllocated() && size() > 0;
1765  }
1766 
1767 private:
1768 
1769  CHArray(const CHArray&);
1770  CHArray &operator=(const CHArray&);
1771 
1772  struct Array_impl : public Alloc
1773  {
1775  : size(0), data(0)
1776  { }
1777  Array_impl(const ArSp::USz_t a_size)
1778  : size(a_size), data(0)
1779  {
1780  data = Alloc::allocate(size);
1781  }
1783  {
1784  if (data != 0) undefine();
1785  }
1786  void define(const ArSp::USz_t a_size)
1787  {
1788  if (data != 0) undefine();
1789  size = a_size;
1790  data = Alloc::allocate(size);
1791  }
1792  void define(void *const addr, const ArSp::USz_t a_size)
1793  {
1794  if (data != 0) undefine();
1795  size = a_size;
1796  data = Alloc::allocate(addr, size);
1797  }
1798  void undefine()
1799  {
1800  Alloc::deallocate(data, size);
1801  data = 0;
1802  size = 0;
1803  }
1804  ArSp::USz_t size; ///< Overall size of the array
1805  T *data; ///< Data for the array
1806  };
1807 
1808  Array_impl m_arrayImpl; ///< Data + allocation/deallocation
1809 };
1810 
1811 /// Vector definition
1813 
1814 /// Matrix defined with column-ordered storage
1816 
1817 /// Output of an array
1818 template<typename T, unsigned Rank, int ArConf, typename Alloc>
1819 std::ostream &operator<<(std::ostream &os,
1821 {
1822  CH_assert(A.isAllocated());
1823  const T *p = A.begin();
1824  const T *const pEnd = A.end();
1825  if (p != pEnd) os << *p++;
1826  while (p != pEnd) os << ' ' << *p++;
1827  return os;
1828 }
1829 
1830 /// Pretty output of a matrix (should be in .cpp)
1831 template<>
1832 inline std::ostream &operator<<(std::ostream &os, const CHMatrix &M)
1833 {
1834  CH_assert(M.isAllocated());
1835  const int prec = 2;
1836  os.setf(std::ios_base::scientific, std::ios_base::floatfield);
1837  os.precision(prec);
1838  const ArSp::USz_t iMax = M.size(0);
1839  const ArSp::USz_t jMax = M.size(1);
1840  for (ArSp::USz_t i = 0; i != iMax; ++i)
1841  {
1842  if (jMax > 0)
1843  {
1844  os << std::setw(prec+7) << M(i, 0);
1845  for (ArSp::USz_t j = 1; j != jMax; ++j)
1846  {
1847  os << ' ' << std::setw(prec+7) << M(i, j);
1848  }
1849  os << std::endl;
1850  }
1851  }
1852  os.setf(std::ios_base::fmtflags(0), std::ios_base::floatfield);
1853  os.precision(6);
1854  return os;
1855 }
1856 
1857 namespace ArSp
1858 {
1859 
1860 /*====================================================================*/
1861 /** \name Special allocators
1862  *//*=================================================================*/
1863 //@{
1864 
1865 /*--------------------------------------------------------------------*/
1866 /// Allocator that only permits allocation by new
1867 /** Use of CHArray::define(void *const addr, ...) will cause an error
1868  *//*-----------------------------------------------------------------*/
1869 
1870 template <typename T>
1872 {
1873 public:
1874  T* allocate(const USz_t size)
1875  {
1876  T *const p = new(std::nothrow) T[size];
1877  CH_assert(p != 0);
1878  return p;
1879  }
1880 
1881  void deallocate(T *p, const USz_t size)
1882  {
1883  delete[] p;
1884  }
1885 };
1886 
1887 /*--------------------------------------------------------------------*/
1888 /// Allocator for an array of matrices contiguous in memory
1889 /** Useful for allocating an array of matrices which can be easily
1890  * passed to Fortran, etc.
1891  *
1892  * Example - 1D Array of 2 3x3 matrices \verbatim
1893  *
1894  * CHArray<CHMatrix, 1, ArZeroRow, ArSp::ArrayOfMatrixAlloc> AM;
1895  * AM.getAllocator().define(3, 3);
1896  * AM.define(2);
1897  * AM(0) = 1.1;
1898  * AM(1) = 1.9;
1899  * std::cout << AM << std::endl;
1900  * \endverbatim
1901  *//*-----------------------------------------------------------------*/
1902 
1904 {
1905  public:
1907  : defined(false)
1908  { }
1909  void define(const USz_t a_m, const USz_t a_n)
1910  {
1911  m = a_m;
1912  n = a_n;
1913  defined = true;
1914  }
1915  CHMatrix* allocate(const USz_t size)
1916  {
1917  CH_assert(defined);
1918  CHMatrix *const M = new(std::nothrow) CHMatrix[size];
1919  CH_assert(M != 0);
1920  const USz_t stride = m*n;
1921  matrixData = new(std::nothrow) Real[size*stride];
1922  CH_assert(matrixData != 0);
1923  for (USz_t i = 0; i != size; ++i)
1924  {
1925  M[i].define(matrixData + i*stride, m, n);
1926  }
1927  return M;
1928  }
1929  void deallocate(CHMatrix *p, const USz_t size)
1930  {
1931  delete[] p;
1932  delete[] matrixData;
1933  }
1934 private:
1938  bool defined;
1939 };
1940 //@}
1941 } // End of namespace ArSp
1942 
1943 //--Row ordered speed test
1944 
1945 // StopWatchLinux sw1;
1946 // CHArray<int, 3, ArZeroRow> AR1;
1947 // const unsigned nr = 200;
1948 // AR1.define(nr, nr, nr);
1949 // AR1 = 1;
1950 // sw1.start();
1951 // for (int i = 1; i != nr; ++i)
1952 // for (int j = 0; j != nr; ++j)
1953 // for (int k = 0; k != nr; ++k)
1954 // AR1(i, j, k) += AR1(i-1, j, k);
1955 // sw1.stop();
1956 // std::cout << AR1((int)AR1(1, 0, 0), (int)AR1(0, 1, 0), (int)AR1(0, 0, 1))
1957 // << std::endl;
1958 // std::cout << "Time: " << sw1.getTime() << std::endl;
1959 
1960 //--Column ordered speed test
1961 
1962 // StopWatchLinux sw2;
1963 // CHArray<int, 3, ArZeroCol> AC1;
1964 // const unsigned nc = 200;
1965 // AC1.define(nc, nc, nc);
1966 // AC1 = 1;
1967 // sw2.start();
1968 // for (int i = 1; i != nc; ++i)
1969 // for (int j = 0; j != nc; ++j)
1970 // for (int k = 0; k != nc; ++k)
1971 // AC1(k, j, i) += AC1(k, j, i-1);
1972 // sw2.stop();
1973 // std::cout << AC1((int)AC1(1, 0, 0), (int)AC1(0, 1, 0), (int)AC1(0, 0, 1))
1974 // << std::endl;
1975 // std::cout << "Time: " << sw2.getTime() << std::endl;
1976 
1977 #ifdef CH_SPACEDIM
1978  #include "NamespaceFooter.H"
1979 #endif
1980 #endif
Multidimensional array class.
Definition: CHArray.H:1256
CHArray(const Box &box, const DimT &dimc0)
Definition: CHArray.H:1319
#define D_DECL6(a, b, c, d, e, f)
Definition: CHArray.H:39
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1, const IIx_t i2, const IIx_t i3, const IIx_t i4) const
Definition: CHArray.H:922
USz_t ixDimSize(const USz_t size, const unsigned dim) const
Definition: CHArray.H:726
IIx_t m_ixIB
Lower bound for this dimension.
Definition: CHArray.H:505
IIx_t ixLowerBound(const unsigned dim) const
Definition: CHArray.H:784
bool isUsable() const
Memory has been allocated and size is > 0.
Definition: CHArray.H:1762
void define(void *const addr, const IntVect &iv, const DimT &dimc0)
Definition: CHArray.H:1493
Rank > 2 for zero-based subscripts and > 1 for subscript ranges.
Definition: CHArray.H:810
CHArray(const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1284
IIx_t ixDimOffset() const
Definition: CHArray.H:398
Allocator for an array of matrices contiguous in memory.
Definition: CHArray.H:1903
ArSp::IIx_t dimB
Definition: CHArray.H:193
#define D_DEFIV
Definition: CHArray.H:122
void define(const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
Definition: CHArray.H:1394
USz_t m_ixStride
Stride for this dimension.
Definition: CHArray.H:435
void ixDefine(const IIx_t offset, const DimT &dim6, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:566
IIx_t ixLowerBound(const unsigned dim) const
Definition: CHArray.H:959
T & operator()(const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0)
Definition: CHArray.H:1594
#define D_DEFBOX
Definition: CHArray.H:130
int vec[SpaceDim]
Definition: CHArray.H:70
void define(void *const addr, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1454
Rank 1 and a zero-based subscript (no data)
Definition: CHArray.H:445
T & operator()(const ArSp::IIx_t c0, const IntVect &iv)
Definition: CHArray.H:1625
Allocator that only permits allocation by new.
Definition: CHArray.H:1871
#define D_TERM6(a, b, c, d, e, f)
Definition: CHArray.H:40
static void eval(T *p, USz_t size)
Definition: CHArray.H:293
void ixDefine(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3, const DimT &dim4, const DimT &dim5, const DimT &dim6)
Definition: CHArray.H:855
IIx_t ixLowerBound(const unsigned dim) const
Definition: CHArray.H:1072
#define CH_assert(cond)
Definition: CHArray.H:37
void define(void *const addr, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1474
const T & operator()(const ArSp::IIx_t i6, const ArSp::IIx_t i5, const ArSp::IIx_t i4, const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
Constant access to an element.
Definition: CHArray.H:1632
void define(const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1368
IndexerData< 1, DimT > IxData
Definition: CHArray.H:988
void ixDefineTotalOffset(const IIx_t offset)
Definition: CHArray.H:462
Array_impl()
Definition: CHArray.H:1774
#define SpaceDim
Definition: CHArray.H:38
CSIndexer(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3)
Definition: CHArray.H:838
const T & operator()(const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
Definition: CHArray.H:1662
const T & operator()(const ArSp::IIx_t i5, const ArSp::IIx_t i4, const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
Definition: CHArray.H:1641
bool ixValidBounds(const IIx_t i, const USz_t size) const
Definition: CHArray.H:458
IIx_t ixLowerBound() const
Definition: CHArray.H:488
IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
Definition: CHArray.H:788
Definition: CHArray_fwd.H:37
CHArray(const Box &box, const DimT &dimc1, const DimT &dimc0)
Definition: CHArray.H:1311
IIx_t ixTotalOffset() const
Definition: CHArray.H:464
T * allocate(void *const addr, const USz_t size)
Definition: CHArray.H:346
unsigned ixIV(const unsigned i) const
Definition: CHArray.H:1081
const T & operator()(const ArSp::IIx_t i4, const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
Definition: CHArray.H:1649
IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
Definition: CHArray.H:734
bool defined
Definition: CHArray.H:1938
CHArray< Real, 2, ArZeroCol, ArSp::DefaultArrayAlloc< Real > > CHMatrix
Matrix defined with column-ordered storage.
Definition: CHArray.H:1815
int product() const
Definition: CHArray.H:64
void ixDefine(const IIx_t offset, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:593
T & operator()(const ArSp::IIx_t c1, const ArSp::IIx_t c0, const IntVect &iv)
Definition: CHArray.H:1620
IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
Definition: CHArray.H:676
IndexerData< 1, DimT > IxData
Definition: CHArray.H:699
CSIndexer(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2)
Definition: CHArray.H:844
USz_t ixIndex1D(const USz_t size, const IIx_t i0) const
Definition: CHArray.H:1007
IntVect(const IntVect &iv)
Definition: CHArray.H:51
void ixDefine(const IIx_t offset, const USz_t dim0, const USz_t dim1)
Definition: CHArray.H:1053
USz_t ixIndex1D(const USz_t size, const IIx_t i2, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:649
void deallocate(CHMatrix *p, const USz_t size)
Definition: CHArray.H:1929
const int & operator[](const int i) const
Definition: CHArray.H:60
void define(const DimT &dimc0, const Box &box)
Definition: CHArray.H:1429
T & operator()(const IntVect &iv, const ArSp::IIx_t c0)
Definition: CHArray.H:1615
void define(void *const addr, const Box &box, const DimT &dimc1, const DimT &dimc0)
Definition: CHArray.H:1510
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1, const IIx_t i2, const IIx_t i3, const IIx_t i4, const IIx_t i5, const IIx_t i6) const
Definition: CHArray.H:905
void define(void *const addr, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1468
AllocBy m_allocBy
Definition: CHArray.H:331
void ixDefineLowerBound(const DimT &dim)
Definition: CHArray.H:388
IntVect size() const
Definition: CHArray.H:86
const T & operator()(const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
Definition: CHArray.H:1656
int BoxAllowed
Definition: CHArray.H:1119
void define(void *const addr, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1461
double Real
Definition: CHArray.H:41
USz_t ixDimSize(const USz_t size, const unsigned dim) const
Definition: CHArray.H:664
const T * begin() const
Definition: CHArray.H:1712
CHArray & operator=(const T2 &val)
Assign a constant to the array.
Definition: CHArray.H:1554
CHArray(const DimT &dim0)
Definition: CHArray.H:1294
RSIndexer(const IIx_t offset, const USz_t &dim1, const USz_t &dim0)
Definition: CHArray.H:760
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1, const IIx_t i2) const
Definition: CHArray.H:938
T & operator()(const IntVect &iv, const ArSp::IIx_t c1, const ArSp::IIx_t c0)
Definition: CHArray.H:1610
CHRange(const ArSp::IIx_t a_dimE)
Definition: CHArray.H:183
CSIndexer< Rank-1, DimT > m_ixNext
Next lower rank.
Definition: CHArray.H:978
Array_impl(const ArSp::USz_t a_size)
Definition: CHArray.H:1777
RSIndexer(const IIx_t offset, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:555
void undefine()
Definition: CHArray.H:1798
USz_t ixIndex1D(const USz_t size, const IIx_t i4, const IIx_t i3, const IIx_t i2, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:633
void ixDefine(const IIx_t offset, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:608
RSIndexer()
Definition: CHArray.H:756
IndexerData< Rank, DimT > IxData
Definition: CHArray.H:812
void ixDefineLowerBound(const CHRange &dim)
Definition: CHArray.H:419
RSIndexer(const IIx_t offset, const DimT &dim0)
Definition: CHArray.H:705
int IIx_t
Definition: CHArray.H:159
void define(const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1356
ArSp::USz_t size
Overall size of the array.
Definition: CHArray.H:1804
void ixDefine(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2)
Definition: CHArray.H:890
int smallEnd(const int dir) const
Definition: CHArray.H:78
ArSp::ArTr< Rank, ArConf >::DimT DimT
Definition: CHArray.H:1258
USz_t ixIndex1D(const USz_t size, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:771
IIx_t ixLowerBound(const unsigned dim) const
Definition: CHArray.H:730
CHArray(const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1291
IIx_t ixLowerBound() const
Definition: CHArray.H:423
void ixDefineLowerBound(const DimT &dim)
Definition: CHArray.H:452
const T & operator()(const IntVect &iv, const ArSp::IIx_t c0) const
Definition: CHArray.H:1684
bool ixValidBounds(const IIx_t i, const USz_t size) const
Definition: CHArray.H:427
bool ixValidBounds(const IIx_t i, const USz_t size) const
Definition: CHArray.H:394
Alloc & getAllocator()
Get the allocator.
Definition: CHArray.H:1702
void define(void *const addr, const DimT &dimc0, const Box &box)
Definition: CHArray.H:1536
void define(const DimT &dim0)
Definition: CHArray.H:1378
Any rank and a zero-based subscript.
Definition: CHArray.H:379
ArSp::RSIndexer< Rank, DimT > IndexerT
Definition: CHArray.H:1111
AllocBy
Definition: CHArray.H:325
USz_t m
Definition: CHArray.H:1936
void ixDefineLowerBound(const CHRange &dim)
Definition: CHArray.H:484
CSIndexer()
Definition: CHArray.H:1044
ArSp::IIx_t lowerBound(const unsigned dim) const
Lower bound of a dimension (0 is dimension with contiguous storage)
Definition: CHArray.H:1740
void define(const DimT &dimc1, const DimT &dimc0, const Box &box)
Definition: CHArray.H:1421
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1) const
Definition: CHArray.H:945
const T & operator()(const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
Definition: CHArray.H:1668
Definition: EBInterface.H:45
unsigned USz_t
Type of unsigned int for a size.
Definition: CHArray.H:161
RSIndexer(const IIx_t offset, const DimT &dim6, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:529
void const char const int const int const int const Real const Real const int const Real const int const Real Real * C
Definition: Lapack.H:83
USz_t ixIndex1D(const USz_t size, const IIx_t i0) const
Definition: CHArray.H:719
ArSp::USz_t size(const unsigned dim) const
Size of a dimension (0 is dimension with contiguous storage)
Definition: CHArray.H:1732
CHArray(const IntVect &iv, const DimT &dimc0)
Definition: CHArray.H:1301
IIx_t ixLowerBound() const
Definition: CHArray.H:390
IndexerData(const USz_t stride, const DimT &dim)
Definition: CHArray.H:385
T & operator()(const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0)
Definition: CHArray.H:1588
void ixDefine(const IIx_t offset, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:601
RSIndexer(const IIx_t offset, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:543
IndexerData()
Definition: CHArray.H:413
T & operator()(const ArSp::IIx_t i1, const ArSp::IIx_t i0)
Definition: CHArray.H:1600
CHRange(const ArSp::IIx_t a_dimB, const ArSp::IIx_t a_dimE)
Definition: CHArray.H:188
T * end()
Definition: CHArray.H:1716
IntVect m_lb
Definition: CHArray.H:95
IIx_t ixDimOffset() const
Definition: CHArray.H:431
ArSp::USz_t DimT
Definition: CHArray.H:1104
void const char const int const int const int const Real const Real * A
Definition: Lapack.H:83
Box(const IntVect &lb, const IntVect &ub)
Definition: CHArray.H:75
CSIndexer()
Definition: CHArray.H:814
USz_t sizeOfDim< CHRange >(const CHRange &dim)
Definition: CHArray.H:214
ArSp::ArTr< Rank, ArConf >::IndexerT Indexer
Definition: CHArray.H:1259
IntVect(D_DECL6(const int i0, const int i1, const int i2, const int i3, const int i4, const int i5))
Definition: CHArray.H:45
void define(const USz_t a_m, const USz_t a_n)
Definition: CHArray.H:1909
IIx_t m_ixIB
Lower bound for this dimension.
Definition: CHArray.H:437
Definition: CHArray.H:1772
T * data
Data for the array.
Definition: CHArray.H:1805
RSIndexer(const IIx_t offset, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:537
Real * matrixData
Definition: CHArray.H:1935
IndexerData(const CHRange &dim)
Definition: CHArray.H:481
IndexerData< 2, USz_t > IxData
Definition: CHArray.H:754
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1, const IIx_t i2, const IIx_t i3) const
Definition: CHArray.H:930
~Array_impl()
Definition: CHArray.H:1782
RSIndexer()
Definition: CHArray.H:525
Array_impl m_arrayImpl
Data + allocation/deallocation.
Definition: CHArray.H:1808
DefaultArrayAlloc()
Definition: CHArray.H:334
void define(const ArSp::USz_t a_size)
Definition: CHArray.H:1786
bool ixValidBounds(const IIx_t i, const USz_t size) const
Definition: CHArray.H:492
IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
Definition: CHArray.H:965
void ixDefine(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3)
Definition: CHArray.H:882
IndexerData< Rank, DimT > IxData
Definition: CHArray.H:523
friend std::ostream & operator<<(std::ostream &os, const IntVect &iv)
void define(void *const addr, const DimT &dimc0, const IntVect &iv)
Definition: CHArray.H:1504
T & operator()(const ArSp::IIx_t i4, const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0)
Definition: CHArray.H:1581
Forward declarations for class CHArray.
void define(const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
Definition: CHArray.H:1384
RSIndexer< Rank-1, DimT > m_ixNext
Next lower rank.
Definition: CHArray.H:689
double Real
Definition: REAL.H:33
IndexerData(const USz_t stride, const CHRange &dim)
Definition: CHArray.H:416
void ixDefine(const IIx_t offset, const DimT &dim0)
Definition: CHArray.H:712
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1, const IIx_t i2, const IIx_t i3, const IIx_t i4, const IIx_t i5) const
Definition: CHArray.H:914
T * allocate(const USz_t size)
Definition: CHArray.H:1874
Definition: CHArray.H:277
IntVect m_ub
Definition: CHArray.H:96
RSIndexer()
Definition: CHArray.H:701
unsigned ixIV(const unsigned i) const
Definition: CHArray.H:683
USz_t m_ixStride
Stride for this dimension.
Definition: CHArray.H:402
void ixDefine(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3, const DimT &dim4, const DimT &dim5)
Definition: CHArray.H:865
IIx_t ixLowerBound(const unsigned dim) const
Definition: CHArray.H:670
int & operator[](const int i)
Definition: CHArray.H:56
CHArray(const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1279
Range of subscripts and row-storage.
Definition: CHArray_fwd.H:36
void define(const IntVect &iv, const DimT &dimc0)
Definition: CHArray.H:1389
void define(void *const addr, const DimT &dim6, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Define the dimensions and allocate on 'addr'.
Definition: CHArray.H:1439
CSIndexer(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3, const DimT &dim4, const DimT &dim5, const DimT &dim6)
Definition: CHArray.H:818
IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
Definition: CHArray.H:1076
ArSp::RSIndexer< Rank, DimT > IndexerT
Definition: CHArray.H:1099
CHMatrix * allocate(const USz_t size)
Definition: CHArray.H:1915
unsigned ixIV(const unsigned i) const
Definition: CHArray.H:1027
void ixDefine(const IIx_t offset, const DimT &dim0)
Definition: CHArray.H:1001
int BoxAllowed
Definition: CHArray.H:1112
void ixDefine(const IIx_t offset, const DimT &dim0, const DimT &dim1)
Definition: CHArray.H:897
void deallocate(T *p, const USz_t size)
Definition: CHArray.H:352
CSIndexer(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3, const DimT &dim4, const DimT &dim5)
Definition: CHArray.H:826
unsigned ixIV(const unsigned i) const
Definition: CHArray.H:793
CHArray(const DimT &dimc0, const IntVect &iv)
Definition: CHArray.H:1307
CHArray(const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
Definition: CHArray.H:1304
void ixDefine(const IIx_t offset, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:576
void define(void *const addr, const DimT &dim0)
Definition: CHArray.H:1480
T * begin()
Access extents of the memory allocated for the array.
Definition: CHArray.H:1708
IIx_t ixLowerBound(const unsigned dim) const
Definition: CHArray.H:1018
Definition: CHArray.H:328
ArSp::CSIndexer< Rank, DimT > IndexerT
Definition: CHArray.H:1118
void define(const Box &box, const DimT &dimc1, const DimT &dimc0)
Definition: CHArray.H:1405
void define(void *const addr, const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
Definition: CHArray.H:1498
ArrayOfMatrixAlloc()
Definition: CHArray.H:1906
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:469
Test for class type.
Definition: Misc.H:136
const T & operator()(const ArSp::IIx_t c1, const ArSp::IIx_t c0, const IntVect &iv) const
Definition: CHArray.H:1689
bool isAllocated() const
Memory has been allocated.
Definition: CHArray.H:1756
CHArray()
Default constructor.
Definition: CHArray.H:1263
void define(const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1373
Zero lower bound and column-storage.
Definition: CHArray_fwd.H:35
T & operator()(const ArSp::IIx_t i6, const ArSp::IIx_t i5, const ArSp::IIx_t i4, const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0)
Access an element.
Definition: CHArray.H:1564
void define(const DimT &dimc0, const IntVect &iv)
Definition: CHArray.H:1399
void ixDefine(const IIx_t offset, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:585
CSIndexer()
Definition: CHArray.H:990
USz_t ixIndex1D(const USz_t size, const IIx_t i5, const IIx_t i4, const IIx_t i3, const IIx_t i2, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:625
CSIndexer(const IIx_t offset, const DimT &dim0)
Definition: CHArray.H:994
IIx_t ixTotalOffset() const
Definition: CHArray.H:500
IIx_t ixLowerBound() const
Definition: CHArray.H:454
Definition: CHArray.H:248
static void eval(T *p, USz_t size)
Definition: CHArray.H:283
const T & operator()(const ArSp::IIx_t c0, const IntVect &iv) const
Definition: CHArray.H:1695
int bigEnd(const int dir) const
Definition: CHArray.H:82
IIx_t ixDimSize(const USz_t size, const unsigned dim) const
Definition: CHArray.H:1067
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
void define(const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1350
USz_t ixDimSize(const USz_t size, const unsigned dim) const
Definition: CHArray.H:1014
IndexerData(const DimT &dim)
Definition: CHArray.H:450
CHArray(const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1288
void ixDefine(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3, const DimT &dim4)
Definition: CHArray.H:874
CHArray< Real, 1, ArZeroCol, ArSp::DefaultArrayAlloc< Real > > CHVector
Vector definition.
Definition: CHArray.H:1812
void define(const Box &box, const DimT &dimc0)
Definition: CHArray.H:1413
void const char const int * M
Definition: Lapack.H:83
IndexerData< 2, USz_t > IxData
Definition: CHArray.H:1042
void p() const
Zero lower bound and row-storage.
Definition: CHArray_fwd.H:34
IIx_t m_ixOffset
Definition: CHArray.H:506
USz_t ixDimSize(const USz_t size, const unsigned dim) const
Definition: CHArray.H:953
T & operator()(const ArSp::IIx_t i5, const ArSp::IIx_t i4, const ArSp::IIx_t i3, const ArSp::IIx_t i2, const ArSp::IIx_t i1, const ArSp::IIx_t i0)
Definition: CHArray.H:1573
RSIndexer(const IIx_t offset, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:560
T & operator()(const ArSp::IIx_t i0)
Definition: CHArray.H:1605
unsigned ixIV(const unsigned i) const
Definition: CHArray.H:739
IndexerData()
Definition: CHArray.H:478
ArSp::USz_t size() const
Overall size of the array.
Definition: CHArray.H:1726
CHArray(const DimT &dimc0, const Box &box)
Definition: CHArray.H:1334
ArSp::IIx_t dimE
Definition: CHArray.H:194
IntVect operator*(const IntVect &p) const
Definition: IntVect.H:1102
Default allocator.
Definition: CHArray.H:322
RSIndexer(const IIx_t offset, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:549
void ixDefineTotalOffset(const IIx_t offset)
Definition: CHArray.H:496
void ixDefine(const IIx_t offset, const USz_t &dim1, const USz_t &dim0)
Definition: CHArray.H:765
ArSp::USz_t DimT
Definition: CHArray.H:1098
void deallocate(T *p, const USz_t size)
Definition: CHArray.H:1881
void define(void *const addr, const ArSp::USz_t a_size)
Definition: CHArray.H:1792
CSIndexer(const IIx_t offset, const DimT &dim0, const DimT &dim1)
Definition: CHArray.H:849
void define(void *const addr, const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
Definition: CHArray.H:1487
ArSp::IIx_t upperBound(const unsigned dim) const
Upper bound of a dimension (0 is dimension with contiguous storage)
Definition: CHArray.H:1748
ArSp::CSIndexer< Rank, DimT > IndexerT
Definition: CHArray.H:1105
unsigned ixIV(const unsigned i) const
Definition: CHArray.H:972
Definition: CHArray.H:1094
static T * eval(void *const addr, const USz_t size)
Definition: CHArray.H:264
const T & operator()(const IntVect &iv, const ArSp::IIx_t c1, const ArSp::IIx_t c0) const
Definition: CHArray.H:1678
CSIndexer(const IIx_t offset, const USz_t dim0, const USz_t dim1)
Definition: CHArray.H:1048
int dim
Definition: EBInterface.H:146
USz_t ixIndex1D(const USz_t size, const IIx_t i6, const IIx_t i5, const IIx_t i4, const IIx_t i3, const IIx_t i2, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:616
void undefine()
Deallocate the array.
Definition: CHArray.H:1546
USz_t ixIndex1D(const USz_t size, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:656
void define(const DimT &dim6, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Define the dimensions.
Definition: CHArray.H:1343
#define D_IXIV
Definition: CHArray.H:145
USz_t ixIndex1D(const USz_t size, const IIx_t i3, const IIx_t i2, const IIx_t i1, const IIx_t i0) const
Definition: CHArray.H:641
USz_t ixDimSize(const USz_t size, const unsigned dim) const
Definition: CHArray.H:779
char One
Definition: CHArray.H:104
const T & operator()(const ArSp::IIx_t i0) const
Definition: CHArray.H:1673
USz_t sizeOfDim(const T &dim)
Get the size of a dimension.
Definition: CHArray.H:207
IndexerData()
Definition: CHArray.H:382
CHArray(const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
Definition: CHArray.H:1298
CHArray(const DimT &dimc1, const DimT &dimc0, const Box &box)
Definition: CHArray.H:1326
CSIndexer(const IIx_t offset, const DimT &dim0, const DimT &dim1, const DimT &dim2, const DimT &dim3, const DimT &dim4)
Definition: CHArray.H:832
CHArray(const DimT &dim6, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Construct with dimensions.
Definition: CHArray.H:1268
void define(void *const addr, const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1447
T * allocate(const USz_t size)
Definition: CHArray.H:338
CHRange DimT
Definition: CHArray.H:1110
const T * end() const
Definition: CHArray.H:1720
IndexerData()
Definition: CHArray.H:448
static T * eval(void *const addr, const USz_t size)
Definition: CHArray.H:254
Defines a range of subscripts.
Definition: CHArray.H:181
void define(const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1362
CHRange DimT
Definition: CHArray.H:1117
USz_t ixIndex1D(const USz_t size, const IIx_t i0, const IIx_t i1) const
Definition: CHArray.H:1059
IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
Definition: CHArray.H:1022
Rank > 2 for zero-based subscripts and > 1 for subscript ranges.
Definition: CHArray.H:521
void define(void *const addr, const DimT &dimc1, const DimT &dimc0, const Box &box)
Definition: CHArray.H:1527
CHArray(const DimT &dim5, const DimT &dim4, const DimT &dim3, const DimT &dim2, const DimT &dim1, const DimT &dim0)
Definition: CHArray.H:1274
IntVect()
Definition: IntVect.H:67
void define(void *const addr, const Box &box, const DimT &dimc0)
Definition: CHArray.H:1519
USz_t n
Definition: CHArray.H:1937