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__