basix_doc 0.1
|
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