basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/table.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines