00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_ITERATOR_HPP
00014 #define __MMX_ITERATOR_HPP
00015 #include <basix/function.hpp>
00016
00018
00019 namespace mmx {
00020 #define TMPL_DEF template<typename C>
00021 #define TMPL template<typename C>
00022 #define Format format<C>
00023 #define Iterator iterator<C>
00024 #define Iterator_rep iterator_rep<C>
00025 TMPL class iterator;
00026 TMPL inline bool busy (const Iterator& it);
00027 TMPL inline bool done (const Iterator& it);
00028 TMPL inline bool init (const Iterator& it);
00029 TMPL inline nat hash (const Iterator& it);
00030 TMPL inline nat exact_hash (const Iterator& it);
00031 TMPL inline Iterator copy (const Iterator& it);
00032
00033
00034
00035
00036
00037 TMPL_DEF
00038 class iterator_rep REP_STRUCT_1(C) {
00039 protected:
00040 virtual bool is_busy () = 0;
00041 virtual bool is_done () { return !is_busy (); }
00042 virtual bool is_init () {
00043 ERROR ("not implemented (is_init)"); return false; }
00044 virtual void advance () = 0;
00045 virtual void regress () {
00046 ERROR ("not implemented (regress)"); }
00047 virtual C current () = 0;
00048 virtual Iterator_rep* clone () {
00049 ERROR ("not implemented (clone)"); return NULL; }
00050
00051 public:
00052 inline iterator_rep () {}
00053 inline iterator_rep (const Format& fm): Format (fm) {}
00054 virtual ~iterator_rep () {}
00055 friend class Iterator;
00056 friend bool busy LESSGTR (const Iterator& it);
00057 friend bool done LESSGTR (const Iterator& it);
00058 friend bool init LESSGTR (const Iterator& it);
00059 friend nat hash LESSGTR (const Iterator& it);
00060 friend nat exact_hash LESSGTR (const Iterator& it);
00061 friend Iterator copy LESSGTR (const Iterator& it);
00062 };
00063
00064 TMPL_DEF
00065 class iterator {
00066 INDIRECT_PROTO_1 (iterator, iterator_rep, C)
00067 public:
00068 iterator ();
00069 iterator (const Format& fm);
00070 iterator (const C& c);
00071 inline C operator * () const { return rep->current(); }
00072 const Iterator& operator ++ () const {
00073
00074
00075
00076
00077
00078
00079 rep->advance(); return *this; }
00080 const Iterator& operator -- () const {
00081
00082
00083
00084
00085
00086
00087 rep->regress(); return *this; }
00088 friend bool busy LESSGTR (const Iterator& it);
00089 friend bool done LESSGTR (const Iterator& it);
00090 friend bool init LESSGTR (const Iterator& it);
00091 friend nat hash LESSGTR (const Iterator& it);
00092 friend nat exact_hash LESSGTR (const Iterator& it);
00093 friend Iterator copy LESSGTR (const Iterator& it);
00094 };
00095 INDIRECT_IMPL_1 (iterator, iterator_rep, typename C, C)
00096
00097 TMPL inline bool busy (const Iterator& it) { return it.rep->is_busy (); }
00098 TMPL inline bool done (const Iterator& it) { return it.rep->is_done (); }
00099 TMPL inline bool init (const Iterator& it) { return it.rep->is_init (); }
00100 TMPL inline Iterator copy (const Iterator& it) { return it.rep->clone (); }
00101 TMPL inline Format CF (const Iterator& it) { return it->tfm (); }
00102
00103
00104
00105
00106
00107 TMPL
00108 struct format<Iterator >: public Format {
00109 inline format () {}
00110 inline format (const Format& fm): Format (fm) {}
00111 inline format (const format<Iterator >& fm): Format ((Format) fm) {}
00112 };
00113
00114 TMPL inline format<Iterator >
00115 get_format (const Iterator& it) {
00116 return format<Iterator > (CF (it));
00117 }
00118
00119 TMPL inline Iterator
00120 get_sample (const format<Iterator >& fm) {
00121 return Iterator ((Format) fm);
00122 }
00123
00124
00125
00126
00127
00128 TMPL syntactic
00129 flatten (const syntactic& fun, const Iterator& it) {
00130 vector<syntactic> v;
00131 for (; busy (it); ++it)
00132 v << flatten (*it);
00133 return apply (fun, v);
00134 }
00135
00136 TMPL syntactic
00137 flatten (const Iterator& it) {
00138 return flatten ("iterator", it);
00139
00140
00141
00142
00143
00144
00145 }
00146
00147 TMPL
00148 struct binary_helper<Iterator >: public void_binary_helper<Iterator > {
00149 static inline string short_type_name () {
00150 return "It" * Short_type_name (C); }
00151 static inline generic full_type_name () {
00152 return gen ("Iterator", Full_type_name (C)); }
00153 };
00154
00155 template<typename Op, typename C> nat
00156 unary_hash (const Iterator& it) {
00157 (void) it; return 20077002;
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 }
00168
00169 template<typename Op, typename C> bool
00170 binary_test (const Iterator& it1b, const Iterator& it2b) {
00171 (void) it1b; (void) it2b;
00172 ERROR ("invalid test on iterators");
00173 return false;
00174
00175
00176
00177
00178
00179
00180
00181
00182 }
00183
00184 HARD_TO_EXACT_IDENTITY_SUGAR(TMPL,Iterator)
00185 HARD_TO_TRUE_IDENTITY_SUGAR(TMPL,Iterator)
00186
00187
00188
00189
00190
00191
00192
00193
00194 template<typename C, typename S>
00195 class as_iterator_rep: public Iterator_rep {
00196 iterator<S> it_S;
00197
00198 public:
00199 as_iterator_rep (const iterator<S>& it, const Format& fm):
00200 Iterator_rep (fm), it_S (it) {}
00201
00202 protected:
00203 inline bool is_busy () { return busy (it_S); }
00204 inline bool is_init () { return init (it_S); }
00205 inline void advance () { ++ it_S; }
00206 inline void regress () { -- it_S; }
00207 C current () { return as<C> (* it_S); }
00208 Iterator_rep* clone () {
00209 return new as_iterator_rep (it_S, (Format) *this); }
00210 };
00211
00212 template<typename C, typename S>
00213 struct as_helper<iterator<C>, iterator<S> > {
00214 static inline iterator<C>
00215 cv (const iterator<S>& it) {
00216 format<C> fm= as<format<C> > (CF(it));
00217 return Iterator (new as_iterator_rep<C,S> (it, fm)); }
00218 };
00219
00220 template<typename T,typename F> inline void
00221 set_as (iterator<T>& r, const iterator<F>& x) {
00222 r= iterator<T> (new as_iterator_rep<T,F> (x, CF(r)));
00223 }
00224
00225
00226
00227
00228
00229 TMPL_DEF
00230 class finite_iterator_rep: public Iterator_rep {
00231 C* a;
00232 nat n;
00233 nat i;
00234 nat count;
00235
00236 public:
00237 finite_iterator_rep (C* a2, nat n2, const Format& fm):
00238 Iterator_rep (fm), a(a2), n(n2), i(0), count(1) {}
00239 finite_iterator_rep (C* a2, nat n2, nat i2, nat count2, const Format& fm):
00240 Iterator_rep (fm), a(a2), n(n2), i(i2), count(count2) {}
00241 ~finite_iterator_rep () {
00242 if ((--count) == 0) mmx_delete<C> (a, n); }
00243
00244 protected:
00245 bool is_busy () { return i<n; }
00246 bool is_init () { return i==0; }
00247 void advance () { i++; }
00248 void regress () { i--; }
00249 C current () { return a[i]; }
00250 Iterator_rep* clone () {
00251 return new finite_iterator_rep (a, n, i, count+1, (Format) *this); }
00252 };
00253
00254 TMPL
00255 Iterator::iterator () {
00256 C* a= mmx_new<C> (0);
00257 rep= new finite_iterator_rep<C> (a, 0, Format (no_format ()));
00258 }
00259
00260 TMPL
00261 Iterator::iterator (const Format& fm) {
00262 C* a= mmx_new<C> (0);
00263 rep= new finite_iterator_rep<C> (a, 0, fm);
00264 }
00265
00266 TMPL
00267 Iterator::iterator (const C& c) {
00268 C* a= mmx_new<C> (1);
00269 a[0]= c;
00270 rep= new finite_iterator_rep<C> (a, 1, get_format (c));
00271 }
00272
00273 TMPL Iterator
00274 seq (const C& c1) {
00275 C* a= mmx_new<C> (1);
00276 a[0]= c1;
00277 return Iterator (new finite_iterator_rep<C> (a, 1, get_format (c1)));
00278 }
00279
00280 TMPL Iterator
00281 seq (const C& c1, const C& c2) {
00282 C* a= mmx_new<C> (2);
00283 a[0]= c1; a[1]= c2;
00284 return Iterator (new finite_iterator_rep<C> (a, 2, get_format (c1)));
00285 }
00286
00287 TMPL Iterator
00288 seq (const C& c1, const C& c2, const C& c3) {
00289 C* a= mmx_new<C> (3);
00290 a[0]= c1; a[1]= c2; a[2]= c3;
00291 return Iterator (new finite_iterator_rep<C> (a, 3, get_format (c1)));
00292 }
00293
00294 TMPL Iterator
00295 seq (const C& c1, const C& c2, const C& c3,
00296 const C& c4)
00297 {
00298 C* a= mmx_new<C> (4);
00299 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4;
00300 return Iterator (new finite_iterator_rep<C> (a, 4, get_format (c1)));
00301 }
00302
00303 TMPL Iterator
00304 seq (const C& c1, const C& c2, const C& c3,
00305 const C& c4, const C& c5)
00306 {
00307 C* a= mmx_new<C> (5);
00308 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; a[4]= c5;
00309 return Iterator (new finite_iterator_rep<C> (a, 5, get_format (c1)));
00310 }
00311
00312 TMPL Iterator
00313 seq (const C& c1, const C& c2, const C& c3,
00314 const C& c4, const C& c5, const C& c6)
00315 {
00316 C* a= mmx_new<C> (6);
00317 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; a[4]= c5; a[5]= c6;
00318 return Iterator (new finite_iterator_rep<C> (a, 6, get_format (c1)));
00319 }
00320
00321
00322
00323
00324
00325 TMPL_DEF
00326 class range_iterator_rep: public Iterator_rep {
00327 C start, end, step, now;
00328 bool back, strict;
00329
00330 public:
00331 range_iterator_rep (const C& start2, const C& end2, const C& step2, bool f):
00332 Iterator_rep (get_format (start2)),
00333 start (start2), end (end2), step (step2),
00334 now (start), back (sign (step) < 0), strict (f) {}
00335 ~range_iterator_rep () {}
00336
00337 protected:
00338 bool is_busy () {
00339 return strict? (back? now>end: now<end): (back? now>=end: now<=end); }
00340 bool is_init () { return now == start; }
00341 void advance () { now += step; }
00342 void regress () { now -= step; }
00343 C current () { return now; }
00344 Iterator_rep* clone () {
00345 range_iterator_rep* rep= new range_iterator_rep (start, end, step, strict);
00346 rep->now= now;
00347 return rep;
00348 }
00349 };
00350
00351 TMPL Iterator
00352 range_iterator (const C& start, const C& end,
00353 const C& step= outplace_set_as<C> (1), bool strict= true)
00354 {
00355 return Iterator (new range_iterator_rep<C> (start, end, step, strict));
00356 }
00357
00358 template<typename S, typename T> inline iterator<S>
00359 strict_range (const S& start, const T& end) {
00360 return range_iterator (start, outplace_set_as<S> (end),
00361 outplace_set_as<S> (1), true);
00362 }
00363
00364 template<typename S, typename T> inline iterator<S>
00365 natural_range (const S& start, const T& end) {
00366 return range_iterator (start, outplace_set_as<S> (end),
00367 outplace_set_as<S> (1), false);
00368 }
00369
00370 template<typename S, typename T> inline iterator<S>
00371 downwards_range (const S& start, const T& end) {
00372 return range_iterator (start, outplace_set_as<S> (end),
00373 outplace_set_as<S> (-1), false);
00374 }
00375
00376
00377
00378
00379
00380 TMPL_DEF
00381 class join_iterator_rep: public Iterator_rep {
00382 Iterator it1, it2;
00383
00384 public:
00385 join_iterator_rep (const Iterator it1b, const Iterator it2b):
00386 Iterator_rep (CF (it1b)), it1(it1b), it2(it2b) {}
00387
00388 protected:
00389 bool is_busy () { return busy (it1) || busy (it2); }
00390 void advance () { if (busy (it1)) ++it1; else ++it2; }
00391 bool is_init () { return init (it1) && init (it2); }
00392 void regress () { if (init (it2)) --it1; else --it2; }
00393 C current () { return busy (it1)? *it1: *it2; }
00394 Iterator_rep* clone () {
00395 return new join_iterator_rep (copy (it1), copy (it2)); }
00396 };
00397
00398 TMPL Iterator
00399 operator * (const Iterator& it1, const Iterator& it2) {
00400 return Iterator (new join_iterator_rep<C> (it1, it2));
00401 }
00402
00403
00404
00405
00406
00407 template<typename C, typename T>
00408 class lazy_iterator_rep: public Iterator_rep {
00409 T x;
00410 bool initialized;
00411 iterator<C> it;
00412
00413 public:
00414 lazy_iterator_rep (const T& x2, const Format& fm):
00415 Iterator_rep (fm), x (x2), initialized (false) {}
00416 lazy_iterator_rep (const T& x2, bool init2, const iterator<C> it2,
00417 const Format& fm):
00418 Iterator_rep (fm), x (x2), initialized (init2), it (it2) {}
00419 void initialize () {
00420 if (initialized) return;
00421 initialized= true;
00422 it= iterate (x);
00423 }
00424
00425 protected:
00426 bool is_busy () { initialize (); return busy (it); }
00427 void advance () { initialize (); ++it; }
00428 bool is_init () { return !initialized; }
00429 void regress () { initialize (); --it; }
00430 C current () { initialize (); return *it; }
00431 Iterator_rep* clone () {
00432 return new lazy_iterator_rep (x, initialized, copy (it), (Format) *this); }
00433 };
00434
00435 template<typename C, typename T> Iterator
00436 lazy_iterator (const T& x, const Format& fm) {
00437 return Iterator (new lazy_iterator_rep<C,T> (x, fm));
00438 }
00439
00440
00441
00442
00443
00444 template<typename Op, typename C> C
00445 big (const Iterator& it) {
00446 if (done (it)) {
00447 C r= get_sample (CF (it));
00448 Op::set_neutral (r);
00449 return r;
00450 }
00451 C r= *it;
00452 for (++it; busy (it); ++it)
00453 Op::set_op (r, *it);
00454 return r;
00455 }
00456
00457 TMPL inline C big_add (const Iterator& it) { return big<add_op> (it); }
00458 TMPL inline C big_mul (const Iterator& it) { return big<mul_op> (it); }
00459 TMPL inline C big_or (const Iterator& it) { return big<or_op > (it); }
00460 TMPL inline C big_and (const Iterator& it) { return big<and_op> (it); }
00461 TMPL inline C big_min (const Iterator& it) { return big<min_op> (it); }
00462 TMPL inline C big_max (const Iterator& it) { return big<max_op> (it); }
00463
00464 #undef TMPL_DEF
00465 #undef TMPL
00466 #undef Format
00467 #undef Iterator
00468 #undef Iterator_rep
00469 }
00470 #endif // __MMX_ITERATOR_HPP