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