Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members

flex.h

00001 /* -*- c++ -*- */
00002 /*
00003  * Expresso, a C++ Array template class library
00004  * Copyright (C) 1998,2004 Oskar Enoksson (enok@lysator.liu.se)
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the
00018  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019  * Boston, MA  02111-1307, USA.
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 // Some template magic for use internally by Array<N,T> methods
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 // typedefs and enums
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 // Private data
00450   private:
00452     MultiPtr<T> data;
00454     T *origo;
00456     Ix<N> l;
00458     Ix<N> u;
00461     Ix<N> stride;
00462   };
00463 
00465 // Basic array methods implementation
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 // Functions on Basic arrays:
00858 
00859 }
00860 
00861 #endif

Generated on Wed May 12 13:34:34 2004 for Expresso by doxygen 1.3.3