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 #include <cassert>
00031 
00032 namespace esso {
00033 
00035 // Some template magic for use internally by Array<N,T> methods
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 // typedefs and enums
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 // Private data
00452   private:
00454     MultiPtr<T> data;
00456     T *origo;
00458     Ix<N> l;
00460     Ix<N> u;
00463     Ix<N> stride;
00464   };
00465 
00467 // Basic array methods implementation
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 // Functions on Basic arrays:
00861 
00862 }
00863 
00864 #endif

Generated on Thu Jun 3 00:21:25 2004 for Expresso by doxygen 1.3.3