basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/iterator.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : iterator.hpp
00004 * DESCRIPTION: Iterators
00005 * COPYRIGHT  : (C) 2004  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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 * The abstract iterator class
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     if (rep->ref_count>1) {
00075       rep->ref_count--;
00076       *(const_cast<Iterator_rep**> (&rep))= rep->clone ();
00077     }
00078     */
00079     rep->advance(); return *this; }
00080   const Iterator& operator -- () const {
00081     /*
00082     if (rep->ref_count>1) {
00083       rep->ref_count--;
00084       *(const_cast<Iterator_rep**> (&rep))= rep->clone ();
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 * Formatting information
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 * Output and equality
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   // NOTE: when C involves the generic type, then traversal of the iterator
00140   // is a non trivial operations which may cause trouble (like in 1..10)
00141   // Indeed, the traveral may require operations like < on generic which
00142   // are not defined in the output evaluator.
00143   // return flatten (generic ("iterator"), it);
00144   // (void) it; return "iterator";
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   Iterator it1= copy (it);
00160   register nat h= 20077002;
00161   while (busy (it1)) {
00162     h= (h<<3) ^ (h>>29) ^ Op::op (*it1);
00163     ++it1;
00164   }
00165   return h;
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   Iterator it1= copy (it1b), it2= copy (it2b);
00176   while (busy (it1) && busy (it2)) {
00177     if (Op::not_op (*it1, *it2)) return false;
00178     ++it1; ++it2;
00179   }
00180   return done (it1) && done (it2);
00181   */
00182 }
00183 
00184 HARD_TO_EXACT_IDENTITY_SUGAR(TMPL,Iterator)
00185 HARD_TO_TRUE_IDENTITY_SUGAR(TMPL,Iterator)
00186 
00187 //TRUE_IDENTITY_OP_SUGAR(TMPL,Iterator)
00188 //EXACT_IDENTITY_OP_SUGAR(TMPL,Iterator)
00189 
00190 /******************************************************************************
00191 * Converter iterator
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 * Finite iterators
00227 ******************************************************************************/
00228 
00229 TMPL_DEF
00230 class finite_iterator_rep: public Iterator_rep {
00231   C*  a;      // the items
00232   nat n;      // the number of items
00233   nat i;      // how many items have been processed
00234   nat count;  // how many times do we share a
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 * Ranges
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= C(1), bool strict= true)
00354 {
00355   return Iterator (new range_iterator_rep<C> (start, end, step, strict));
00356 }
00357 
00358 /******************************************************************************
00359 * Joining iterators
00360 ******************************************************************************/
00361 
00362 TMPL_DEF
00363 class join_iterator_rep: public Iterator_rep {
00364   Iterator it1, it2;
00365 
00366 public:
00367   join_iterator_rep (const Iterator it1b, const Iterator it2b):
00368     Iterator_rep (CF (it1b)), it1(it1b), it2(it2b) {}
00369 
00370 protected:
00371   bool is_busy () { return busy (it1) || busy (it2); }
00372   void advance () { if (busy (it1)) ++it1; else ++it2; }
00373   bool is_init () { return init (it1) && init (it2); }
00374   void regress () { if (init (it2)) --it1; else --it2; }
00375   C current () { return busy (it1)? *it1: *it2; }
00376   Iterator_rep* clone () {
00377     return new join_iterator_rep (copy (it1), copy (it2)); }
00378 };
00379 
00380 TMPL Iterator
00381 operator * (const Iterator& it1, const Iterator& it2) {
00382   return Iterator (new join_iterator_rep<C> (it1, it2));
00383 }
00384 
00385 /******************************************************************************
00386 * Lazy iterators
00387 ******************************************************************************/
00388 
00389 template<typename C, typename T>
00390 class lazy_iterator_rep: public Iterator_rep {
00391   T x;
00392   bool initialized;
00393   iterator<C> it;
00394 
00395 public:
00396   lazy_iterator_rep (const T& x2, const Format& fm):
00397     Iterator_rep (fm), x (x2), initialized (false) {}
00398   lazy_iterator_rep (const T& x2, bool init2, const iterator<C> it2,
00399                      const Format& fm):
00400     Iterator_rep (fm), x (x2), initialized (init2), it (it2) {}
00401   void initialize () {
00402     if (initialized) return;
00403     initialized= true;
00404     it= iterate (x);
00405   }
00406 
00407 protected:
00408   bool is_busy () { initialize (); return busy (it); }
00409   void advance () { initialize (); ++it; }
00410   bool is_init () { return !initialized; }
00411   void regress () { initialize (); --it; }
00412   C current ()    { initialize (); return *it; }
00413   Iterator_rep* clone () {
00414     return new lazy_iterator_rep (x, initialized, copy (it), (Format) *this); }
00415 };
00416 
00417 template<typename C, typename T> Iterator
00418 lazy_iterator (const T& x, const Format& fm) {
00419   return Iterator (new lazy_iterator_rep<C,T> (x, fm));
00420 }
00421 
00422 /******************************************************************************
00423 * Big operators on iterators
00424 ******************************************************************************/
00425 
00426 template<typename Op, typename C> C
00427 big (const Iterator& it) {
00428   if (done (it)) {
00429     C r= get_sample (CF (it));
00430     Op::set_neutral (r);
00431     return r;
00432   }
00433   C r= *it;
00434   for (++it; busy (it); ++it)
00435     Op::set_op (r, *it);
00436   return r;
00437 }
00438 
00439 TMPL inline C big_add (const Iterator& it) { return big<add_op> (it); }
00440 TMPL inline C big_mul (const Iterator& it) { return big<mul_op> (it); }
00441 TMPL inline C big_or  (const Iterator& it) { return big<or_op > (it); }
00442 TMPL inline C big_and (const Iterator& it) { return big<and_op> (it); }
00443 TMPL inline C big_min (const Iterator& it) { return big<min_op> (it); }
00444 TMPL inline C big_max (const Iterator& it) { return big<max_op> (it); }
00445 
00446 #undef TMPL_DEF
00447 #undef TMPL
00448 #undef Format
00449 #undef Iterator
00450 #undef Iterator_rep
00451 } // namespace mmx
00452 #endif // __MMX_ITERATOR_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines