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