00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _CHARRAY_H_
00012 #define _CHARRAY_H_
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iomanip>
00024
00025 #include "CHArray_fwd.H"
00026
00027 #ifdef CH_SPACEDIM
00028
00029 #include "REAL.H"
00030 #include "Misc.H"
00031 #include "Box.H"
00032 #include "NamespaceHeader.H"
00033 #else
00034
00035 #include <cassert>
00036
00037 #define CH_assert(cond) assert(cond)
00038 #define SpaceDim 2
00039 #define D_DECL6(a,b,c,d,e,f) a,b
00040 #define D_TERM6(a,b,c,d,e,f) a b
00041 typedef double Real;
00042 class IntVect
00043 {
00044 public:
00045 IntVect(D_DECL6(const int i0, const int i1, const int i2,
00046 const int i3, const int i4, const int i5))
00047 {
00048 D_TERM6(vec[0] = i0;, vec[1] = i1;, vec[2] = i2;,
00049 vec[3] = i3;, vec[4] = i4;, vec[5] = i5;)
00050 }
00051 IntVect(const IntVect &iv)
00052 {
00053 D_TERM6(vec[0] = iv.vec[0];, vec[1] = iv.vec[1];, vec[2] = iv.vec[2];,
00054 vec[3] = iv.vec[3];, vec[4] = iv.vec[4];, vec[5] = iv.vec[5];)
00055 }
00056 int &operator[](const int i)
00057 {
00058 return vec[i];
00059 }
00060 const int &operator[](const int i) const
00061 {
00062 return vec[i];
00063 }
00064 int product() const
00065 {
00066 int prod = 1;
00067 for (int i = 0; i != SpaceDim; ++i) prod *= vec[i];
00068 return prod;
00069 }
00070 int vec[SpaceDim];
00071 };
00072 class Box
00073 {
00074 public:
00075 Box(const IntVect &lb, const IntVect &ub)
00076 : m_lb(lb), m_ub(ub)
00077 { }
00078 int smallEnd(const int dir) const
00079 {
00080 return m_lb[dir];
00081 }
00082 int bigEnd(const int dir) const
00083 {
00084 return m_ub[dir];
00085 }
00086 IntVect size() const
00087 {
00088 return IntVect(D_DECL6(m_ub[0] - m_lb[0] + 1,
00089 m_ub[1] - m_lb[1] + 1,
00090 m_ub[2] - m_lb[2] + 1,
00091 m_ub[3] - m_lb[3] + 1,
00092 m_ub[4] - m_lb[4] + 1,
00093 m_ub[5] - m_lb[5] + 1));
00094 }
00095 IntVect m_lb;
00096 IntVect m_ub;
00097 };
00098
00099 namespace Misc {
00100 template <typename T>
00101 class TypeTr
00102 {
00103 private:
00104 typedef char One;
00105 typedef struct
00106 {
00107 char a[2];
00108 } Two;
00109 template <typename C> static One test(int C::*);
00110 template <typename C> static Two test(...);
00111 public:
00112 enum
00113 {
00114 IsClass = sizeof(TypeTr<T>::template test<T>(0)) == 1
00115 };
00116 };
00117 }
00118 #endif
00119
00120
00121
00122 # define D_DEFIV D_DECL6(DimT(iv[Indexer::ixIV(0)]), \
00123 DimT(iv[Indexer::ixIV(1)]), \
00124 DimT(iv[Indexer::ixIV(2)]), \
00125 DimT(iv[Indexer::ixIV(3)]), \
00126 DimT(iv[Indexer::ixIV(4)]), \
00127 DimT(iv[Indexer::ixIV(5)]))
00128
00129
00130 # define D_DEFBOX D_DECL6(DimT(box.smallEnd(Indexer::ixIV(0)), \
00131 box.bigEnd(Indexer::ixIV(0))), \
00132 DimT(box.smallEnd(Indexer::ixIV(1)), \
00133 box.bigEnd(Indexer::ixIV(1))), \
00134 DimT(box.smallEnd(Indexer::ixIV(2)), \
00135 box.bigEnd(Indexer::ixIV(2))), \
00136 DimT(box.smallEnd(Indexer::ixIV(3)), \
00137 box.bigEnd(Indexer::ixIV(3))), \
00138 DimT(box.smallEnd(Indexer::ixIV(4)), \
00139 box.bigEnd(Indexer::ixIV(4))), \
00140 DimT(box.smallEnd(Indexer::ixIV(5)), \
00141 box.bigEnd(Indexer::ixIV(5))))
00142
00143
00144
00145 # define D_IXIV D_DECL6(iv[Indexer::ixIV(0)], \
00146 iv[Indexer::ixIV(1)], \
00147 iv[Indexer::ixIV(2)], \
00148 iv[Indexer::ixIV(3)], \
00149 iv[Indexer::ixIV(4)], \
00150 iv[Indexer::ixIV(5)])
00151
00152 namespace ArSp
00153 {
00154
00155
00156
00157
00158
00159 typedef int IIx_t;
00160
00161 typedef unsigned USz_t;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 struct CHRange
00182 {
00183 CHRange(const ArSp::IIx_t a_dimE)
00184 : dimB(0), dimE(a_dimE - 1)
00185 {
00186 CH_assert(a_dimE >= 0);
00187 }
00188 CHRange(const ArSp::IIx_t a_dimB, const ArSp::IIx_t a_dimE)
00189 : dimB(a_dimB), dimE(a_dimE)
00190 {
00191 CH_assert(a_dimE >= a_dimB);
00192 }
00193 ArSp::IIx_t dimB;
00194 ArSp::IIx_t dimE;
00195 };
00196
00197
00198
00199
00200
00201
00202 namespace ArSp
00203 {
00204
00205
00206 template <typename T>
00207 inline USz_t sizeOfDim(const T &dim)
00208 {
00209 return (USz_t)dim;
00210 }
00211
00212
00213 template <>
00214 inline USz_t sizeOfDim<CHRange>(const CHRange &dim)
00215 {
00216 return (USz_t)(dim.dimE - dim.dimB + 1);
00217 }
00218 }
00219
00220
00221 inline ArSp::USz_t operator*(const CHRange &a, const CHRange &b)
00222 {
00223 return (ArSp::sizeOfDim(a)*ArSp::sizeOfDim(b));
00224 }
00225
00226
00227 inline ArSp::USz_t operator*(const ArSp::USz_t &i, const CHRange &a)
00228 {
00229 return i*ArSp::sizeOfDim(a);
00230 }
00231
00232
00233 inline ArSp::USz_t operator*(const CHRange &a, const ArSp::USz_t &i)
00234 {
00235 return ArSp::sizeOfDim(a)*i;
00236 }
00237
00238
00239 namespace ArSp
00240 {
00241
00242
00243
00244
00245
00246
00247 template <typename T, bool IsClass = Misc::TypeTr<T>::IsClass>
00248 struct AllocRawPolicy;
00249
00250
00251 template <typename T>
00252 struct AllocRawPolicy<T, true>
00253 {
00254 static T *eval(void *const addr, const USz_t size)
00255 {
00256 return new(addr) T[size];
00257 }
00258 };
00259
00260
00261 template <typename T>
00262 struct AllocRawPolicy<T, false>
00263 {
00264 static T *eval(void *const addr, const USz_t size)
00265 {
00266 return static_cast<T*>(addr);
00267 }
00268 };
00269
00270
00271
00272
00273
00274
00275
00276 template <typename T, bool IsClass = Misc::TypeTr<T>::IsClass>
00277 struct ReleaseRawPolicy;
00278
00279
00280 template <typename T>
00281 struct ReleaseRawPolicy<T, true>
00282 {
00283 static void eval(T *p, USz_t size)
00284 {
00285 while (size--) p++->~T();
00286 }
00287 };
00288
00289
00290 template <typename T>
00291 struct ReleaseRawPolicy<T, false>
00292 {
00293 static void eval(T *p, USz_t size)
00294 {
00295 }
00296 };
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 template <typename T>
00322 class DefaultArrayAlloc
00323 {
00324 private:
00325 enum AllocBy
00326 {
00327 AllocUndefined,
00328 AllocNew,
00329 AllocRaw
00330 };
00331 AllocBy m_allocBy;
00332
00333 public:
00334 DefaultArrayAlloc()
00335 : m_allocBy(AllocUndefined)
00336 { }
00337
00338 T* allocate(const USz_t size)
00339 {
00340 T *const p = new(std::nothrow) T[size];
00341 CH_assert(p != 0);
00342 m_allocBy = AllocNew;
00343 return p;
00344 }
00345
00346 T* allocate(void *const addr, const USz_t size)
00347 {
00348 m_allocBy = AllocRaw;
00349 return AllocRawPolicy<T>::eval(addr, size);
00350 }
00351
00352 void deallocate(T *p, const USz_t size)
00353 {
00354 switch (m_allocBy)
00355 {
00356 case AllocNew:
00357 delete[] p;
00358 break;
00359 case AllocRaw:
00360 ReleaseRawPolicy<T>::eval(p, size);
00361 break;
00362 case AllocUndefined:
00363 break;
00364 }
00365 }
00366 };
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 template <unsigned Rank, typename DimT>
00379 class IndexerData
00380 {
00381 protected:
00382 IndexerData()
00383 : m_ixStride(0)
00384 { }
00385 IndexerData(const USz_t stride, const DimT &dim)
00386 : m_ixStride(stride)
00387 { }
00388 void ixDefineLowerBound(const DimT &dim)
00389 { }
00390 IIx_t ixLowerBound() const
00391 {
00392 return 0;
00393 }
00394 bool ixValidBounds(const IIx_t i, const USz_t size) const
00395 {
00396 return (((USz_t)i) < size/m_ixStride);
00397 }
00398 IIx_t ixDimOffset() const
00399 {
00400 return 0;
00401 }
00402 USz_t m_ixStride;
00403 };
00404
00405
00406
00407
00408
00409 template <unsigned Rank>
00410 class IndexerData<Rank, CHRange>
00411 {
00412 protected:
00413 IndexerData()
00414 : m_ixStride(0), m_ixIB(0)
00415 { }
00416 IndexerData(const USz_t stride, const CHRange &dim)
00417 : m_ixStride(stride), m_ixIB(dim.dimB)
00418 { }
00419 void ixDefineLowerBound(const CHRange &dim)
00420 {
00421 m_ixIB = dim.dimB;
00422 }
00423 IIx_t ixLowerBound() const
00424 {
00425 return m_ixIB;
00426 }
00427 bool ixValidBounds(const IIx_t i, const USz_t size) const
00428 {
00429 return (i >= m_ixIB && i < m_ixIB + (IIx_t)(size/m_ixStride));
00430 }
00431 IIx_t ixDimOffset() const
00432 {
00433 return m_ixIB*m_ixStride;
00434 }
00435 USz_t m_ixStride;
00436 private:
00437 IIx_t m_ixIB;
00438 };
00439
00440
00441
00442
00443
00444 template <typename DimT>
00445 class IndexerData<1, DimT>
00446 {
00447 protected:
00448 IndexerData()
00449 { }
00450 IndexerData(const DimT &dim)
00451 { }
00452 void ixDefineLowerBound(const DimT &dim)
00453 { }
00454 IIx_t ixLowerBound() const
00455 {
00456 return 0;
00457 }
00458 bool ixValidBounds(const IIx_t i, const USz_t size) const
00459 {
00460 return (((USz_t)i) < size);
00461 }
00462 void ixDefineTotalOffset(const IIx_t offset)
00463 { }
00464 IIx_t ixTotalOffset() const
00465 {
00466 return 0;
00467 }
00468 };
00469
00470
00471
00472
00473
00474 template <>
00475 class IndexerData<1, CHRange>
00476 {
00477 protected:
00478 IndexerData()
00479 : m_ixIB(0)
00480 { }
00481 IndexerData(const CHRange &dim)
00482 : m_ixIB(dim.dimB)
00483 { }
00484 void ixDefineLowerBound(const CHRange &dim)
00485 {
00486 m_ixIB = dim.dimB;
00487 }
00488 IIx_t ixLowerBound() const
00489 {
00490 return m_ixIB;
00491 }
00492 bool ixValidBounds(const IIx_t i, const USz_t size) const
00493 {
00494 return (i >= m_ixIB && i < m_ixIB + (IIx_t)size);
00495 }
00496 void ixDefineTotalOffset(const IIx_t offset)
00497 {
00498 m_ixOffset = offset;
00499 }
00500 IIx_t ixTotalOffset() const
00501 {
00502 return m_ixOffset;
00503 }
00504 private:
00505 IIx_t m_ixIB;
00506 IIx_t m_ixOffset;
00507
00508
00509 };
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 template <unsigned Rank, typename DimT>
00521 class RSIndexer : private IndexerData<Rank, DimT>
00522 {
00523 typedef IndexerData<Rank, DimT> IxData;
00524 public:
00525 RSIndexer()
00526 : IxData(), m_ixNext()
00527 { }
00528
00529 RSIndexer(const IIx_t offset,
00530 const DimT &dim6, const DimT &dim5, const DimT &dim4,
00531 const DimT &dim3, const DimT &dim2, const DimT &dim1,
00532 const DimT &dim0)
00533 : IxData(dim5*dim4*dim3*dim2*dim1*dim0, dim6),
00534 m_ixNext(offset - IxData::ixDimOffset(),
00535 dim5, dim4, dim3, dim2, dim1, dim0)
00536 { }
00537 RSIndexer(const IIx_t offset,
00538 const DimT &dim5, const DimT &dim4, const DimT &dim3,
00539 const DimT &dim2, const DimT &dim1, const DimT &dim0)
00540 : IxData(dim4*dim3*dim2*dim1*dim0, dim5),
00541 m_ixNext(offset - IxData::ixDimOffset(), dim4, dim3, dim2, dim1, dim0)
00542 { }
00543 RSIndexer(const IIx_t offset,
00544 const DimT &dim4, const DimT &dim3, const DimT &dim2,
00545 const DimT &dim1, const DimT &dim0)
00546 : IxData(dim3*dim2*dim1*dim0, dim4),
00547 m_ixNext(offset - IxData::ixDimOffset(), dim3, dim2, dim1, dim0)
00548 { }
00549 RSIndexer(const IIx_t offset,
00550 const DimT &dim3, const DimT &dim2, const DimT &dim1,
00551 const DimT &dim0)
00552 : IxData(dim2*dim1*dim0, dim3),
00553 m_ixNext(offset - IxData::ixDimOffset(), dim2, dim1, dim0)
00554 { }
00555 RSIndexer(const IIx_t offset,
00556 const DimT &dim2, const DimT &dim1, const DimT &dim0)
00557 : IxData(dim1*dim0, dim2),
00558 m_ixNext(offset - IxData::ixDimOffset(), dim1, dim0)
00559 { }
00560 RSIndexer(const IIx_t offset,
00561 const DimT &dim1, const DimT &dim0)
00562 : IxData(sizeOfDim(dim0), dim1),
00563 m_ixNext(offset - IxData::ixDimOffset(), dim0)
00564 { }
00565
00566 void ixDefine(const IIx_t offset,
00567 const DimT &dim6, const DimT &dim5, const DimT &dim4,
00568 const DimT &dim3, const DimT &dim2, const DimT &dim1,
00569 const DimT &dim0)
00570 {
00571 IxData::m_ixStride = dim5*dim4*dim3*dim2*dim1*dim0;
00572 IxData::ixDefineLowerBound(dim6);
00573 m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
00574 dim5, dim4, dim3, dim2, dim1, dim0);
00575 }
00576 void ixDefine(const IIx_t offset,
00577 const DimT &dim5, const DimT &dim4, const DimT &dim3,
00578 const DimT &dim2, const DimT &dim1, const DimT &dim0)
00579 {
00580 IxData::m_ixStride = dim4*dim3*dim2*dim1*dim0;
00581 IxData::ixDefineLowerBound(dim5);
00582 m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
00583 dim4, dim3, dim2, dim1, dim0);
00584 }
00585 void ixDefine(const IIx_t offset,
00586 const DimT &dim4, const DimT &dim3, const DimT &dim2,
00587 const DimT &dim1, const DimT &dim0)
00588 {
00589 IxData::m_ixStride = dim3*dim2*dim1*dim0;
00590 IxData::ixDefineLowerBound(dim4);
00591 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim3, dim2, dim1, dim0);
00592 }
00593 void ixDefine(const IIx_t offset,
00594 const DimT &dim3, const DimT &dim2, const DimT &dim1,
00595 const DimT &dim0)
00596 {
00597 IxData::m_ixStride = dim2*dim1*dim0;
00598 IxData::ixDefineLowerBound(dim3);
00599 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim2, dim1, dim0);
00600 }
00601 void ixDefine(const IIx_t offset,
00602 const DimT &dim2, const DimT &dim1, const DimT &dim0)
00603 {
00604 IxData::m_ixStride = dim1*dim0;
00605 IxData::ixDefineLowerBound(dim2);
00606 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim1, dim0);
00607 }
00608 void ixDefine(const IIx_t offset,
00609 const DimT &dim1, const DimT &dim0)
00610 {
00611 IxData::m_ixStride = sizeOfDim(dim0);
00612 IxData::ixDefineLowerBound(dim1);
00613 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0);
00614 }
00615
00616 USz_t ixIndex1D(const USz_t size,
00617 const IIx_t i6, const IIx_t i5, const IIx_t i4,
00618 const IIx_t i3, const IIx_t i2, const IIx_t i1,
00619 const IIx_t i0) const
00620 {
00621 CH_assert((IxData::ixValidBounds(i6, size)));
00622 return IxData::m_ixStride*i6 +
00623 m_ixNext.ixIndex1D(IxData::m_ixStride, i5, i4, i3, i2, i1, i0);
00624 }
00625 USz_t ixIndex1D(const USz_t size,
00626 const IIx_t i5, const IIx_t i4, const IIx_t i3,
00627 const IIx_t i2, const IIx_t i1, const IIx_t i0) const
00628 {
00629 CH_assert((IxData::ixValidBounds(i5, size)));
00630 return IxData::m_ixStride*i5 +
00631 m_ixNext.ixIndex1D(IxData::m_ixStride, i4, i3, i2, i1, i0);
00632 }
00633 USz_t ixIndex1D(const USz_t size,
00634 const IIx_t i4, const IIx_t i3, const IIx_t i2,
00635 const IIx_t i1, const IIx_t i0) const
00636 {
00637 CH_assert((IxData::ixValidBounds(i4, size)));
00638 return IxData::m_ixStride*i4 +
00639 m_ixNext.ixIndex1D(IxData::m_ixStride, i3, i2, i1, i0);
00640 }
00641 USz_t ixIndex1D(const USz_t size,
00642 const IIx_t i3, const IIx_t i2, const IIx_t i1,
00643 const IIx_t i0) const
00644 {
00645 CH_assert((IxData::ixValidBounds(i3, size)));
00646 return IxData::m_ixStride*i3 +
00647 m_ixNext.ixIndex1D(IxData::m_ixStride, i2, i1, i0);
00648 }
00649 USz_t ixIndex1D(const USz_t size,
00650 const IIx_t i2, const IIx_t i1, const IIx_t i0) const
00651 {
00652 CH_assert((IxData::ixValidBounds(i2, size)));
00653 return IxData::m_ixStride*i2 +
00654 m_ixNext.ixIndex1D(IxData::m_ixStride, i1, i0);
00655 }
00656 USz_t ixIndex1D(const USz_t size,
00657 const IIx_t i1, const IIx_t i0) const
00658 {
00659 CH_assert((IxData::ixValidBounds(i1, size)));
00660 return IxData::m_ixStride*i1 +
00661 m_ixNext.ixIndex1D(IxData::m_ixStride, i0);
00662 }
00663
00664 USz_t ixDimSize(const USz_t size, const unsigned dim) const
00665 {
00666 return (dim == Rank) ?
00667 size/IxData::m_ixStride :
00668 m_ixNext.ixDimSize(IxData::m_ixStride, dim);
00669 }
00670 IIx_t ixLowerBound(const unsigned dim) const
00671 {
00672 return (dim == Rank) ?
00673 IxData::ixLowerBound() :
00674 m_ixNext.ixLowerBound(dim);
00675 }
00676 IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
00677 {
00678 return (dim == Rank) ?
00679 IxData::ixLowerBound() + size/IxData::m_ixStride - 1 :
00680 m_ixNext.ixUpperBound(IxData::m_ixStride, dim);
00681 }
00682
00683 unsigned ixIV(const unsigned i) const
00684 {
00685 return SpaceDim - 1 - i;
00686 }
00687
00688 private:
00689 RSIndexer<Rank-1, DimT> m_ixNext;
00690 };
00691
00692
00693
00694
00695
00696 template <typename DimT>
00697 class RSIndexer<1, DimT> : private IndexerData<1, DimT>
00698 {
00699 typedef IndexerData<1, DimT> IxData;
00700 public:
00701 RSIndexer()
00702 : IxData()
00703 { }
00704
00705 RSIndexer(const IIx_t offset,
00706 const DimT &dim0)
00707 : IxData(dim0)
00708 {
00709 IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
00710 }
00711
00712 void ixDefine(const IIx_t offset,
00713 const DimT &dim0)
00714 {
00715 IxData::ixDefineLowerBound(dim0);
00716 IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
00717 }
00718
00719 USz_t ixIndex1D(const USz_t size,
00720 const IIx_t i0) const
00721 {
00722 CH_assert((IxData::ixValidBounds(i0, size)));
00723 return i0 + IxData::ixTotalOffset();
00724 }
00725
00726 USz_t ixDimSize(const USz_t size, const unsigned dim) const
00727 {
00728 return size;
00729 }
00730 IIx_t ixLowerBound(const unsigned dim) const
00731 {
00732 return IxData::ixLowerBound();
00733 }
00734 IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
00735 {
00736 return IxData::ixLowerBound() + size - 1;
00737 }
00738
00739 unsigned ixIV(const unsigned i) const
00740 {
00741 return SpaceDim - 1 - i;
00742 }
00743 };
00744
00745
00746
00747
00748
00749
00750
00751 template <>
00752 class RSIndexer<2, USz_t> : private IndexerData<2, USz_t>
00753 {
00754 typedef IndexerData<2, USz_t> IxData;
00755 public:
00756 RSIndexer()
00757 : IxData()
00758 { }
00759
00760 RSIndexer(const IIx_t offset,
00761 const USz_t &dim1, const USz_t &dim0)
00762 : IxData(dim0, dim1)
00763 { }
00764
00765 void ixDefine(const IIx_t offset,
00766 const USz_t &dim1, const USz_t &dim0)
00767 {
00768 IxData::m_ixStride = dim0;
00769 }
00770
00771 USz_t ixIndex1D(const USz_t size,
00772 const IIx_t i1, const IIx_t i0) const
00773 {
00774 CH_assert((IxData::ixValidBounds(i1, size)));
00775 CH_assert((i0 < IxData::m_ixStride));
00776 return IxData::m_ixStride*i1 + i0;
00777 }
00778
00779 USz_t ixDimSize(const USz_t size, const unsigned dim) const
00780 {
00781 return (dim == 2) ? size/IxData::m_ixStride :
00782 IxData::m_ixStride;
00783 }
00784 IIx_t ixLowerBound(const unsigned dim) const
00785 {
00786 return 0;
00787 }
00788 IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
00789 {
00790 return ixDimSize(size, dim) - 1;
00791 }
00792
00793 unsigned ixIV(const unsigned i) const
00794 {
00795 return SpaceDim - 1 - i;
00796 }
00797 };
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 template <unsigned Rank, typename DimT>
00810 class CSIndexer : private IndexerData<Rank, DimT>
00811 {
00812 typedef IndexerData<Rank, DimT> IxData;
00813 public:
00814 CSIndexer()
00815 : IxData(), m_ixNext()
00816 { }
00817
00818 CSIndexer(const IIx_t offset,
00819 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00820 const DimT &dim3, const DimT &dim4, const DimT &dim5,
00821 const DimT &dim6)
00822 : IxData(dim0*dim1*dim2*dim3*dim4*dim5, dim6),
00823 m_ixNext(offset - IxData::ixDimOffset(),
00824 dim0, dim1, dim2, dim3, dim4, dim5)
00825 { }
00826 CSIndexer(const IIx_t offset,
00827 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00828 const DimT &dim3, const DimT &dim4, const DimT &dim5)
00829 : IxData(dim0*dim1*dim2*dim3*dim4, dim5),
00830 m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1, dim2, dim3, dim4)
00831 { }
00832 CSIndexer(const IIx_t offset,
00833 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00834 const DimT &dim3, const DimT &dim4)
00835 : IxData(dim0*dim1*dim2*dim3, dim4),
00836 m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1, dim2, dim3)
00837 { }
00838 CSIndexer(const IIx_t offset,
00839 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00840 const DimT &dim3)
00841 : IxData(dim0*dim1*dim2, dim3),
00842 m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1, dim2)
00843 { }
00844 CSIndexer(const IIx_t offset,
00845 const DimT &dim0, const DimT &dim1, const DimT &dim2)
00846 : IxData(dim0*dim1, dim2),
00847 m_ixNext(offset - IxData::ixDimOffset(), dim0, dim1)
00848 { }
00849 CSIndexer(const IIx_t offset,
00850 const DimT &dim0, const DimT &dim1)
00851 : IxData(sizeOfDim(dim0), dim1),
00852 m_ixNext(offset - IxData::ixDimOffset(), dim0)
00853 { }
00854
00855 void ixDefine(const IIx_t offset,
00856 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00857 const DimT &dim3, const DimT &dim4, const DimT &dim5,
00858 const DimT &dim6)
00859 {
00860 IxData::m_ixStride = dim0*dim1*dim2*dim3*dim4*dim5;
00861 IxData::ixDefineLowerBound(dim6);
00862 m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
00863 dim0, dim1, dim2, dim3, dim4, dim5);
00864 }
00865 void ixDefine(const IIx_t offset,
00866 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00867 const DimT &dim3, const DimT &dim4, const DimT &dim5)
00868 {
00869 IxData::m_ixStride = dim0*dim1*dim2*dim3*dim4;
00870 IxData::ixDefineLowerBound(dim5);
00871 m_ixNext.ixDefine(offset - IxData::ixDimOffset(),
00872 dim0, dim1, dim2, dim3, dim4);
00873 }
00874 void ixDefine(const IIx_t offset,
00875 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00876 const DimT &dim3, const DimT &dim4)
00877 {
00878 IxData::m_ixStride = dim0*dim1*dim2*dim3;
00879 IxData::ixDefineLowerBound(dim4);
00880 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0, dim1, dim2, dim3);
00881 }
00882 void ixDefine(const IIx_t offset,
00883 const DimT &dim0, const DimT &dim1, const DimT &dim2,
00884 const DimT &dim3)
00885 {
00886 IxData::m_ixStride = dim0*dim1*dim2;
00887 IxData::ixDefineLowerBound(dim3);
00888 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0, dim1, dim2);
00889 }
00890 void ixDefine(const IIx_t offset,
00891 const DimT &dim0, const DimT &dim1, const DimT &dim2)
00892 {
00893 IxData::m_ixStride = dim0*dim1;
00894 IxData::ixDefineLowerBound(dim2);
00895 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0, dim1);
00896 }
00897 void ixDefine(const IIx_t offset,
00898 const DimT &dim0, const DimT &dim1)
00899 {
00900 IxData::m_ixStride = sizeOfDim(dim0);
00901 IxData::ixDefineLowerBound(dim1);
00902 m_ixNext.ixDefine(offset - IxData::ixDimOffset(), dim0);
00903 }
00904
00905 USz_t ixIndex1D(const USz_t size,
00906 const IIx_t i0, const IIx_t i1, const IIx_t i2,
00907 const IIx_t i3, const IIx_t i4, const IIx_t i5,
00908 const IIx_t i6) const
00909 {
00910 CH_assert((IxData::ixValidBounds(i6, size)));
00911 return IxData::m_ixStride*i6 +
00912 m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2, i3, i4, i5);
00913 }
00914 USz_t ixIndex1D(const USz_t size,
00915 const IIx_t i0, const IIx_t i1, const IIx_t i2,
00916 const IIx_t i3, const IIx_t i4, const IIx_t i5) const
00917 {
00918 CH_assert((IxData::ixValidBounds(i5, size)));
00919 return IxData::m_ixStride*i5 +
00920 m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2, i3, i4);
00921 }
00922 USz_t ixIndex1D(const USz_t size,
00923 const IIx_t i0, const IIx_t i1, const IIx_t i2,
00924 const IIx_t i3, const IIx_t i4) const
00925 {
00926 CH_assert((IxData::ixValidBounds(i4, size)));
00927 return IxData::m_ixStride*i4 +
00928 m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2, i3);
00929 }
00930 USz_t ixIndex1D(const USz_t size,
00931 const IIx_t i0, const IIx_t i1, const IIx_t i2,
00932 const IIx_t i3) const
00933 {
00934 CH_assert((IxData::ixValidBounds(i3, size)));
00935 return IxData::m_ixStride*i3 +
00936 m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1, i2);
00937 }
00938 USz_t ixIndex1D(const USz_t size,
00939 const IIx_t i0, const IIx_t i1, const IIx_t i2) const
00940 {
00941 CH_assert((IxData::ixValidBounds(i2, size)));
00942 return IxData::m_ixStride*i2 +
00943 m_ixNext.ixIndex1D(IxData::m_ixStride, i0, i1);
00944 }
00945 USz_t ixIndex1D(const USz_t size,
00946 const IIx_t i0, const IIx_t i1) const
00947 {
00948 CH_assert((IxData::ixValidBounds(i1, size)));
00949 return IxData::m_ixStride*i1 +
00950 m_ixNext.ixIndex1D(IxData::m_ixStride, i0);
00951 }
00952
00953 USz_t ixDimSize(const USz_t size, const unsigned dim) const
00954 {
00955 return (dim == Rank) ?
00956 size/IxData::m_ixStride :
00957 m_ixNext.ixDimSize(IxData::m_ixStride, dim);
00958 }
00959 IIx_t ixLowerBound(const unsigned dim) const
00960 {
00961 return (dim == Rank) ?
00962 IxData::ixLowerBound() :
00963 m_ixNext.ixLowerBound(dim);
00964 }
00965 IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
00966 {
00967 return (dim == Rank) ?
00968 IxData::ixLowerBound() + size/IxData::m_ixStride - 1 :
00969 m_ixNext.ixUpperBound(IxData::m_ixStride, dim);
00970 }
00971
00972 unsigned ixIV(const unsigned i) const
00973 {
00974 return i;
00975 }
00976
00977 private:
00978 CSIndexer<Rank-1, DimT> m_ixNext;
00979 };
00980
00981
00982
00983
00984
00985 template <typename DimT>
00986 class CSIndexer<1, DimT> : private IndexerData<1, DimT>
00987 {
00988 typedef IndexerData<1, DimT> IxData;
00989 public:
00990 CSIndexer()
00991 : IxData()
00992 { }
00993
00994 CSIndexer(const IIx_t offset,
00995 const DimT &dim0)
00996 : IxData(dim0)
00997 {
00998 IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
00999 }
01000
01001 void ixDefine(const IIx_t offset, const DimT &dim0)
01002 {
01003 IxData::ixDefineLowerBound(dim0);
01004 IxData::ixDefineTotalOffset(offset - IxData::ixLowerBound());
01005 }
01006
01007 USz_t ixIndex1D(const USz_t size,
01008 const IIx_t i0) const
01009 {
01010 CH_assert((IxData::ixValidBounds(i0, size)));
01011 return i0 + IxData::ixTotalOffset();
01012 }
01013
01014 USz_t ixDimSize(const USz_t size, const unsigned dim) const
01015 {
01016 return size;
01017 }
01018 IIx_t ixLowerBound(const unsigned dim) const
01019 {
01020 return IxData::ixLowerBound();
01021 }
01022 IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
01023 {
01024 return IxData::ixLowerBound() + size - 1;
01025 }
01026
01027 unsigned ixIV(const unsigned i) const
01028 {
01029 return i;
01030 }
01031 };
01032
01033
01034
01035
01036
01037
01038
01039 template <>
01040 class CSIndexer<2, USz_t> : private IndexerData<2, USz_t>
01041 {
01042 typedef IndexerData<2, USz_t> IxData;
01043 public:
01044 CSIndexer()
01045 : IxData()
01046 { }
01047
01048 CSIndexer(const IIx_t offset,
01049 const USz_t dim0, const USz_t dim1)
01050 : IxData(dim0, dim1)
01051 { }
01052
01053 void ixDefine(const IIx_t offset,
01054 const USz_t dim0, const USz_t dim1)
01055 {
01056 IxData::m_ixStride = dim0;
01057 }
01058
01059 USz_t ixIndex1D(const USz_t size,
01060 const IIx_t i0, const IIx_t i1) const
01061 {
01062 CH_assert((IxData::ixValidBounds(i1, size)));
01063 CH_assert((i0 < IxData::m_ixStride));
01064 return IxData::m_ixStride*i1 + i0;
01065 }
01066
01067 IIx_t ixDimSize(const USz_t size, const unsigned dim) const
01068 {
01069 return (dim == 2) ? size/IxData::m_ixStride :
01070 IxData::m_ixStride;
01071 }
01072 IIx_t ixLowerBound(const unsigned dim) const
01073 {
01074 return 0;
01075 }
01076 IIx_t ixUpperBound(const USz_t size, const unsigned dim) const
01077 {
01078 return ixDimSize(size, dim) - 1;
01079 }
01080
01081 unsigned ixIV(const unsigned i) const
01082 {
01083 return i;
01084 }
01085 };
01086
01087
01088
01089
01090
01091
01092
01093 template <unsigned Rank, int ArConf>
01094 struct ArTr;
01095 template <unsigned Rank>
01096 struct ArTr<Rank, ArZeroRow>
01097 {
01098 typedef ArSp::USz_t DimT;
01099 typedef ArSp::RSIndexer<Rank, DimT> IndexerT;
01100 };
01101 template <unsigned Rank>
01102 struct ArTr<Rank, ArZeroCol>
01103 {
01104 typedef ArSp::USz_t DimT;
01105 typedef ArSp::CSIndexer<Rank, DimT> IndexerT;
01106 };
01107 template <unsigned Rank>
01108 struct ArTr<Rank, ArRangeRow>
01109 {
01110 typedef CHRange DimT;
01111 typedef ArSp::RSIndexer<Rank, DimT> IndexerT;
01112 typedef int BoxAllowed;
01113 };
01114 template <unsigned Rank>
01115 struct ArTr<Rank, ArRangeCol>
01116 {
01117 typedef CHRange DimT;
01118 typedef ArSp::CSIndexer<Rank, DimT> IndexerT;
01119 typedef int BoxAllowed;
01120 };
01121
01122
01123 }
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 template <typename T,
01253 unsigned Rank,
01254 int ArConf,
01255 typename Alloc>
01256 class CHArray : private ArSp::ArTr<Rank, ArConf>::IndexerT
01257 {
01258 typedef typename ArSp::ArTr<Rank, ArConf>::DimT DimT;
01259 typedef typename ArSp::ArTr<Rank, ArConf>::IndexerT Indexer;
01260 public:
01261
01262
01263 CHArray()
01264 : Indexer(), m_arrayImpl()
01265 { }
01266
01267
01268 CHArray(const DimT &dim6, const DimT &dim5, const DimT &dim4,
01269 const DimT &dim3, const DimT &dim2, const DimT &dim1,
01270 const DimT &dim0)
01271 : Indexer(0, dim6, dim5, dim4, dim3, dim2, dim1, dim0),
01272 m_arrayImpl(dim6*dim5*dim4*dim3*dim2*dim1*dim0)
01273 { }
01274 CHArray(const DimT &dim5, const DimT &dim4, const DimT &dim3,
01275 const DimT &dim2, const DimT &dim1, const DimT &dim0)
01276 : Indexer(0, dim5, dim4, dim3, dim2, dim1, dim0),
01277 m_arrayImpl(dim5*dim4*dim3*dim2*dim1*dim0)
01278 { }
01279 CHArray(const DimT &dim4, const DimT &dim3, const DimT &dim2,
01280 const DimT &dim1, const DimT &dim0)
01281 : Indexer(0, dim4, dim3, dim2, dim1, dim0),
01282 m_arrayImpl(dim4*dim3*dim2*dim1*dim0)
01283 { }
01284 CHArray(const DimT &dim3, const DimT &dim2, const DimT &dim1,
01285 const DimT &dim0)
01286 : Indexer(0, dim3, dim2, dim1, dim0), m_arrayImpl(dim3*dim2*dim1*dim0)
01287 { }
01288 CHArray(const DimT &dim2, const DimT &dim1, const DimT &dim0)
01289 : Indexer(0, dim2, dim1, dim0), m_arrayImpl(dim2*dim1*dim0)
01290 { }
01291 CHArray(const DimT &dim1, const DimT &dim0)
01292 : Indexer(0, dim1, dim0), m_arrayImpl(dim1*dim0)
01293 { }
01294 CHArray(const DimT &dim0)
01295 : Indexer(0, dim0), m_arrayImpl(ArSp::sizeOfDim(dim0))
01296 { }
01297
01298 CHArray(const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
01299 : Indexer(0, D_DEFIV, dimc1, dimc0), m_arrayImpl(iv.product()*dimc1*dimc0)
01300 { }
01301 CHArray(const IntVect &iv, const DimT &dimc0)
01302 : Indexer(0, D_DEFIV, dimc0), m_arrayImpl(iv.product()*dimc0)
01303 { }
01304 CHArray(const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
01305 : Indexer(0, dimc1, dimc0, D_DEFIV), m_arrayImpl(dimc1*dimc0*iv.product())
01306 { }
01307 CHArray(const DimT &dimc0, const IntVect &iv)
01308 : Indexer(0, dimc0, D_DEFIV), m_arrayImpl(dimc0*iv.product())
01309 { }
01310
01311 CHArray(const Box &box, const DimT &dimc1, const DimT &dimc0)
01312 : Indexer(0, D_DEFBOX, dimc1, dimc0),
01313 m_arrayImpl(box.size().product()*dimc1*dimc0)
01314 {
01315
01316
01317 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01318 }
01319 CHArray(const Box &box, const DimT &dimc0)
01320 : Indexer(0, D_DEFBOX, dimc0), m_arrayImpl(box.size().product()*dimc0)
01321 {
01322
01323
01324 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01325 }
01326 CHArray(const DimT &dimc1, const DimT &dimc0, const Box &box)
01327 : Indexer(0, dimc1, dimc0, D_DEFBOX),
01328 m_arrayImpl(dimc1*dimc0*box.size().product())
01329 {
01330
01331
01332 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01333 }
01334 CHArray(const DimT &dimc0, const Box &box)
01335 : Indexer(0, dimc0, D_DEFBOX), m_arrayImpl(dimc0*box.size().product())
01336 {
01337
01338
01339 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01340 }
01341
01342
01343 void define(const DimT &dim6, const DimT &dim5, const DimT &dim4,
01344 const DimT &dim3, const DimT &dim2, const DimT &dim1,
01345 const DimT &dim0)
01346 {
01347 Indexer::ixDefine(0, dim6, dim5, dim4, dim3, dim2, dim1, dim0);
01348 m_arrayImpl.define(dim6*dim5*dim4*dim3*dim2*dim1*dim0);
01349 }
01350 void define(const DimT &dim5, const DimT &dim4, const DimT &dim3,
01351 const DimT &dim2, const DimT &dim1, const DimT &dim0)
01352 {
01353 Indexer::ixDefine(0, dim5, dim4, dim3, dim2, dim1, dim0);
01354 m_arrayImpl.define(dim5*dim4*dim3*dim2*dim1*dim0);
01355 }
01356 void define(const DimT &dim4, const DimT &dim3, const DimT &dim2,
01357 const DimT &dim1, const DimT &dim0)
01358 {
01359 Indexer::ixDefine(0, dim4, dim3, dim2, dim1, dim0);
01360 m_arrayImpl.define(dim4*dim3*dim2*dim1*dim0);
01361 }
01362 void define(const DimT &dim3, const DimT &dim2, const DimT &dim1,
01363 const DimT &dim0)
01364 {
01365 Indexer::ixDefine(0, dim3, dim2, dim1, dim0);
01366 m_arrayImpl.define(dim3*dim2*dim1*dim0);
01367 }
01368 void define(const DimT &dim2, const DimT &dim1, const DimT &dim0)
01369 {
01370 Indexer::ixDefine(0, dim2, dim1, dim0);
01371 m_arrayImpl.define(dim2*dim1*dim0);
01372 }
01373 void define(const DimT &dim1, const DimT &dim0)
01374 {
01375 Indexer::ixDefine(0, dim1, dim0);
01376 m_arrayImpl.define(dim1*dim0);
01377 }
01378 void define(const DimT &dim0)
01379 {
01380 Indexer::ixDefine(0, dim0);
01381 m_arrayImpl.define(ArSp::sizeOfDim(dim0));
01382 }
01383
01384 void define(const IntVect &iv, const DimT &dimc1, const DimT &dimc0)
01385 {
01386 Indexer::ixDefine(0, D_DEFIV, dimc1, dimc0);
01387 m_arrayImpl.define(iv.product()*dimc1*dimc0);
01388 }
01389 void define(const IntVect &iv, const DimT &dimc0)
01390 {
01391 Indexer::ixDefine(0, D_DEFIV, dimc0);
01392 m_arrayImpl.define(iv.product()*dimc0);
01393 }
01394 void define(const DimT &dimc1, const DimT &dimc0, const IntVect &iv)
01395 {
01396 Indexer::ixDefine(0, dimc1, dimc0, D_DEFIV);
01397 m_arrayImpl.define(dimc1*dimc0*iv.product());
01398 }
01399 void define(const DimT &dimc0, const IntVect &iv)
01400 {
01401 Indexer::ixDefine(0, dimc0, D_DEFIV);
01402 m_arrayImpl.define(dimc0*iv.product());
01403 }
01404
01405 void define(const Box &box, const DimT &dimc1, const DimT &dimc0)
01406 {
01407
01408
01409 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01410 Indexer::ixDefine(0, D_DEFBOX, dimc1, dimc0);
01411 m_arrayImpl.define(box.size().product()*dimc1*dimc0);
01412 }
01413 void define(const Box &box, const DimT &dimc0)
01414 {
01415
01416
01417 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01418 Indexer::ixDefine(0, D_DEFBOX, dimc0);
01419 m_arrayImpl.define(box.size().product()*dimc0);
01420 }
01421 void define(const DimT &dimc1, const DimT &dimc0, const Box &box)
01422 {
01423
01424
01425 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01426 Indexer::ixDefine(0, dimc1, dimc0, D_DEFBOX);
01427 m_arrayImpl.define(dimc1*dimc0*box.size().product());
01428 }
01429 void define(const DimT &dimc0, const Box &box)
01430 {
01431
01432
01433 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01434 Indexer::ixDefine(0, dimc0, D_DEFBOX);
01435 m_arrayImpl.define(dimc0*box.size().product());
01436 }
01437
01438
01439 void define(void *const addr,
01440 const DimT &dim6, const DimT &dim5, const DimT &dim4,
01441 const DimT &dim3, const DimT &dim2, const DimT &dim1,
01442 const DimT &dim0)
01443 {
01444 Indexer::ixDefine(0, dim6, dim5, dim4, dim3, dim2, dim1, dim0);
01445 m_arrayImpl.define(addr, dim6*dim5*dim4*dim3*dim2*dim1*dim0);
01446 }
01447 void define(void *const addr,
01448 const DimT &dim5, const DimT &dim4, const DimT &dim3,
01449 const DimT &dim2, const DimT &dim1, const DimT &dim0)
01450 {
01451 Indexer::ixDefine(0, dim5, dim4, dim3, dim2, dim1, dim0);
01452 m_arrayImpl.define(addr, dim5*dim4*dim3*dim2*dim1*dim0);
01453 }
01454 void define(void *const addr,
01455 const DimT &dim4, const DimT &dim3, const DimT &dim2,
01456 const DimT &dim1, const DimT &dim0)
01457 {
01458 Indexer::ixDefine(0, dim4, dim3, dim2, dim1, dim0);
01459 m_arrayImpl.define(addr, dim4*dim3*dim2*dim1*dim0);
01460 }
01461 void define(void *const addr,
01462 const DimT &dim3, const DimT &dim2, const DimT &dim1,
01463 const DimT &dim0)
01464 {
01465 Indexer::ixDefine(0, dim3, dim2, dim1, dim0);
01466 m_arrayImpl.define(addr, dim3*dim2*dim1*dim0);
01467 }
01468 void define(void *const addr,
01469 const DimT &dim2, const DimT &dim1, const DimT &dim0)
01470 {
01471 Indexer::ixDefine(0, dim2, dim1, dim0);
01472 m_arrayImpl.define(addr, dim2*dim1*dim0);
01473 }
01474 void define(void *const addr,
01475 const DimT &dim1, const DimT &dim0)
01476 {
01477 Indexer::ixDefine(0, dim1, dim0);
01478 m_arrayImpl.define(addr, dim1*dim0);
01479 }
01480 void define(void *const addr,
01481 const DimT &dim0)
01482 {
01483 Indexer::ixDefine(0, dim0);
01484 m_arrayImpl.define(addr, ArSp::sizeOfDim(dim0));
01485 }
01486
01487 void define(void *const addr, const IntVect &iv,
01488 const DimT &dimc1, const DimT &dimc0)
01489 {
01490 Indexer::ixDefine(0, D_DEFIV, dimc1, dimc0);
01491 m_arrayImpl.define(addr, iv.product()*dimc1*dimc0);
01492 }
01493 void define(void *const addr, const IntVect &iv, const DimT &dimc0)
01494 {
01495 Indexer::ixDefine(0, D_DEFIV, dimc0);
01496 m_arrayImpl.define(addr, iv.product()*dimc0);
01497 }
01498 void define(void *const addr, const DimT &dimc1, const DimT &dimc0,
01499 const IntVect &iv)
01500 {
01501 Indexer::ixDefine(0, dimc1, dimc0, D_DEFIV);
01502 m_arrayImpl.define(addr, dimc1*dimc0*iv.product());
01503 }
01504 void define(void *const addr, const DimT &dimc0, const IntVect &iv)
01505 {
01506 Indexer::ixDefine(0, dimc0, D_DEFIV);
01507 m_arrayImpl.define(addr, dimc0*iv.product());
01508 }
01509
01510 void define(void *const addr, const Box &box,
01511 const DimT &dimc1, const DimT &dimc0)
01512 {
01513
01514
01515 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01516 Indexer::ixDefine(0, D_DEFBOX, dimc1, dimc0);
01517 m_arrayImpl.define(addr, box.size().product()*dimc1*dimc0);
01518 }
01519 void define(void *const addr, const Box &box, const DimT &dimc0)
01520 {
01521
01522
01523 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01524 Indexer::ixDefine(0, D_DEFBOX, dimc0);
01525 m_arrayImpl.define(addr, box.size().product()*dimc0);
01526 }
01527 void define(void *const addr, const DimT &dimc1, const DimT &dimc0,
01528 const Box &box)
01529 {
01530
01531
01532 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01533 Indexer::ixDefine(0, dimc1, dimc0, D_DEFBOX);
01534 m_arrayImpl.define(addr, dimc1*dimc0*box.size().product());
01535 }
01536 void define(void *const addr, const DimT &dimc0, const Box &box)
01537 {
01538
01539
01540 typedef typename ArSp::ArTr<Rank, ArConf>::BoxAllowed Check;
01541 Indexer::ixDefine(0, dimc0, D_DEFBOX);
01542 m_arrayImpl.define(addr, dimc0*box.size().product());
01543 }
01544
01545
01546 void undefine()
01547 {
01548 CH_assert(isAllocated());
01549 m_arrayImpl.undefine();
01550 }
01551
01552
01553 template <typename T2>
01554 CHArray &operator=(const T2 &val)
01555 {
01556 CH_assert(isAllocated());
01557 T Tval = val;
01558 const T *const pEnd = end();
01559 for (T *p = begin(); p != pEnd;) *p++ = Tval;
01560 return *this;
01561 }
01562
01563
01564 T &operator()(const ArSp::IIx_t i6, const ArSp::IIx_t i5,
01565 const ArSp::IIx_t i4, const ArSp::IIx_t i3,
01566 const ArSp::IIx_t i2, const ArSp::IIx_t i1,
01567 const ArSp::IIx_t i0)
01568 {
01569 CH_assert(isUsable());
01570 return m_arrayImpl.data[
01571 Indexer::ixIndex1D(size(), i6, i5, i4, i3, i2, i1, i0)];
01572 }
01573 T &operator()(const ArSp::IIx_t i5, const ArSp::IIx_t i4,
01574 const ArSp::IIx_t i3, const ArSp::IIx_t i2,
01575 const ArSp::IIx_t i1, const ArSp::IIx_t i0)
01576 {
01577 CH_assert(isUsable());
01578 return m_arrayImpl.data[
01579 Indexer::ixIndex1D(size(), i5, i4, i3, i2, i1, i0)];
01580 }
01581 T &operator()(const ArSp::IIx_t i4, const ArSp::IIx_t i3,
01582 const ArSp::IIx_t i2, const ArSp::IIx_t i1,
01583 const ArSp::IIx_t i0)
01584 {
01585 CH_assert(isUsable());
01586 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i4, i3, i2, i1, i0)];
01587 }
01588 T &operator()(const ArSp::IIx_t i3, const ArSp::IIx_t i2,
01589 const ArSp::IIx_t i1, const ArSp::IIx_t i0)
01590 {
01591 CH_assert(isUsable());
01592 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i3, i2, i1, i0)];
01593 }
01594 T &operator()(const ArSp::IIx_t i2, const ArSp::IIx_t i1,
01595 const ArSp::IIx_t i0)
01596 {
01597 CH_assert(isUsable());
01598 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i2, i1, i0)];
01599 }
01600 T &operator()(const ArSp::IIx_t i1, const ArSp::IIx_t i0)
01601 {
01602 CH_assert(isUsable());
01603 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i1, i0)];
01604 }
01605 T &operator()(const ArSp::IIx_t i0)
01606 {
01607 CH_assert(isUsable());
01608 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i0)];
01609 }
01610 T &operator()(const IntVect& iv, const ArSp::IIx_t c1, const ArSp::IIx_t c0)
01611 {
01612 CH_assert(isUsable());
01613 return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c1, c0)];
01614 }
01615 T &operator()(const IntVect& iv, const ArSp::IIx_t c0)
01616 {
01617 CH_assert(isUsable());
01618 return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c0)];
01619 }
01620 T &operator()(const ArSp::IIx_t c1, const ArSp::IIx_t c0, const IntVect& iv)
01621 {
01622 CH_assert(isUsable());
01623 return m_arrayImpl.data[Indexer::ixIndex1D(size(), c1, c0, D_IXIV)];
01624 }
01625 T &operator()(const ArSp::IIx_t c0, const IntVect& iv)
01626 {
01627 CH_assert(isUsable());
01628 return m_arrayImpl.data[Indexer::ixIndex1D(size(), c0, D_IXIV)];
01629 }
01630
01631
01632 const T &operator()(const ArSp::IIx_t i6, const ArSp::IIx_t i5,
01633 const ArSp::IIx_t i4, const ArSp::IIx_t i3,
01634 const ArSp::IIx_t i2, const ArSp::IIx_t i1,
01635 const ArSp::IIx_t i0) const
01636 {
01637 CH_assert(isUsable());
01638 return m_arrayImpl.data[
01639 Indexer::ixIndex1D(size(), i6, i5, i4, i3, i2, i1, i0)];
01640 }
01641 const T &operator()(const ArSp::IIx_t i5, const ArSp::IIx_t i4,
01642 const ArSp::IIx_t i3, const ArSp::IIx_t i2,
01643 const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
01644 {
01645 CH_assert(isUsable());
01646 return m_arrayImpl.data[
01647 Indexer::ixIndex1D(size(), i5, i4, i3, i2, i1, i0)];
01648 }
01649 const T &operator()(const ArSp::IIx_t i4, const ArSp::IIx_t i3,
01650 const ArSp::IIx_t i2, const ArSp::IIx_t i1,
01651 const ArSp::IIx_t i0) const
01652 {
01653 CH_assert(isUsable());
01654 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i4, i3, i2, i1, i0)];
01655 }
01656 const T &operator()(const ArSp::IIx_t i3, const ArSp::IIx_t i2,
01657 const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
01658 {
01659 CH_assert(isUsable());
01660 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i3, i2, i1, i0)];
01661 }
01662 const T &operator()(const ArSp::IIx_t i2, const ArSp::IIx_t i1,
01663 const ArSp::IIx_t i0) const
01664 {
01665 CH_assert(isUsable());
01666 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i2, i1, i0)];
01667 }
01668 const T &operator()(const ArSp::IIx_t i1, const ArSp::IIx_t i0) const
01669 {
01670 CH_assert(isUsable());
01671 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i1, i0)];
01672 }
01673 const T &operator()(const ArSp::IIx_t i0) const
01674 {
01675 CH_assert(isUsable());
01676 return m_arrayImpl.data[Indexer::ixIndex1D(size(), i0)];
01677 }
01678 const T &operator()(const IntVect& iv,
01679 const ArSp::IIx_t c1, const ArSp::IIx_t c0) const
01680 {
01681 CH_assert(isUsable());
01682 return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c1, c0)];
01683 }
01684 const T &operator()(const IntVect& iv, const ArSp::IIx_t c0) const
01685 {
01686 CH_assert(isUsable());
01687 return m_arrayImpl.data[Indexer::ixIndex1D(size(), D_IXIV, c0)];
01688 }
01689 const T &operator()(const ArSp::IIx_t c1, const ArSp::IIx_t c0,
01690 const IntVect& iv) const
01691 {
01692 CH_assert(isUsable());
01693 return m_arrayImpl.data[Indexer::ixIndex1D(size(), c1, c0, D_IXIV)];
01694 }
01695 const T &operator()(const ArSp::IIx_t c0, const IntVect& iv) const
01696 {
01697 CH_assert(isUsable());
01698 return m_arrayImpl.data[Indexer::ixIndex1D(size(), c0, D_IXIV)];
01699 }
01700
01701
01702 Alloc& getAllocator()
01703 {
01704 return *static_cast<Alloc*>(&m_arrayImpl);
01705 }
01706
01707
01708 T* begin()
01709 {
01710 return m_arrayImpl.data;
01711 }
01712 const T* begin() const
01713 {
01714 return m_arrayImpl.data;
01715 }
01716 T* end()
01717 {
01718 return m_arrayImpl.data + size();
01719 }
01720 const T* end() const
01721 {
01722 return m_arrayImpl.data + size();
01723 }
01724
01725
01726 ArSp::USz_t size() const
01727 {
01728 return m_arrayImpl.size;
01729 }
01730
01731
01732 ArSp::USz_t size(const unsigned dim) const
01733 {
01734 CH_assert(isUsable());
01735 CH_assert(dim < Rank);
01736 return Indexer::ixDimSize(size(), dim+1);
01737 }
01738
01739
01740 ArSp::IIx_t lowerBound(const unsigned dim) const
01741 {
01742 CH_assert(isUsable());
01743 CH_assert(dim < Rank);
01744 return Indexer::ixLowerBound(dim+1);
01745 }
01746
01747
01748 ArSp::IIx_t upperBound(const unsigned dim) const
01749 {
01750 CH_assert(isUsable());
01751 CH_assert(dim < Rank);
01752 return Indexer::ixUpperBound(size(), dim+1);
01753 }
01754
01755
01756 bool isAllocated() const
01757 {
01758 return (m_arrayImpl.data != 0);
01759 }
01760
01761
01762 bool isUsable() const
01763 {
01764 return isAllocated() && size() > 0;
01765 }
01766
01767 private:
01768
01769 CHArray(const CHArray&);
01770 CHArray &operator=(const CHArray&);
01771
01772 struct Array_impl : public Alloc
01773 {
01774 Array_impl()
01775 : size(0), data(0)
01776 { }
01777 Array_impl(const ArSp::USz_t a_size)
01778 : size(a_size), data(0)
01779 {
01780 data = Alloc::allocate(size);
01781 }
01782 ~Array_impl()
01783 {
01784 if (data != 0) undefine();
01785 }
01786 void define(const ArSp::USz_t a_size)
01787 {
01788 if (data != 0) undefine();
01789 size = a_size;
01790 data = Alloc::allocate(size);
01791 }
01792 void define(void *const addr, const ArSp::USz_t a_size)
01793 {
01794 if (data != 0) undefine();
01795 size = a_size;
01796 data = Alloc::allocate(addr, size);
01797 }
01798 void undefine()
01799 {
01800 Alloc::deallocate(data, size);
01801 data = 0;
01802 size = 0;
01803 }
01804 ArSp::USz_t size;
01805 T *data;
01806 };
01807
01808 Array_impl m_arrayImpl;
01809 };
01810
01811
01812 typedef CHArray<Real, 1, ArZeroCol, ArSp::DefaultArrayAlloc<Real> > CHVector;
01813
01814
01815 typedef CHArray<Real, 2, ArZeroCol, ArSp::DefaultArrayAlloc<Real> > CHMatrix;
01816
01817
01818 template<typename T, unsigned Rank, int ArConf, typename Alloc>
01819 std::ostream &operator<<(std::ostream &os,
01820 const CHArray<T, Rank, ArConf, Alloc> &A)
01821 {
01822 CH_assert(A.isAllocated());
01823 const T *p = A.begin();
01824 const T *const pEnd = A.end();
01825 if (p != pEnd) os << *p++;
01826 while (p != pEnd) os << ' ' << *p++;
01827 return os;
01828 }
01829
01830
01831 template<>
01832 inline std::ostream &operator<<(std::ostream &os, const CHMatrix &M)
01833 {
01834 CH_assert(M.isAllocated());
01835 const int prec = 2;
01836 os.setf(std::ios_base::scientific, std::ios_base::floatfield);
01837 os.precision(prec);
01838 const ArSp::USz_t iMax = M.size(0);
01839 const ArSp::USz_t jMax = M.size(1);
01840 for (ArSp::USz_t i = 0; i != iMax; ++i)
01841 {
01842 if (jMax > 0)
01843 {
01844 os << std::setw(prec+7) << M(i, 0);
01845 for (ArSp::USz_t j = 1; j != jMax; ++j)
01846 {
01847 os << ' ' << std::setw(prec+7) << M(i, j);
01848 }
01849 os << std::endl;
01850 }
01851 }
01852 os.setf(std::ios_base::fmtflags(0), std::ios_base::floatfield);
01853 os.precision(6);
01854 return os;
01855 }
01856
01857 namespace ArSp
01858 {
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870 template <typename T>
01871 class NewArrayAlloc
01872 {
01873 public:
01874 T* allocate(const USz_t size)
01875 {
01876 T *const p = new(std::nothrow) T[size];
01877 CH_assert(p != 0);
01878 return p;
01879 }
01880
01881 void deallocate(T *p, const USz_t size)
01882 {
01883 delete[] p;
01884 }
01885 };
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903 class ArrayOfMatrixAlloc
01904 {
01905 public:
01906 ArrayOfMatrixAlloc()
01907 : defined(false)
01908 { }
01909 void define(const USz_t a_m, const USz_t a_n)
01910 {
01911 m = a_m;
01912 n = a_n;
01913 defined = true;
01914 }
01915 CHMatrix* allocate(const USz_t size)
01916 {
01917 CH_assert(defined);
01918 CHMatrix *const M = new(std::nothrow) CHMatrix[size];
01919 CH_assert(M != 0);
01920 const USz_t stride = m*n;
01921 matrixData = new(std::nothrow) Real[size*stride];
01922 CH_assert(matrixData != 0);
01923 for (USz_t i = 0; i != size; ++i)
01924 {
01925 M[i].define(matrixData + i*stride, m, n);
01926 }
01927 return M;
01928 }
01929 void deallocate(CHMatrix *p, const USz_t size)
01930 {
01931 delete[] p;
01932 delete[] matrixData;
01933 }
01934 private:
01935 Real *matrixData;
01936 USz_t m;
01937 USz_t n;
01938 bool defined;
01939 };
01940
01941 }
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977 #ifdef CH_SPACEDIM
01978 #include "NamespaceFooter.H"
01979 #endif
01980 #endif