basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : table.hpp 00004 * DESCRIPTION: Hash tables 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_TABLE_HPP 00014 #define __MMX_TABLE_HPP 00015 #include <basix/list.hpp> 00016 #include <basix/pair.hpp> 00017 00019 00020 namespace mmx { 00021 struct exact_eq_table; 00022 #define TMPL_DEF template<typename C, typename T, typename V= exact_eq_table> 00023 #define TMPL template<typename C, typename T, typename V> 00024 #define TMPLK template<typename C, typename T, typename V, typename K> 00025 #define Format1 format<C> 00026 #define Format2 format<T> 00027 #define Table table<C,T,V> 00028 #define Table_rep table_rep<C,T,V> 00029 TMPL class table_rep; 00030 TMPL class table; 00031 TMPL class entries_iterator_rep; 00032 TMPL class table_iterator_rep; 00033 TMPL inline C& I (Table& t); 00034 TMPL inline const C& I (const Table& t); 00035 TMPL inline const C& read_I (const Table& t); 00036 TMPL inline nat N (const Table& t); 00037 TMPL inline void simplify (Table& t); 00038 TMPL bool operator == (const Table& t1, const Table& t2); 00039 00040 /****************************************************************************** 00041 * Different kinds of tables 00042 ******************************************************************************/ 00043 00044 struct hard_eq_table { 00045 typedef hard_eq_op key_op; 00046 typedef equal_op val_op; 00047 }; 00048 00049 struct exact_eq_table { 00050 typedef exact_eq_op key_op; 00051 typedef equal_op val_op; 00052 }; 00053 00054 struct equal_table { 00055 typedef equal_op key_op; 00056 typedef equal_op val_op; 00057 }; 00058 00059 /****************************************************************************** 00060 * Table class and its representation class 00061 ******************************************************************************/ 00062 00063 TMPL_DEF 00064 class table_rep REP_STRUCT_2(C,T) { 00065 nat size; // size of table (nr of entries) 00066 nat n; // nr of keys (a power of two) 00067 C* init; // default entry 00068 list<pair<T,C> >* a; // the array of entries 00069 00070 public: 00071 Table_rep (nat n2, const Format1& fm1, const Format2& fm2): 00072 encapsulate1<Format1 > (fm1), 00073 encapsulate2<Format2 > (fm2), 00074 size (0), n (n2), 00075 init (NULL), 00076 a (mmx_new<list<pair<T,C> > > (n)) 00077 { 00078 //mmout << "[+init=" << init << "," << this 00079 //<< "]" << flush_now; 00080 } 00081 Table_rep (const C& init2, nat n2, const Format2& fm2): 00082 encapsulate1<Format1 > (get_format (init2)), 00083 encapsulate2<Format2 > (fm2), 00084 size (0), n (n2), 00085 init (mmx_new_one<C> (init2)), 00086 a (mmx_new<list<pair<T,C> > > (n)) 00087 { 00088 //mmout << "[+init=" << init << "," << this 00089 //<< ";" << ((int*) ((void*) init))[-1] 00090 //<< "]" << flush_now; 00091 } 00092 ~Table_rep () { 00093 //mmout << "[-init=" << init << "," << this; 00094 //if (init != NULL) 00095 //mmout << ";" << ((int*) ((void*) init))[-1]; 00096 //mmout << "]" << flush_now; 00097 if (init != NULL) mmx_delete_one<C> (init); 00098 mmx_delete<list<pair<T,C> > > (a, n); } 00099 inline void lazy_initialize () const { 00100 if (init == NULL) { 00101 *((C**) ((void*) &init))= mmx_new_one<C> (); 00102 //mmout << "[:init=" << init << "," << this 00103 //<< ";" << ((int*) ((void*) init))[-1] 00104 //<< "]" << flush_now; 00105 } 00106 } 00107 void resize (nat n); 00108 void reset (const T& x); 00109 bool contains (const T& x) const; 00110 bool get (const T& x, C& y) const; 00111 const C& get (const T& x) const; 00112 C& set (const T& x); 00113 void simplify (); 00114 double complexity () const; 00115 00116 friend class Table; 00117 friend class entries_iterator_rep<C,T,V>; 00118 friend class table_iterator_rep<C,T,V>; 00119 friend C& I LESSGTR (Table& t); 00120 friend const C& I LESSGTR (const Table& t); 00121 friend const C& read_I LESSGTR (const Table& t); 00122 friend nat N LESSGTR (const Table& t); 00123 friend bool operator == LESSGTR (const Table& t1, const Table& t2); 00124 }; 00125 00126 TMPL_DEF 00127 class table { 00128 INDIRECT_PROTO_3 (table, table_rep, C, T, V) 00129 inline table (): 00130 rep (new Table_rep (1, Format1 (no_format ()), Format2 (no_format ()))) {} 00131 inline table (const Format1& fm1, const Format2& fm2): 00132 rep (new Table_rep (1, fm1, fm2)) {} 00133 template<typename K> inline table (const K& i, nat n=1): 00134 rep (new Table_rep (as<C> (i), n, Format2 ())) {} 00135 template<typename K> inline table (const K& i, const Format2& fm2, nat n=1): 00136 rep (new Table_rep (as<C> (i), n, fm2)) {} 00137 inline table (const iterator<pair<T,C> >& it): 00138 rep (new Table_rep (1, CF(it).format1 (), CF(it).format2 ())) { 00139 for (; busy (it); ++it) rep->set ((*it).x1)= (*it).x2; } 00140 template<typename K> inline const C& operator [] (const K& x) const { 00141 return rep->get (as<T> (x)); } 00142 inline const C& operator [] (const T& x) const { 00143 return rep->get (x); } 00144 template<typename K> inline C& operator [] (const K& x) { 00145 secure (); return rep->set (as<T> (x)); } 00146 inline C& operator [] (const T& x) { 00147 secure (); return rep->set (x); } 00148 inline Format1 coefficient1_format () const { 00149 return (Format1) (encapsulate1<Format1 >) (*rep); } 00150 inline Format2 coefficient2_format () const { 00151 return (Format2) (encapsulate2<Format2 >) (*rep); } 00152 friend void simplify LESSGTR (Table& t); 00153 }; 00154 INDIRECT_IMPL_3 (table, table_rep, typename C, C, typename T, T, typename V, V) 00155 DEFINE_BINARY_FORMAT_3 (table) 00156 00157 STYPE_TO_TYPE(TMPL,scalar_type,Table,C); 00158 00159 TMPL inline Format1 CF1 (const Table& t) { return t.coefficient1_format (); } 00160 TMPL inline Format2 CF2 (const Table& t) { return t.coefficient2_format (); } 00161 00162 TMPLK inline const C& read (const Table& t, const K& x) { 00163 return t[as<T> (x)]; } 00164 TMPLK inline void reset (Table& t, const K& x) { 00165 t.secure(); inside (t) -> reset (as<T> (x)); } 00166 TMPLK inline bool contains (const Table& t, const K& x) { 00167 return t->contains (as<T> (x)); } 00168 TMPLK inline void inside_set (const Table& t, const K& x, const C& v) { 00169 inside (t) -> set (as<T> (x)) = v; } 00170 00171 TMPL inline void simplify (Table& t) { 00172 t.secure(); t.rep->simplify (); } 00173 TMPL inline const C& read (const Table& t, const T& x) { 00174 return t[x]; } 00175 TMPL inline void reset (Table& t, const T& x) { 00176 t.secure(); inside (t) -> reset (x); } 00177 TMPL inline bool contains (const Table& t, const T& x) { 00178 return t->contains (x); } 00179 TMPL inline void inside_set (const Table& t, const T& x, const C& v) { 00180 inside (t) -> set (x) = v; } 00181 00182 TMPL struct species_type_information<Table > { 00183 static const nat id= SPECIES_TABLE; }; 00184 00185 template<typename D, typename C, typename T> 00186 struct as_helper<table<D,T>,table<C,T> > { 00187 static inline table<D,T> 00188 cv (const table<C,T>& t) { 00189 table<D,T> r (as<D> (I (t)), CF2(t)); 00190 for (iterator<T> it= entries (t); busy (it); ++it) 00191 r[*it]= as<D> (t[*it]); 00192 return r; 00193 } 00194 }; 00195 00196 /****************************************************************************** 00197 * Basic access routines for tables 00198 ******************************************************************************/ 00199 00200 TMPL inline C& 00201 I (Table& t) { 00202 t->lazy_initialize (); 00203 return *t->init; 00204 } 00205 00206 TMPL inline const C& 00207 I (const Table& t) { 00208 t->lazy_initialize (); 00209 return *t->init; 00210 } 00211 00212 TMPL inline const C& 00213 read_I (const Table& t) { 00214 t->lazy_initialize (); 00215 return *t->init; 00216 } 00217 00218 TMPL inline nat 00219 N (const Table& t) { 00220 return t->size; 00221 } 00222 00223 TMPL void 00224 Table_rep::resize (nat n2) { 00225 nat i, oldn= n; 00226 list<pair<T,C> >* olda= a; 00227 n= n2; 00228 a= mmx_new<list<pair<T,C> > > (n); 00229 for (i=0; i<oldn; i++) { 00230 list<pair<T,C> > l (olda [i]); 00231 while (!is_nil (l)) { 00232 nat code= V::key_op::hash_op (read_car(l).x1); 00233 list<pair<T,C> >& newl= a [code & (n-1)]; 00234 newl= cons (read_car (l), newl); 00235 l= read_cdr (l); 00236 } 00237 } 00238 mmx_delete<list<pair<T,C> > > (olda, oldn); 00239 //double acc= 0.0; 00240 //for (i=0; i<n; i++) 00241 //acc += N(a[i]) * N(a[i]); 00242 //mmout << "Access ratio: " << (acc/n) << " out of " << n << "\n"; 00243 } 00244 00245 TMPL bool 00246 Table_rep::contains (const T& x) const { 00247 list<pair<T,C> > l (a [V::key_op::hash_op (x) & (n-1)]); 00248 while (!is_nil (l)) { 00249 if (V::key_op::op (read_car (l).x1, x)) return true; 00250 l= read_cdr (l); 00251 } 00252 return false; 00253 } 00254 00255 TMPL bool 00256 Table_rep::get (const T& x, C& y) const { 00257 list<pair<T,C> > l (a [V::key_op::hash_op (x) & (n-1)]); 00258 while (!is_nil (l)) { 00259 if (V::key_op::op (read_car (l).x1, x)) { 00260 y= read_car (l).x2; 00261 return true; 00262 } 00263 l= read_cdr (l); 00264 } 00265 return false; 00266 } 00267 00268 TMPL C& 00269 Table_rep::set (const T& x) { 00270 register nat hv= V::key_op::hash_op (x); 00271 list<pair<T,C> >* l= &(a [hv & (n-1)]); 00272 while (!is_nil (*l)) { 00273 if (V::key_op::op (read_car (*l).x1, x)) 00274 return car (*l).x2; 00275 l= &cdr (*l); 00276 } 00277 //mmout << "size= " << size << ", n= " << n << "\n"; 00278 if (size>=n) resize (n<<1); 00279 //mmout << "Resized\n"; 00280 lazy_initialize (); 00281 l= &a [hv & (n-1)]; 00282 *l= cons (pair<T,C> (x, *init), *l); 00283 size ++; 00284 return car (*l).x2; 00285 } 00286 00287 TMPL const C& 00288 Table_rep::get (const T& x) const { 00289 list<pair<T,C> > l (a [V::key_op::hash_op (x) & (n-1)]); 00290 while (!is_nil (l)) { 00291 if (V::key_op::op (read_car (l).x1, x)) return read_car (l).x2; 00292 l= read_cdr (l); 00293 } 00294 lazy_initialize (); 00295 return *init; 00296 } 00297 00298 TMPL void 00299 Table_rep::reset (const T& x) { 00300 list<pair<T,C> > *l= &(a [V::key_op::hash_op (x) & (n-1)]); 00301 while (!is_nil (*l)) { 00302 if (V::key_op::op (read_car (*l).x1, x)) { 00303 *l= read_cdr (*l); 00304 size --; 00305 if (size < (n>>1)) resize (n>>1); 00306 return; 00307 } 00308 l= &cdr (*l); 00309 } 00310 } 00311 00312 TMPL void 00313 Table_rep::simplify () { 00314 lazy_initialize (); 00315 for (nat i=0; i<n; i++) { 00316 list<pair<T,C> > *l= &(a[i]); 00317 while (!is_nil (*l)) { 00318 if (V::val_op::op (read_car (*l).x2, *init)) { 00319 *l= read_cdr (*l); 00320 size --; 00321 } 00322 else l= &cdr (*l); 00323 } 00324 } 00325 while (size < (n>>1)) resize (n>>1); 00326 } 00327 00328 TMPL double 00329 Table_rep::complexity () const { 00330 double sum= 0.0; 00331 //mmout << "{"; 00332 for (nat i=0; i<n; i++) { 00333 nat l= N(a[i]); 00334 sum += l*l; 00335 //mmout << " " << l; 00336 } 00337 //mmout << " }"; 00338 return sum / n; 00339 } 00340 00341 /****************************************************************************** 00342 * Iterators 00343 ******************************************************************************/ 00344 00345 TMPL_DEF 00346 class entries_iterator_rep: public iterator_rep<T> { 00347 Table t; // the table to traverse 00348 nat i; // current entry in table 00349 list<pair<T,C> > l; // current list 00350 00351 protected: 00352 entries_iterator_rep (const Table& t2, nat i2, const list<pair<T,C> >& l2): 00353 iterator_rep<T> (CF1(t2)), t(t2), i(i2), l(l2) {} 00354 void spool () { 00355 while (is_nil (l)) { 00356 i++; 00357 if (i >= t->n) break; 00358 l= t->a[i]; 00359 } 00360 } 00361 bool is_busy () { return i<t->n; } 00362 void advance () { l= read_cdr (l); spool (); } 00363 T current () { return read_car (l).x1; } 00364 iterator_rep<T>* clone () { return new entries_iterator_rep (t, i, l); } 00365 00366 public: 00367 entries_iterator_rep (const Table& t2): 00368 t(t2), i(0), l(t->a[0]) { spool (); } 00369 }; 00370 00371 TMPL iterator<T> 00372 entries (const Table& t) { 00373 return iterator<T> (new entries_iterator_rep<C,T,V> (t)); 00374 } 00375 00376 TMPL_DEF 00377 class table_iterator_rep: public iterator_rep<pair<T,C> > { 00378 Table t; // the table to traverse 00379 nat i; // current entry in table 00380 list<pair<T,C> > l; // current list 00381 00382 protected: 00383 table_iterator_rep (const Table& t2, nat i2, const list<pair<T,C> >& l2): 00384 iterator_rep<pair<T,C> > (format<pair<T,C> > (CF1 (t2), CF2 (t2))), 00385 t(t2), i(i2), l(l2) {} 00386 void spool () { 00387 while (is_nil (l)) { 00388 i++; 00389 if (i >= t->n) break; 00390 l= t->a[i]; 00391 } 00392 } 00393 bool is_busy () { return i<t->n; } 00394 void advance () { l= read_cdr (l); spool (); } 00395 pair<T,C> current () { return read_car (l); } 00396 iterator_rep<pair<T,C> >* clone () { 00397 return new table_iterator_rep (t, i, l); } 00398 00399 public: 00400 table_iterator_rep (const Table& t2): 00401 t(t2), i(0), l(t->a[0]) { spool (); } 00402 }; 00403 00404 TMPL iterator<pair<T,C> > 00405 iterate (const Table& t) { 00406 return iterator<pair<T,C> > (new table_iterator_rep<C,T,V> (t)); 00407 } 00408 00409 /****************************************************************************** 00410 * Printing tables 00411 ******************************************************************************/ 00412 00413 TMPL syntactic 00414 flatten (const Table& t) { 00415 vector<syntactic> v; 00416 for (iterator<pair<T,C> > it= iterate (t); busy (it); ++it) 00417 v << flatten (*it); 00418 return apply ("table", v); 00419 } 00420 00421 TMPL 00422 struct binary_helper<Table >: public void_binary_helper<Table > { 00423 static inline string short_type_name () { 00424 return "T" * Short_type_name (C) * Short_type_name (T); } 00425 static inline generic full_type_name () { 00426 return gen ("Table", Full_type_name (T), Full_type_name (C)); } 00427 static inline generic disassemble (const Table& t) { 00428 vector<generic> v; 00429 v << as<generic> (I(t)); 00430 for (iterator<pair<T,C> > it= iterate (t); busy (it); ++it) 00431 v << as<generic> (*it); 00432 return as<generic> (v); } 00433 static inline Table assemble (const generic& x) { 00434 vector<generic> v= as<vector<generic> > (x); 00435 Table t (as<C> (v[0])); 00436 for (nat i=1; i<N(v); i++) { 00437 pair<T,C> p= as<pair<T,C> > (v[i]); 00438 t[p.x1]= p.x2; 00439 } 00440 return t; } 00441 static inline void write (const port& out, const Table& t) { 00442 binary_write<C> (out, I (t)); 00443 binary_write<Format2 > (out, CF2(t)); 00444 binary_write<nat> (out, N (t)); 00445 for (iterator<T> it= entries (t); busy (it); ++it) { 00446 binary_write<T> (out, *it); 00447 binary_write<C> (out, t[*it]); } } 00448 static inline Table read (const port& in) { 00449 C init= binary_read<C> (in); 00450 Format2 fm2= binary_read<Format2 > (in); 00451 Table t (init, fm2); 00452 nat n= binary_read<nat> (in); 00453 for (nat i=0; i<n; i++) { 00454 T key= binary_read<T> (in); 00455 t[key]= binary_read<C> (in); 00456 } 00457 return t; } 00458 }; 00459 00460 /****************************************************************************** 00461 * Abstract operations on tables 00462 ******************************************************************************/ 00463 00464 template<typename Op, typename C, typename T, typename V> nat 00465 unary_hash (const Table& t) { 00466 // we add all hash codes of the element pairs; don't "cycle", 00467 // because the order of the element pairs is not uniquely determined 00468 nat h=54321; 00469 for (iterator<pair<T,C> > it= iterate (t); busy (it); ++it) { 00470 pair<T,C> p= *it; 00471 nat key_h= V::key_op::hash_op (p.x1); 00472 nat val_h= Op::op (p.x2); 00473 h += (key_h << 5) ^ (key_h >> 27) ^ val_h; 00474 } 00475 return h; 00476 } 00477 00478 TMPL Table 00479 copy (const Table& t) { 00480 Table r (I(t), CF2(t)); 00481 for (iterator<T> it= entries (t); busy (it); ++it) 00482 r[*it]= t[*it]; 00483 return r; 00484 } 00485 00486 template<typename Op, typename C, typename T, typename V> Table 00487 unary_map (const Table& t) { 00488 Table r (Op::op (I(t)), CF2(t)); 00489 for (iterator<T> it= entries (t); busy (it); ++it) 00490 r[*it]= Op::op (t[*it]); 00491 simplify (r); 00492 return r; 00493 } 00494 00495 template<typename Op, typename C, typename T, typename V> Table 00496 binary_map (const Table& t, const Table& u) { 00497 Table r (Op::op (I(t), I(u)), CF2(t)); 00498 for (iterator<T> it= entries (t); busy (it); ++it) 00499 r[*it]= Op::op (t[*it], u[*it]); 00500 for (iterator<T> it= entries (u); busy (it); ++it) 00501 if (!(t->contains (*it))) 00502 r[*it]= Op::op (t[*it], u[*it]); 00503 simplify (r); 00504 return r; 00505 } 00506 00507 template<typename Op, typename C, typename T, typename V, typename X> Table 00508 binary_map_scalar (const Table& t, const X& x) { 00509 Table r (Op::op (I(t), x), CF2(t)); 00510 for (iterator<T> it= entries (t); busy (it); ++it) 00511 r[*it]= Op::op (t[*it], x); 00512 simplify (r); 00513 return r; 00514 } 00515 00516 template<typename Op, typename C, typename T, typename V> Table& 00517 unary_set (Table& t, const Table& u) { 00518 Op::set_op (I(t), I(u)); 00519 for (iterator<T> it= entries (u); busy (it); ++it) { 00520 Op::set_op (t[*it], u[*it]); 00521 if (V::val_op::op (read (t, *it), read_I (t))) reset (t, *it); 00522 } 00523 return t; 00524 } 00525 00526 template<typename Op, typename C, typename T, typename V, typename X> Table& 00527 unary_set_scalar (Table& t, const X& x) { 00528 Op::set_op (I (t), x); 00529 for (iterator<T> it= entries (t); busy (it); ++it) 00530 Op::set_op (t[*it], x); 00531 simplify (t); 00532 return t; 00533 } 00534 00535 template<typename Op, typename C, typename T, typename V> bool 00536 binary_test (const Table& t, const Table& u) { 00537 if (Op::not_op (I(t), I(u))) return false; 00538 for (iterator<T> it= entries (t); busy (it); ++it) 00539 if (Op::not_op (t[*it], u[*it])) return false; 00540 for (iterator<T> it= entries (u); busy (it); ++it) 00541 if (!t->contains (*it) && Op::not_op (t[*it], u[*it])) return false; 00542 return true; 00543 } 00544 00545 template<typename Op, typename C, typename T, typename V, typename X> bool 00546 binary_test_scalar (const Table& t, const X& c) { 00547 if (Op::not_op (I(t), c)) return false; 00548 for (iterator<T> it= entries (t); busy (it); ++it) 00549 if (Op::not_op (t[*it], c)) return false; 00550 return true; 00551 } 00552 00553 template<typename Op, typename C, typename T, typename V> inline C 00554 big (const Table& t) { 00555 iterator<T> it= entries (t); 00556 if (done (it)) return Op::template neutral<C> (); 00557 C r= t[*it]; 00558 for (++it; busy (it); ++it) 00559 Op::set_op (r, t[*it]); 00560 return r; 00561 } 00562 00563 template<typename Op, typename C, typename T, typename V> Table 00564 binary_combine (const Table& t, const Table& u) { 00565 Table r (Op::template neutral<C> ()); 00566 for (iterator<T> it1= entries (t); busy (it1); ++it1) 00567 for (iterator<T> it2= entries (u); busy (it2); ++it2) 00568 Op::set_op (r[Op::rhs_op::op (*it1, *it2)], t[*it1], u[*it2]); 00569 simplify (r); 00570 return r; 00571 } 00572 00573 template<typename Op, typename C, typename T, typename V> Table 00574 unary_filter (const Table& t) { 00575 Table r (I(t)); 00576 for (iterator<T> it= entries (t); busy (it); ++it) 00577 if (Op::op (*it)) r[*it]= t[*it]; 00578 return r; 00579 } 00580 00581 /****************************************************************************** 00582 * Dynamic mappers 00583 ******************************************************************************/ 00584 00585 template<typename T1, typename C1, typename T2, typename C2> table<C2,T2> 00586 map (const function_1<T2,Argument(T1) >& funT, 00587 const function_1<C2,Argument(C1) >& funC, 00588 const table<C1,T1>& t, 00589 const format<T2>& fmT, 00590 const format<C2>& fmC) 00591 { 00592 table<C2,T2> r (funC (I(t)), fmT); 00593 for (iterator<T1> it= entries (t); busy (it); ++it) 00594 r[funT(*it)]= funC (t[*it]); 00595 simplify (r); 00596 return r; 00597 } 00598 00599 /****************************************************************************** 00600 * Instantiations of the abstract routines 00601 ******************************************************************************/ 00602 00603 TMPL inline Table duplicate (const Table& t) { 00604 return unary_map<duplicate_op,C,T,V> (t); } 00605 TMPL inline Table operator - (const Table& t) { 00606 return unary_map<neg_op,C,T,V> (t); } 00607 TMPL inline Table operator + (const Table& t, const Table& u) { 00608 return binary_map<add_op,C,T,V> (t, u); } 00609 TMPL inline Table operator + (const Table& t, const C& u) { 00610 return binary_map<add_op,C,T,V> (t, Table (u)); } 00611 TMPL inline Table operator + (const C& t, const Table& u) { 00612 return binary_map<add_op,C,T,V> (Table (t), u); } 00613 TMPL inline Table operator - (const Table& t, const Table& u) { 00614 return binary_map<sub_op,C,T,V> (t, u); } 00615 TMPL inline Table operator - (const Table& t, const C& u) { 00616 return binary_map<sub_op,C,T,V> (t, Table (u)); } 00617 TMPL inline Table operator - (const C& t, const Table& u) { 00618 return binary_map<sub_op,C,T,V> (Table (t), u); } 00619 TMPL inline Table operator * (const Table& t, const Table& u) { 00620 return binary_map<mul_op,C,T,V> (t, u); } 00621 TMPL inline Table operator / (const Table& t, const Table& u) { 00622 return binary_map<div_op,C,T,V> (t, u); } 00623 TMPL inline Table quo (const Table& t, const Table& u) { 00624 return binary_map<quo_op,C,T,V> (t, u); } 00625 TMPL inline Table rem (const Table& t, const Table& u) { 00626 return binary_map<rem_op,C,T,V> (t, u); } 00627 TMPL inline Table operator | (const Table& t, const Table& u) { 00628 return binary_map<or_op,C,T,V> (t, u); } 00629 TMPL inline Table operator & (const Table& t, const Table& u) { 00630 return binary_map<and_op,C,T,V> (t, u); } 00631 TMPL inline Table inf (const Table& t, const Table& u) { 00632 return binary_map<inf_op,C,T,V> (t, u); } 00633 TMPL inline Table sup (const Table& t, const Table& u) { 00634 return binary_map<sup_op,C,T,V> (t, u); } 00635 template<typename C, typename T, typename V, typename K> inline Table 00636 operator * (const Table& t, const K& sc) { 00637 return binary_map_scalar<rmul_op> (t, sc); } 00638 template<typename C, typename T, typename V, typename K> inline Table 00639 operator * (const K& sc, const Table& t) { 00640 return binary_map_scalar<lmul_op> (t, sc); } 00641 template<typename C, typename T, typename V, typename K> inline Table 00642 operator / (const Table& t, const K& sc) { 00643 return binary_map_scalar<rdiv_op> (t, sc); } 00644 template<typename C, typename T, typename V, typename K> inline Table 00645 operator / (const K& sc, const Table& t) { 00646 return binary_map_scalar<ldiv_op> (t, sc); } 00647 template<typename C, typename T, typename V, typename K> inline Table 00648 quo (const Table& t, const K& sc) { 00649 return binary_map_scalar<rquo_op> (t, sc); } 00650 template<typename C, typename T, typename V, typename K> inline Table 00651 rem (const Table& t, const K& sc) { 00652 return binary_map_scalar<rrem_op> (t, sc); } 00653 TMPL inline Table operator += (Table& t, const Table& u) { 00654 return unary_set<add_op,C,T,V> (t, u); } 00655 TMPL inline Table operator -= (Table& t, const Table& u) { 00656 return unary_set<sub_op,C,T,V> (t, u); } 00657 TMPL inline Table operator *= (Table& t, const Table& u) { 00658 return unary_set<mul_op,C,T,V> (t, u); } 00659 TMPL inline Table operator /= (Table& t, const Table& u) { 00660 return unary_set<div_op,C,T,V> (t, u); } 00661 TMPL inline Table operator |= (Table& t, const Table& u) { 00662 return unary_set<or_op,C,T,V> (t, u); } 00663 TMPL inline Table operator &= (Table& t, const Table& u) { 00664 return unary_set<and_op,C,T,V> (t, u); } 00665 template<typename C, typename T, typename V, typename K> inline Table& 00666 operator *= (Table& t, const K& sc) { 00667 return unary_set_scalar<rmul_op> (t, sc); } 00668 template<typename C, typename T, typename V, typename K> inline Table& 00669 operator /= (Table& t, const K& sc) { 00670 return unary_set_scalar<rdiv_op> (t, sc); } 00671 TMPL inline bool operator <= (const Table& t, const Table& u) { 00672 return binary_test<lesseq_op> (t, u); } 00673 TMPL inline bool operator >= (const Table& t, const Table& u) { 00674 return binary_test<gtreq_op,C,T,V> (t, u); } 00675 template<typename C, typename T, typename V, typename K> inline bool 00676 operator == (const Table& t, const K& c) { 00677 return binary_test_scalar<equal_op> (t, c); } 00678 template<typename C, typename T, typename V, typename K> inline bool 00679 operator <= (const Table& t, const K& c) { 00680 return binary_test_scalar<lesseq_op> (t, c); } 00681 template<typename C, typename T, typename V, typename K> inline bool 00682 operator >= (const Table& t, const K& c) { 00683 return binary_test_scalar<gtreq_op> (t, c); } 00684 00685 TRUE_IDENTITY_OP_SUGAR(TMPL,Table) 00686 EXACT_IDENTITY_OP_SUGAR(TMPL,Table) 00687 ADDITIVE_SCALAR_INT_SUGAR(TMPL,Table) 00688 STRICT_COMPARE_SUGAR(TMPL,Table) 00689 00690 TMPL inline C big_add (const Table& t) { return big<add_op> (t); } 00691 TMPL inline C big_mul (const Table& t) { return big<mul_op> (t); } 00692 TMPL inline C big_or (const Table& t) { return big< or_op> (t); } 00693 TMPL inline C big_and (const Table& t) { return big<and_op> (t); } 00694 TMPL inline C big_min (const Table& t) { return big<min_op> (t); } 00695 TMPL inline C big_max (const Table& t) { return big<max_op> (t); } 00696 TMPL inline C big_inf (const Table& t) { return big<inf_op> (t); } 00697 TMPL inline C big_sup (const Table& t) { return big<sup_op> (t); } 00698 00699 /****************************************************************************** 00700 * Floating point related operations 00701 ******************************************************************************/ 00702 00703 TMPL inline bool is_finite (const Table& t) { 00704 return big<and_is_finite_op> (t); } 00705 TMPL inline bool is_nan (const Table& t) { 00706 return big<or_is_nan_op> (t); } 00707 TMPL inline bool is_infinite (const Table& t) { 00708 return !is_nan (t) && big<or_is_infinite_op> (t); } 00709 TMPL inline bool is_fuzz (const Table& t) { 00710 return !is_nan (t) && big<or_is_fuzz_op> (t); } 00711 TMPL inline bool is_reliable (const Table& t) { 00712 return is_reliable (C (0)); } 00713 00714 TMPL inline Table sharpen (const Table& t) { 00715 return unary_map<sharpen_op> (t); } 00716 TMPLK inline Table blur (const Table& t, const K& x) { 00717 return binary_map_scalar<blur_op> (t, x); } 00718 00719 /****************************************************************************** 00720 * Set-like operations 00721 ******************************************************************************/ 00722 00723 TMPL Table 00724 append (const Table& t, const Table& u) { 00725 Table r (I (u), CF2(t)); 00726 for (iterator<T> it= entries (t); busy (it); ++it) 00727 r[*it]= t[*it]; 00728 simplify (r); 00729 for (iterator<T> it= entries (u); busy (it); ++it) 00730 r[*it]= u[*it]; 00731 return r; 00732 } 00733 00734 TMPL Table 00735 common (const Table& t, const Table& u) { 00736 Table r (I (t), CF2(t)); 00737 for (iterator<T> it= entries (t); busy (it); ++it) 00738 if (V::val_op::op (u[*it], t[*it])) 00739 r[*it]= t[*it]; 00740 return r; 00741 } 00742 00743 TMPL Table 00744 difference (const Table& t, const Table& u) { 00745 Table r (I (t), CF2(t)); 00746 for (iterator<T> it= entries (t); busy (it); ++it) 00747 if (!V::val_op::op (u[*it], t[*it])) 00748 r[*it]= t[*it]; 00749 return r; 00750 } 00751 00752 #undef TMPL_DEF 00753 #undef TMPL 00754 #undef TMPLK 00755 #undef Format1 00756 #undef Format2 00757 #undef Table 00758 #undef Table_rep 00759 } // namespace mmx 00760 #endif // __MMX_TABLE_HPP