00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #ifndef __loaded__array_iterator_h__
00021 #define __loaded__array_iterator_h__
00022 using namespace std;
00023 #line 1 "array-iterator.h++"
00024 #include <cstdio>
00035 template <class T, bool PT> class ArrayIteratorBacking
00036 {
00037  public:
00038   int idx;
00039   int delta;
00040   int next;
00041   T* first;
00042   ArrayIteratorBacking<T,PT>  * _more;
00043   int * pos;
00044   
00045   ArrayIteratorBacking(T* _start, int _delta, int _s, int* target);
00046   ArrayIteratorBacking() : idx(0), delta(0), next(0), _more(NULL), pos(NULL) 
00047     {
00048     };
00049   operator T&() const          
00050     {
00051       return first[idx]; 
00052     };
00053   T& operator*() const         
00054     {
00055       return first[idx]; 
00056     };
00057   T* current() const           
00058     {
00059       return first+idx; 
00060     };
00061   T& operator[](int) const  
00062     {
00063       assert(0); 
00064     };
00065   operator T*() const         
00066     {
00067       return first; 
00068     };
00069   bool more()                  
00070     { 
00071       return idx<next || needmore();
00072     }
00073   bool needmore();
00074   void operator ++()
00075     {
00076       inc();
00077     };
00078   void operator ++(int)
00079     {
00080       inc();
00081     };
00082   void skipBlock()
00083     {
00084       idx = next;
00085       if(PT) (*pos)=-1;
00086     };
00087   bool linear() const
00088     {
00089       return delta == 1;
00090     };
00091   int  size() const
00092     {
00093       return next/delta;
00094     };
00095   void print() const;
00096   T&   operator=(const T& v)
00097     {
00098       first[idx]=v;
00099       return first[idx];
00100     };
00101   template <bool PT2> 
00102     void init(const ArrayIteratorBacking<T,PT2> & b)
00103     {
00104       init(b.current());
00105       if (_more) _more->init(b);
00106     }
00107  private:
00108   void init(T* start)
00109     {
00110       idx = 0;
00111       first=start;
00112       if (PT) (*pos) = 0;
00113     }
00114   void inc()                   
00115     { 
00116       idx += delta; 
00117       if(PT) (*pos)++;
00118     };
00119 };
00120 
00130 template <int D, class T, bool PT, int SM, bool ORDERED>
00131 class ArrayIterator: public ArrayIteratorBacking<T,PT>
00132 { 
00133  private:
00134   Array<SM,T> submatrix;
00135   void setup(const Array<D,T>& m, const Select<D-SM> sel, T* start);
00136  public:
00137   Position<D> position;
00138   Array<D,T> matrix;
00142   ArrayIterator<D,T,PT,SM,ORDERED>()
00143     {
00144     }
00145 
00150   ArrayIterator<D,T,PT,SM,ORDERED>(const Array<D,T> &m)
00151     {
00152       reset(m);
00153     }
00154   ArrayIterator<D,T,PT,SM,ORDERED>(Array<D,T> *m)
00155     { 
00156       reset(*m); 
00157     }
00158   void reset(const Array<D,T> &m)
00159     {
00160       assert(SM==0);
00161       setup(m, Select<D>(), NULL); 
00162     }
00163   void reset()
00164     {
00165       reset(matrix);
00166     }
00167   ArrayIterator<D,T,PT,SM,ORDERED>(const Array<D,T> &m, const Select<D-SM> sel)
00168     {
00169       setup(m, sel, NULL);
00170     }
00171   ArrayIterator<D,T,PT,SM,ORDERED>(const Array<D,T> &m, int d)
00172     { 
00173       setup(m, Select<1>(d), NULL);
00174     };
00175   ArrayIterator<D,T,PT,SM,ORDERED>(const Array<D,T> &m, int x, int y)
00176     {
00177       setup(m, Select<2>(x,y), NULL);
00178     };
00179   int operator[](int i) const  
00180     {
00181       assert(PT); 
00182       return position[i]; 
00183     };
00184   operator Position<D>() const 
00185     {
00186       assert(PT); 
00187       return position; 
00188     };
00189   operator Array<SM,T>&() 
00190     {
00191       return subArray(); 
00192     };
00193   
00194   T&   operator =  (const T& v) 
00195     {
00196       return ArrayIteratorBacking<T,PT>::operator=(v); 
00197     };
00198   T&   operator += (const T& v) 
00199     {
00200       return ((T&)(*this)) += v; 
00201     };
00202   T&   operator -= (const T& v) 
00203     { 
00204       return ((T&)(*this)) -= v; 
00205     };
00206   T&   operator /= (const T& v) 
00207     {
00208       return ((T&)(*this)) /= v; 
00209     };
00210   T&   operator *= (const T& v) 
00211     { 
00212       return ((T&)(*this)) *= v; 
00213     };
00214   bool operator == (const T& v) 
00215     { 
00216       return ((T&)(*this)) == v; 
00217     };
00218   bool operator != (const T& v) 
00219     { 
00220       return ((T&)(*this)) != v; 
00221     };
00222  private:
00223   Array<SM,T>& subArray()
00224     {
00225       assert(SM);
00226       submatrix . setAddress(ArrayIteratorBacking<T,PT>::current());
00227       return submatrix; 
00228     };
00229 };
00230 
00231 template<class T, bool PT>
00232 bool ArrayIteratorBacking<T,PT>::needmore()
00233 {
00234   if (_more)
00235     {
00236       _more->inc();
00237       if (_more->more())
00238         {
00239           init(_more->current());
00240           return true;
00241         }
00242     }
00243   return false;
00244 };
00245 
00246 template <class T, bool PT>
00247 ArrayIteratorBacking<T,PT>::ArrayIteratorBacking(T* _start, int _delta, 
00248                                                  int _s, int* target) : 
00249   idx(0), delta(_delta), next(_s*_delta), first(_start), 
00250   _more(NULL), pos(target)
00251 {
00252   if (PT)
00253     {
00254       assert(pos);
00255       (*pos)=0;
00256     }
00257 };
00258 
00259 
00260 
00261 
00262 template <int D, class T, bool PT, int SM, bool ORDERED>
00263 void ArrayIterator<D,T,PT,SM,ORDERED>::setup(const Array<D,T>& m, 
00264                                              const Select<D-SM> selected, 
00265                                              T* start)
00266 {
00267   matrix = m;
00268   const int SEL = D - SM;
00269   
00270   if(matrix.empty()) 
00271     {
00272       ArrayIteratorBacking<T,PT>::idx = 0;
00273       ArrayIteratorBacking<T,PT>::first = NULL;
00274       ArrayIteratorBacking<T,PT>::delta = 0;
00275       ArrayIteratorBacking<T,PT>::next = 0;
00276       ArrayIteratorBacking<T,PT>::_more = NULL;
00277       return;
00278     }
00279   
00280   Delta<SEL>    deltas;
00281   Size<SEL>     sizes;
00282   if (SEL==D)
00283     {
00284       deltas.set(matrix.delta());
00285       sizes.set(matrix.size());
00286     }
00287   else
00288     {
00289       deltas.set(matrix.delta().select(selected));
00290       sizes.set(matrix.size().select(selected));
00291     }
00292   Position<SEL> addr;
00293   if (PT)
00294     for(int i = 0 ; i < SEL ; i++) addr[i]=i;
00295   
00296   if (!ORDERED)
00297     
00298     for(int d = SEL - 1 ; d >= 1 ; d--)
00299       {
00300         int mi = d, mv = deltas[mi];
00301         for(int i = mi - 1 ; i>=0 ; i--)
00302           if (deltas[i]<mv)
00303             mv=deltas[mi=i];
00304         if (mi!=d)
00305           {
00306             int t = deltas[mi];
00307             int u = sizes[mi];
00308             deltas[mi]=deltas[d];
00309             sizes[mi]=sizes[d];
00310             deltas[d]=t;
00311             sizes[d]=u;
00312             if (PT)
00313               {
00314                 int v = addr[mi];
00315                 addr[mi]=addr[d];
00316                 addr[d]=v;
00317               }
00318           }
00319       }
00320   
00331   if (!PT)
00332     {
00333       bool combined = false;
00334       for(int dim = 0 ; dim < SEL - 1 ; dim++)
00335         {
00336           
00337           const int into = dim + 1;
00338           if (deltas[dim] == deltas[into]*sizes[into])
00339             {
00340               
00341               
00342               
00343               sizes[into]*=sizes[dim];
00344               deltas[dim]=0;
00345               sizes[dim]=0;
00346               combined=true;
00347             }
00348         }
00349       
00350       
00351       
00352       
00353       if (!ORDERED)
00354         if (combined)
00355           for(int d = SEL - 1 ; d >= 1 ; d--)
00356             {
00357               int ma = d, mv = sizes[ma];
00358               for(int i = ma - 1 ; i>=0 ; i--)
00359                 if (sizes[i]>mv)
00360                   mv=sizes[ma=i];
00361               if (ma!=d)
00362                 {
00363                   int t = deltas[ma];
00364                   int u = sizes[ma];
00365                   deltas[ma]=deltas[d];
00366                   sizes[ma]=sizes[d];
00367                   deltas[d]=t;
00368                   sizes[d]=u;
00369                 }
00370             }
00371     }
00372 
00378   if (start==NULL) start = matrix.address(0);
00379   ArrayIteratorBacking<T,PT> * next_iterator = NULL;
00380   for(int dim = 0; dim < SEL - 1 ; dim++)
00381     {
00382       if (!sizes[dim]) continue;
00383       int * posfield = NULL;
00384       if (PT) posfield = &(position[selected[addr[dim]]]);
00385       ArrayIteratorBacking<T,PT> * new_iterator;
00386       new_iterator = new ArrayIteratorBacking<T,PT>(start, deltas[dim], 
00387                                                     sizes[dim], posfield);
00388       new_iterator->_more = next_iterator;
00389       next_iterator = new_iterator;
00390     }
00391   
00392   ArrayIteratorBacking<T,PT>::idx = 0;
00393   ArrayIteratorBacking<T,PT>::first = start;
00394   ArrayIteratorBacking<T,PT>::delta = deltas[SEL-1];
00395   ArrayIteratorBacking<T,PT>::next  = deltas[SEL-1]*sizes[SEL-1];
00396   if (PT) ArrayIteratorBacking<T,PT>::pos = &(position[selected[addr[SEL-1]]]);
00397   ArrayIteratorBacking<T,PT>::_more = next_iterator;
00398 
00403   if (SM)
00404     {
00405       Select<SM> remaining;
00406       int j = 0;
00407       for(int i = 0 ; i < D ; i ++)
00408         if (!selected.has(i)) remaining[j++]=i;
00409       assert(j==SM);
00410       submatrix = matrix(remaining);
00411     }
00412 }
00413 
00414 template<class T, bool PT>
00415 void ArrayIteratorBacking<T,PT>::print() const
00416 {
00417   if (PT)
00418     {
00419       assert(pos);
00420       printf("Idx = %d; Delta = %d; Size = %d; Next = %d Pos = %d\n",
00421              idx,delta,next/delta,next,*pos);
00422     }
00423   else
00424     printf("Idx = %d; Delta = %d; Size = %d; Next = %d\n",
00425            idx,delta,next/delta,next);
00426   if (_more) _more->print();
00427   else printf("-------------------\n");
00428 }
00429 #endif // __loaded__array_iterator_h__