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