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