00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef EXPRESSO_FLEX_HDR
00022 #define EXPRESSO_FLEX_HDR
00023
00024 #include "debug.h"
00025 #include "tmpltool.h"
00026 #include "multiptr.h"
00027 #include "assign.h"
00028 #include "permutation.h"
00029
00030 #include <cassert>
00031
00032 namespace esso {
00033
00035
00036 namespace BasicInternal {
00037
00038 template<bool Method>
00039 class Assign {
00040 public:
00041 template<int N, class T0, class TypeS>
00042 static inline void Do(Array<N,T0> &dest, const Array<N,TypeS> &src) {
00043 dest.Refer(src);
00044 }
00045 };
00046
00047 template<>
00048 class Assign<false> {
00049 public:
00050 template<int N, class T0, class TypeS>
00051 static inline void Do(Array<N,T0> &dest, const Array<N,TypeS> &src) {
00052 dest.Clone(src);
00053 }
00054 };
00055 }
00056
00058
00078 template<int N, class T0>
00079 class Array {
00080 public:
00081 friend class Array<N,typename TmplTools::FlipConst<T0>::T>;
00082
00084
00085 typedef T0 T;
00086 enum { fixrank=0 };
00087 enum { varrank=N };
00088 enum { check=0 };
00089 enum { hasdata=1 };
00090 typedef T0 Type;
00091 typedef Array<N,Iterator<T0> > IteratorType;
00094
00096 inline Array(): data(), origo(0) ,l(0) ,u(0) {}
00099 inline Array(const Ix<N> &len0);
00103 inline Array(const Ix<N> &len0, const Ix<N> &l0);
00106 inline Array(const Array &src):
00107 data(src.data), origo(src.origo), l(src.l), u(src.u), stride(src.stride)
00108 {}
00113 template<class TypeS>
00114 inline Array(const Array<N,TypeS> &src) {
00115 BasicInternal::Assign<(
00116 Array<N,TypeS>::hasdata &&
00117 (TmplTools::IsSame<T,
00118 typename Array<N,TypeS>::T>::check ||
00119 TmplTools::IsSame<typename TmplTools::UnConst<T>::T,
00120 typename Array<N,TypeS>::T>::check))
00121 >::Do(*this,src);
00122 }
00125 inline Array(const Array<N+1,Type> &src, DIMT n, IXTYPE i);
00127 inline Array(IXTYPE i0):
00128 data(i0), origo(data.Data()),l(0) {
00129 TmplTools::TAssert<(N==1)>();
00130 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0);
00131 u[0]=i0;
00132 stride[0]=1;
00133 }
00135 inline Array(IXTYPE i0, IXTYPE i1):
00136 data(i0*i1), origo(data.Data()),l(0) {
00137 TmplTools::TAssert<(N==2)>();
00138 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1);
00139 u[0]=i0;
00140 u[1]=i1;
00141 stride[0]=1;
00142 stride[1]=stride[0]*i0;
00143 }
00145 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2):
00146 data(i0*i1*i2), origo(data.Data()),l(0) {
00147 TmplTools::TAssert<(N==3)>();
00148 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2);
00149 u[0]=i0;
00150 u[1]=i1;
00151 u[2]=i2;
00152 stride[0]=1;
00153 stride[1]=stride[0]*i0;
00154 stride[2]=stride[1]*i1;
00155 }
00157 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3):
00158 data(i0*i1*i2*i3), origo(data.Data()),l(0) {
00159 TmplTools::TAssert<(N==4)>();
00160 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2 && 0<=i3);
00161 u[0]=i0;
00162 u[1]=i1;
00163 u[2]=i2;
00164 u[3]=i3;
00165 stride[0]=1;
00166 stride[1]=stride[0]*i0;
00167 stride[2]=stride[1]*i1;
00168 stride[3]=stride[2]*i2;
00169 }
00171 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4):
00172 data(i0*i1*i2*i3*i4), origo(data.Data()),l(0) {
00173 TmplTools::TAssert<(N==5)>();
00174 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2 && 0<=i3 && 0<=i4);
00175 u[0]=i0;
00176 u[1]=i1;
00177 u[2]=i2;
00178 u[3]=i3;
00179 u[4]=i4;
00180 stride[0]=1;
00181 stride[1]=stride[0]*i0;
00182 stride[2]=stride[1]*i1;
00183 stride[3]=stride[2]*i2;
00184 stride[4]=stride[3]*i3;
00185 }
00187 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4, IXTYPE i5):
00188 data(i0*i1*i2*i3*i4*i5), origo(data.Data()),l(0) {
00189 TmplTools::TAssert<(N==6)>();
00190 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2 && 0<=i3 && 0<=i4 && 0<=i5);
00191 u[0]=i0;
00192 u[1]=i1;
00193 u[2]=i2;
00194 u[3]=i3;
00195 u[4]=i4;
00196 u[5]=i5;
00197 stride[0]=1;
00198 stride[1]=stride[0]*i0;
00199 stride[2]=stride[1]*i1;
00200 stride[3]=stride[2]*i2;
00201 stride[4]=stride[3]*i3;
00202 stride[5]=stride[4]*i4;
00203 }
00207
00210 inline IXTYPE L(DIMT n) const {
00211 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N); return l[n];
00212 }
00216 inline IXTYPE U(DIMT n) const {
00217 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N); return u[n];
00218 }
00223 inline IXTYPE Len(DIMT n) const {
00224 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N); return u[n]-l[n];
00225 }
00233 inline IXTYPE Stride(DIMT n) const {
00234 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N); return stride[n];
00235 }
00241 inline T * Origo() const { return origo; }
00248 inline T * Start() const { return & operator [](l); }
00250 inline const MultiPtr<T> &Data() const { return data; }
00252 inline bool IsNull() const { return data.Data()==0; }
00256
00258 inline bool Dealloc();
00262 inline bool Realloc(const Ix<N> &len0);
00266 inline bool Realloc(const Ix<N> &len0, const Ix<N> &l0);
00271 inline bool Realloc(const Ix<N> &len0, const Ix<N> &l0,
00272 const MultiPtr<T> &data0, T * origo0);
00277 template<class TypeS>
00278 inline bool Realloc(const Array<N,TypeS> &src);
00282 template<class TypeS>
00283 inline bool Refer(const Array<N,TypeS> &src);
00286 inline bool Clone();
00294 template<class TypeS>
00295 inline bool Clone(const Array<N,TypeS> &src);
00296
00301 template<class TypeS>
00302 inline Array & Extend(const Array<N-1,TypeS> &src, IXTYPE l0, IXTYPE u0);
00303
00306 template<class TypeS>
00307 inline Array & Rmdim(const Array<N+1,TypeS> &src, DIMT n, IXTYPE i);
00311 template<class TypeS>
00312 inline Array & operator =(const Array<N,TypeS> &src) {
00313 BasicInternal::Assign<(
00314 Array<N,TypeS>::hasdata &&
00315 (TmplTools::IsSame<T,typename Array<N,TypeS>::T>::check ||
00316 TmplTools::IsSame<typename TmplTools::UnConst<T>::T,
00317 typename Array<N,TypeS>::T>::check))
00318 >::Do(*this,src);
00319 return *this;
00320 }
00322 inline Array & operator =(const Array &src) {
00323 data=src.data;
00324 origo=src.origo;
00325 l=src.l;
00326 u=src.u;
00327 stride=src.stride;
00328 return *this;
00329 }
00331 inline Array & Shift(DIMT n, IXTYPE i);
00333 inline Array & Shift(const Ix<N> &ix);
00335 inline Array & Permute(DIMT n1, DIMT n2);
00337 inline Array & Permute(const Permutation<N> &nx);
00343 inline Array & Restrict(DIMT n, IXTYPE l0, IXTYPE u0);
00345 inline Array & Restrict(const Ix<N> &l0, const Ix<N> &u0);
00347 inline Array & RestrictL(DIMT n, IXTYPE l0);
00349 inline Array & RestrictL(const Ix<N> &l0);
00351 inline Array & RestrictU(DIMT n, IXTYPE u0);
00353 inline Array & RestrictU(const Ix<N> &u0);
00357 inline Array & Flip(DIMT n);
00361 inline Array & Flip(const Ix<N,bool> &r);
00364 inline Array & Reverse(DIMT n);
00367 inline Array & Reverse(const Ix<N,bool> &r);
00370 inline Array & Restride(DIMT n, IXTYPE s);
00373 inline Array & Restride(const Ix<N> &s);
00375
00376 inline T & operator ()(IXTYPE i0) const {
00377 TmplTools::TAssert<(N==1)>();
00378 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]);
00379 return *(origo+stride[0]*i0);
00380 }
00382 inline T & operator ()(IXTYPE i0, IXTYPE i1) const {
00383 TmplTools::TAssert<(N==2)>();
00384 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00385 && l[1]<=i1 && i1<u[1]);
00386 return *(origo+stride[1]*i1+
00387 stride[0]*i0);
00388 }
00390 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2) const {
00391 TmplTools::TAssert<(N==3)>();
00392 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00393 && l[1]<=i1 && i1<u[1]
00394 && l[2]<=i2 && i2<u[2]);
00395 return *(origo+stride[2]*i2+
00396 stride[1]*i1+
00397 stride[0]*i0);
00398 }
00400 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3) const {
00401 TmplTools::TAssert<(N==4)>();
00402 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00403 && l[1]<=i1 && i1<u[1]
00404 && l[2]<=i2 && i2<u[2]
00405 && l[3]<=i3 && i3<u[3]);
00406 return *(origo+stride[3]*i3+
00407 stride[2]*i2+
00408 stride[1]*i1+
00409 stride[0]*i0);
00410 }
00412 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4) const {
00413 TmplTools::TAssert<(N==5)>();
00414 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00415 && l[1]<=i1 && i1<u[1]
00416 && l[2]<=i2 && i2<u[2]
00417 && l[3]<=i3 && i3<u[3]
00418 && l[4]<=i4 && i4<u[4]);
00419 return *(origo+stride[4]*i4+
00420 stride[3]*i3+
00421 stride[2]*i2+
00422 stride[1]*i1+
00423 stride[0]*i0);
00424 }
00426 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4, IXTYPE i5) const {
00427 TmplTools::TAssert<(N==6)>();
00428 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00429 && l[1]<=i1 && i1<u[1]
00430 && l[2]<=i2 && i2<u[2]
00431 && l[3]<=i3 && i3<u[3]
00432 && l[4]<=i4 && i4<u[4]
00433 && l[5]<=i5 && i5<u[5]);
00434 return *(origo+stride[5]*i5+
00435 stride[4]*i4+
00436 stride[3]*i3+
00437 stride[2]*i2+
00438 stride[1]*i1+
00439 stride[0]*i0);
00440 }
00442 inline T & operator [](const Ix<N> &ix) const {
00443 #ifdef EXPRESSO_DEBUG_CHECK_INDEXING_RANGE
00444 for(int k=0; k<N; k++)
00445 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[k]<=ix[k] && ix[k]<u[k]);
00446 #endif
00447 return *(origo+IndexInternal::Recurse<0,N>::SumProd(stride,ix));
00448 }
00449
00451
00452 private:
00454 MultiPtr<T> data;
00456 T *origo;
00458 Ix<N> l;
00460 Ix<N> u;
00463 Ix<N> stride;
00464 };
00465
00467
00468 template<int N, class T0>
00469 inline bool
00470 Array<N,T0>::Dealloc() {
00471 data=MultiPtr<T>();
00472 origo=data.Data();
00473 l=0;
00474 u=0;
00475 stride=0;
00476 return true;
00477 }
00478
00479 template<int N, class T0>
00480 inline bool
00481 Array<N,T0>::Clone() {
00482 return Clone(*this);
00483 }
00484
00485 template<int N, class T0>
00486 inline bool
00487 Array<N,T0>::Realloc(const Ix<N> &len0) {
00488 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00489 for(int k=0; k<varrank; k++)
00490 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00491 #endif
00492 data=MultiPtr<T>(IndexInternal::Recurse<0,N>::Prod(len0));
00493 origo=data.Data();
00494 l=0;
00495 for(int n=0; n<N; n++)
00496 u[n]=len0[n];
00497 stride[0]=1;
00498 for(int n=1; n<N; n++)
00499 stride[n]=stride[n-1]*len0[n-1];
00500 return true;
00501 }
00502
00503 template<int N, class T0>
00504 inline bool
00505 Array<N,T0>::Realloc(const Ix<N> &len0, const Ix<N> &l0) {
00506 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00507 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00508 #endif
00509 data=MultiPtr<T>(IndexInternal::Recurse<0,N>::Prod(len0));
00510 origo=data.Data();
00511 l=l0;
00512 for(int n=0; n<N; n++)
00513 u[n]=len0[n]+l[n];
00514 stride[0]=1;
00515 for(int n=1; n<N; n++)
00516 stride[n]=stride[n-1]*len0[n-1];
00517 origo=origo-IndexInternal::Recurse<0,N>::SumProd(stride,l);
00518 return true;
00519 }
00520
00521 template<int N, class T0>
00522 inline bool
00523 Array<N,T0>::Realloc(const Ix<N> &len0, const Ix<N> &l0,
00524 const MultiPtr<T> &data0, T *origo0) {
00525 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00526 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00527 #endif
00528 data=data0;
00529 origo=origo0;
00530 l=l0;
00531 for(int n=0; n<N; n++)
00532 u[n]=len0[n]+l[n];
00533 stride[0]=1;
00534 for(int n=1; n<N; n++)
00535 stride[n]=stride[n-1]*len0[n-1];
00536 return true;
00537 }
00538
00539 template<int N, class T0>
00540 inline Array<N,T0> &
00541 Array<N,T0>::Shift(DIMT n, IXTYPE i) {
00542 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00543 l[n]+=i;
00544 u[n]+=i;
00545 origo-=i*stride[n];
00546 return *this;
00547 }
00548
00549 template<int N, class T0>
00550 inline Array<N,T0> &
00551 Array<N,T0>::Shift(const Ix<N> &ix) {
00552 for(int n=0; n<N; n++)
00553 Shift(n,ix[n]);
00554 return *this;
00555 }
00556
00557 template<int N, class T0>
00558 inline Array<N,T0> &
00559 Array<N,T0>::Reverse(DIMT n) {
00560 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00561 origo+=stride[n]*(u[n]+l[n]-1);
00562 stride[n]*=-1;
00563 return *this;
00564 }
00565
00566 template<int N, class T0>
00567 inline Array<N,T0> &
00568 Array<N,T0>::Reverse(const Ix<N,bool> &r) {
00569 for(int n=0; n<N; n++) {
00570 if(r[n]) {
00571 origo+=stride[n]*(u[n]+l[n]-1);
00572 stride[n]*=-1;
00573 }
00574 }
00575 return *this;
00576 }
00577
00578 template<int N, class T0>
00579 inline Array<N,T0> &
00580 Array<N,T0>::Flip(DIMT n) {
00581 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00582 stride[n]*=-1;
00583 int tmp=l[n];
00584 l[n]=1-u[n];
00585 u[n]=1-tmp;
00586 return *this;
00587 }
00588
00589 template<int N, class T0>
00590 inline Array<N,T0> &
00591 Array<N,T0>::Flip(const Ix<N,bool> &r) {
00592 for(int n=0; n<N; n++) {
00593 if(r[n]) {
00594 stride[n]*=-1;
00595 int tmp=l[n];
00596 l[n]=1-u[n];
00597 u[n]=1-tmp;
00598 }
00599 }
00600 return *this;
00601 }
00602
00603 template<int N, class T0>
00604 inline Array<N,T0> &
00605 Array<N,T0>::RestrictL(DIMT n, IXTYPE l0) {
00606 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00607 l[n]=std::max(l[n],l0);
00608 if(l[n]>=u[n]) {
00609 l[n]=u[n];
00610 data.clear();
00611 }
00612 return *this;
00613 }
00614
00615 template<int N, class T0>
00616 inline Array<N,T0> &
00617 Array<N,T0>::RestrictL(const Ix<N> &l0) {
00618 for(int n=0; n<N; n++) {
00619 l[n]=std::max(l[n],l0[n]);
00620 if(l[n]>=u[n]) {
00621 l[n]=u[n];
00622 data.clear();
00623 break;
00624 }
00625 }
00626 return *this;
00627 }
00628
00629 template<int N, class T0>
00630 inline Array<N,T0> &
00631 Array<N,T0>::RestrictU(DIMT n, IXTYPE u0) {
00632 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00633 u[n]=std::min(u[n],u0);
00634 if(u[n]<=l[n]) {
00635 u[n]=l[n];
00636 data.clear();
00637 }
00638 return *this;
00639 }
00640
00641 template<int N, class T0>
00642 inline Array<N,T0> &
00643 Array<N,T0>::RestrictU(const Ix<N> &u0) {
00644 for(int n=0; n<N; n++) {
00645 u[n]=std::min(u[n],u0[n]);
00646 if(u[n]<=l[n]) {
00647 u[n]=l[n];
00648 data.clear();
00649 break;
00650 }
00651 }
00652 return *this;
00653 }
00654
00655 template<int N, class T0>
00656 inline Array<N,T0> &
00657 Array<N,T0>::Restrict(DIMT n, IXTYPE l0, IXTYPE u0) {
00658 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00659 l[n]=std::max(l[n],l0);
00660 u[n]=std::min(u[n],u0);
00661 if(l[n]>=u[n]) {
00662 l[n]=u[n];
00663 data.clear();
00664 }
00665 return *this;
00666 }
00667
00668 template<int N, class T0>
00669 inline Array<N,T0> &
00670 Array<N,T0>::Restrict(const Ix<N> &l0, const Ix<N> &u0) {
00671 for(int n=0; n<N; n++) {
00672 l[n]=std::max(l[n],l0[n]);
00673 u[n]=std::min(u[n],u0[n]);
00674 if(l[n]>=u[n]) {
00675 l[n]=u[n];
00676 data.clear();
00677 break;
00678 }
00679 }
00680 return *this;
00681 }
00682
00683 template<int N, class T0>
00684 inline Array<N,T0> &
00685 Array<N,T0>::Permute(DIMT n1, DIMT n2) {
00686 EXPRESSO_DEBUG_CHECK_DIM(0<=n1 && n1<N && 0<=n2 && n2<N);
00687 IXTYPE tmp;
00688 tmp=stride[n1];
00689 stride[n1]=stride[n2];
00690 stride[n2]=tmp;
00691 tmp=l[n1];
00692 l[n1]=l[n2];
00693 l[n2]=tmp;
00694 tmp=u[n1];
00695 u[n1]=u[n2];
00696 u[n2]=tmp;
00697 return *this;
00698 }
00699
00700 template<int N, class T0>
00701 inline Array<N,T0> &
00702 Array<N,T0>::Permute(const Permutation<N> &nx) {
00703 Ix<N> tmp;
00704 stride = nx*stride;
00705 l = nx*l;
00706 u = nx*u;
00707 return *this;
00708 }
00709
00710 template<int N, class T0>
00711 inline Array<N,T0> &
00712 Array<N,T0>::Restride(DIMT n, IXTYPE s) {
00713 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00714 if(l[n]>0) l[n]=(l[n]-1)/s+1; else l[n]=l[n]/s;
00715 if(u[n]>0) u[n]=(u[n]-1)/s+1; else u[n]=u[n]/s;
00716 stride[n]*=s;
00717 return *this;
00718 }
00719
00720 template<int N, class T0>
00721 inline Array<N,T0> &
00722 Array<N,T0>::Restride(const Ix<N> &sx) {
00723 for(int n=0; n<N; n++)
00724 Restride(n,sx[n]);
00725 return *this;
00726 }
00727
00728 template<int N, class T0>
00729 template<class TypeS>
00730 inline bool
00731 Array<N,T0>::Refer(const Array<N,TypeS> &src) {
00732 data=src.Data();
00733 origo=src.Origo();
00734 for(int n=0; n<N; n++) {
00735 l[n]=src.L(n);
00736 u[n]=src.U(n);
00737 stride[n]=src.Stride(n);
00738 }
00739 return true;
00740 }
00741
00742 template<int N, class T0>
00743 template<class TypeS>
00744 inline bool
00745 Array<N,T0>::Realloc(const Array<N,TypeS> &src) {
00746 int totsize=1;
00747 for(int n=0; n<N; n++) {
00748 stride[n]=totsize;
00749 l[n]=src.L(n);
00750 u[n]=src.U(n);
00751 totsize*=u[n]-l[n];
00752 }
00753 data=MultiPtr<T>(totsize);
00754 origo=data.Data()-IndexInternal::Recurse<0,N>::SumProd(stride,l);
00755 return true;
00756 }
00757
00758 template<int N, class T0>
00759 template<class TypeS>
00760 inline bool
00761 Array<N,T0>::Clone(const Array<N,TypeS> &src) {
00762 Array<N,T0> foo;
00763 if(!foo.Realloc(src))
00764 return false;
00765 if(!foo.IsNull())
00766 foo<<=src;
00767 *this=foo;
00768 return true;
00769 }
00770
00771 template<int N, class T0>
00772 template<class TypeS>
00773 inline Array<N,T0> &
00774 Array<N,T0>::Extend(const Array<N-1,TypeS> &src,
00775 IXTYPE l0, IXTYPE u0) {
00776 data=src.Data();
00777 origo=src.Origo();
00778 for(int n=0; n<N-1; n++) {
00779 l[n+1]=src.L(n);
00780 u[n+1]=src.U(n);
00781 stride[n+1]=src.Stride(n);
00782 }
00783 l[0]=l0;
00784 u[0]=u0;
00785 stride[0]=0;
00786 return *this;
00787 }
00788
00789 template<int N, class T0>
00790 template<class TypeS>
00791 inline Array<N,T0> &
00792 Array<N,T0>::Rmdim(const Array<N+1,TypeS> &src, DIMT dim, IXTYPE i) {
00793 data=src.Data();
00794 origo=src.Origo()+src.Stride(dim)*i;
00795 for(int n=0; n<dim; n++) {
00796 l[n]=src.L(n);
00797 u[n]=src.U(n);
00798 stride[n]=src.Stride(n);
00799 }
00800 for(int n=dim+1; n<N+1; n++) {
00801 l[n-1]=src.L(n);
00802 u[n-1]=src.U(n);
00803 stride[n-1]=src.Stride(n);
00804 }
00805 return *this;
00806 }
00807
00808 template<int N, class T0>
00809 inline
00810 Array<N,T0>::Array(const Ix<N> &len0):
00811 data(IndexInternal::Recurse<0,N>::Prod(len0)),
00812 origo(data.Data()), l(0),u(len0)
00813 {
00814 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00815 for(int k=0; k<N; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00816 #endif
00817 stride[0]=1;
00818 for(int n=1; n<N; n++)
00819 stride[n]=stride[n-1]*len0[n-1];
00820 }
00821
00822 template<int N, class T0>
00823 inline
00824 Array<N,T0>::Array(const Ix<N> &len0, const Ix<N> &l0):
00825 data(IndexInternal::Recurse<0,N>::Prod(len0)),
00826 origo(data.Data()), l(l0)
00827 {
00828 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00829 for(int k=0; k<N; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00830 #endif
00831 for(int n=0; n<N; n++)
00832 u[n]=len0[n]+l[n];
00833 stride[0]=1;
00834 for(int n=1; n<N; n++)
00835 stride[n]=stride[n-1]*len0[n-1];
00836 origo=origo-IndexInternal::Recurse<0,N>::SumProd(stride,l);
00837 }
00838
00839 template<int N, class T0>
00840 inline
00841 Array<N,T0>::Array(const Array<N+1,Type> &src, DIMT n, IXTYPE i):
00842 data(src.Data()), origo(src.Origo()+i*src.Stride(n))
00843 {
00844 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N+1);
00845 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(src.L(n)<=i && i<src.U(n));
00846
00847 for(int k=0; k<n; k++) {
00848 l[k]=src.L(k);
00849 u[k]=src.U(k);
00850 stride[k]=src.Stride(k);
00851 }
00852 for(int k=n; k<N; k++) {
00853 l[k]=src.L(k+1);
00854 u[k]=src.U(k+1);
00855 stride[k]=src.Stride(k+1);
00856 }
00857 }
00858
00860
00861
00862 }
00863
00864 #endif