00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMC_GLUE_HPP
00014 #define __MMC_GLUE_HPP
00015
00016 #include <basix/table.hpp>
00017 #include <basix/literal.hpp>
00018 #include <basix/compound.hpp>
00019 #include <basix/system.hpp>
00020 #include <basix/document.hpp>
00021 #include <basix/routine.hpp>
00022 #include <basix/generic_function.hpp>
00023 #include <basix/object_format.hpp>
00024 #include <basix/instance.hpp>
00025 #include <basix/dispatcher.hpp>
00026
00027 namespace mmx {
00028
00029
00030
00031
00032
00033 extern vector<string> mmc_args;
00034 void mmc_initialize (int argc, char** argv);
00035 void mmc_terminate ();
00036 void mmc_exit (const int& status);
00037
00038 vector<string> mmc_load_directory (const string& name);
00039 void mmc_save (const string& name, const string& s);
00040 string mmc_load (const string& name);
00041 generic mmc_parse (const string& file_name);
00042 generic mmc_parse (const string& s, const string& input_name);
00043
00044 generic mmc_unliteral (const generic& x);
00045 exception mmc_exception (const string& message, const generic& where);
00046 string as_string (const exception& e);
00047
00048 inline void noop () {}
00049 inline nat hash_combine (nat i, nat j) { return (i << 7) ^ (i >> 25) ^ j; }
00050 template<typename C, typename R> inline C
00051 promote (R* rep) { return C (rep); }
00052 template<typename T> inline syntactic
00053 flatten_as_syntactic (const T& x) { return flatten (x); }
00054
00055
00056
00057
00058
00059 inline literal
00060 string_as_literal (const string& s) {
00061 return literal (s);
00062 }
00063
00064 inline compound
00065 vector_as_compound (const vector<generic>& l) {
00066 return compound (l);
00067 }
00068
00069 inline compound
00070 literal_apply (const literal& f, const vector<generic>& v) {
00071 return compound (cons (as<generic> (f), v));
00072 }
00073
00074 inline compound
00075 compound_apply (const compound& f, const vector<generic>& v) {
00076 return compound (cons (as<generic> (f), v));
00077 }
00078
00079
00080
00081
00082
00083 inline compound
00084 generic_apply (const generic& f, const vector<generic>& v) {
00085 return compound (cons (f, v));
00086 }
00087
00088 inline vector<generic>
00089 generic_components (const generic& g) {
00090 return compound_to_vector (g);
00091 }
00092
00093 inline vector<generic>
00094 generic_arguments (const generic& g) {
00095 return cdr (generic_components (g));
00096 }
00097
00098 inline bool
00099 generic_is_literal (const generic& g) {
00100 return is<literal> (g);
00101 }
00102
00103 inline bool
00104 generic_is_compound (const generic& g) {
00105 return is<compound> (g);
00106 }
00107
00108 inline bool
00109 generic_is_vector_generic (const generic& g) {
00110 return is<vector<generic> > (g);
00111 }
00112
00113 inline bool
00114 generic_is_table_generic (const generic& g) {
00115 return is<table<generic,generic> > (g);
00116 }
00117
00118 inline string
00119 generic_as_string (const generic& g) {
00120 ASSERT (is<string> (g) || is<literal> (g), "string or literal expected");
00121 if (is<string> (g)) return as<string> (g);
00122 else return as_string (as<literal> (g));
00123 }
00124
00125 inline literal
00126 generic_as_literal (const generic& g) {
00127 ASSERT (is<literal> (g), "literal expected");
00128 return as<literal> (g);
00129 }
00130
00131 inline vector<generic>
00132 generic_as_vector (const generic& g) {
00133 ASSERT (is<vector<generic> > (g), "vector expected");
00134 return as<vector<generic> > (g);
00135 }
00136
00137 inline int
00138 generic_size (const generic& g) {
00139 return (int) N(g);
00140 }
00141
00142 generic generic_type (const generic& g);
00143
00144
00145
00146
00147
00148 template<typename T, typename F>
00149 struct verbose_as_helper {
00150 static T cv (const F& g) {
00151 if (!is<T> (g)) {
00152 mmerr << "Expression : " << g << "\n";
00153 mmerr << "Given type : ";
00154 if (type_name (g) != "Unspecified")
00155 mmerr << type_name (g) << lf;
00156 else
00157 mmerr << binary_type_generic (as<generic> (g)) << lf;
00158 mmerr << "Expected type: ";
00159 if (type_name (type_information<T>::id) != "Unspecified")
00160 mmerr << type_name (type_information<T>::id) << lf;
00161 else
00162 mmerr << Full_type_name (T) << lf;
00163 if (!is<T> (g)) abort ();
00164
00165 }
00166 return as_helper<T,F>::cv (g);
00167 }
00168 };
00169
00170 template<>
00171 struct verbose_as_helper<generic,generic> {
00172 static inline generic cv (const generic& g) {
00173 return g; }
00174 };
00175
00176 template<typename T> inline generic
00177 any_as_generic (const T& t) {
00178 return as_helper<generic,T>::cv (t);
00179 }
00180
00181 template<typename T, typename U> inline U
00182 concrete_to_abstract (const T& g) {
00183 return any_as_generic<T> (g);
00184 }
00185
00186 template<typename T> inline T
00187 generic_as_any (const generic& g) {
00188 return verbose_as_helper<T,generic>::cv (g);
00189 }
00190
00191 template<typename T, typename U> inline U
00192 abstract_to_concrete (const T& g) {
00193 return generic_as_any<U> (g);
00194 }
00195
00196
00197
00198
00199
00200 template<typename T> inline vector<T>
00201 vector_new (const vector<T>& v) {
00202 return v;
00203 }
00204
00205 template<typename T> inline int
00206 vector_length (const vector<T>& v) {
00207 return (int) N(v);
00208 }
00209
00210 template<typename T> inline vector<T>
00211 vector_nil () {
00212 return vector<T> ();
00213 }
00214
00215 template<typename T> inline vector<T>
00216 vector_nil (const format<T>& fm) {
00217 return vec<T> (fm);
00218 }
00219
00220 template<typename T> inline vector<T>
00221 vector_cons (const T& x, const vector<T>& v) {
00222 return cons (x, v);
00223 }
00224
00225 template<typename T> inline vector<T>
00226 vector_append (const vector<T>& v1, const vector<T>& v2) {
00227 return append (v1, v2);
00228 }
00229
00230 template<typename T> inline vector<T>
00231 vector_append (const vector<T>& v, const T& x) {
00232 return append (v, x);
00233 }
00234
00235 template<typename T> inline vector<T>&
00236 vector_lessless (vector<T>& v1, const vector<T>& v2) {
00237 return v1 << v2;
00238 }
00239
00240 template<typename T> inline T
00241 vector_read (const vector<T>& v, const int& i) {
00242 return v[(nat) i];
00243 }
00244
00245 template<typename T> inline T&
00246 vector_write (vector<T>& v, const int& i) {
00247 return v[(nat) i];
00248 }
00249
00250 template<typename T> inline vector<T>
00251 vector_range (const vector<T>& v, const int& i, const int& j) {
00252 return range (v, (nat) i, (nat) j);
00253 }
00254
00255 template<typename T> inline bool
00256 vector_is_nil (const vector<T>& v) {
00257 return N(v) == 0;
00258 }
00259
00260 template<typename T> inline bool
00261 vector_is_atom (const vector<T>& v) {
00262 return is_non_scalar (v) && N(v) == 1;
00263 }
00264
00265 template<typename T> vector<T>
00266 vector_reverse (const vector<T>& v) {
00267 if (is_a_scalar (v)) return v;
00268 nat i, n= N(v);
00269 vector<T> r= fill<T> (n);
00270 for (i=0; i<n; i++) r[i]= v[n-1-i];
00271 return r;
00272 }
00273
00274 template<typename T> int
00275 vector_find (const vector<T>& v, const T& x) {
00276 nat i, n=N(v);
00277 for (i=0; i<n; i++)
00278 if (v[i] == x) return (int) i;
00279 return (int) i;
00280 }
00281
00282 template<typename T> inline bool
00283 vector_contains (const vector<T>& v, const T& x) {
00284 return vector_find (v, x) < ((int) N(v));
00285 }
00286
00287 template<typename T> inline vector<T>
00288 vector_insert (const vector<T>& v, const T& x) {
00289 if (vector_contains (v, x)) return v;
00290 else return vector_append (v, x);
00291 }
00292
00293 template<typename T, typename U> inline vector<U>
00294 vector_lift (const vector<T>& v) {
00295 return as<vector<U> > (v);
00296 }
00297
00298 template<typename T> inline vector<generic>
00299 vector_lift_to_generic (const vector<T>& v) {
00300 return vector_lift<T,generic> (v);
00301 }
00302
00303 template<typename S1, typename D> inline vector<D>
00304 vector_lift (const function_1<D,Argument(S1) >& fun, const vector<S1>& v1) {
00305 return map<S1,D> (fun, v1);
00306 }
00307
00308 template<typename S1, typename D> inline vector<D>
00309 vector_lift (D (*fun) (const S1&), const vector<S1>& v1) {
00310 return map<S1,D> (fun, v1);
00311 }
00312
00313 template<typename S1, typename D> inline vector<D>
00314 vector_lift (const function_1<D,Argument(S1) >& fun, const vector<S1>& v1,
00315 const format<D>& fm) {
00316 return map<S1,D> (fun, v1, fm);
00317 }
00318
00319 template<typename S1, typename D> inline vector<D>
00320 vector_lift (D (*fun) (const S1&), const vector<S1>& v1,
00321 const format<D>& fm) {
00322 return map<S1,D> (fun, v1, fm);
00323 }
00324
00325
00326
00327
00328
00329 template<typename D> inline table<D,generic>
00330 table_new (const D& x) {
00331 return table<D,generic> (x, 1);
00332 }
00333
00334 template<typename D> inline int
00335 table_size (const table<D,generic>& t) {
00336 return (int) N(t);
00337 }
00338
00339 template<typename D> inline iterator<generic>
00340 table_explode (const table<D,generic>& t) {
00341 return entries (t);
00342 }
00343
00344 template<typename D> inline bool
00345 table_contains (const table<D,generic>& t, const generic& x) {
00346 return t->contains (x);
00347 }
00348
00349 template<typename D> inline void
00350 table_reset (table<D,generic>& t, const generic& x) {
00351 reset (t, x);
00352 }
00353
00354 template<typename D> inline D
00355 table_read (const table<D,generic>& t, const generic& x) {
00356 return t[x];
00357 }
00358
00359 template<typename D> inline D&
00360 table_write (table<D,generic>& t, const generic& x) {
00361 return t[x];
00362 }
00363
00364 template<typename D> inline void
00365 table_set (const table<D,generic>& t, const generic& x, const D& v) {
00366 inside (t) -> set (x) = v;
00367 }
00368
00369 template<typename D> inline bool
00370 table_contains (const table<D,generic>& t,
00371 const generic& x, const generic& y) {
00372 return t->contains (gen (GEN_TUPLE, x, y));
00373 }
00374
00375 template<typename D> inline void
00376 table_reset (const table<D,generic>& t, const generic& x, const generic& y) {
00377 return inside (t) -> reset (gen (GEN_TUPLE, x, y));
00378 }
00379
00380 template<typename D> inline D
00381 table_read (const table<D,generic>& t, const generic& x, const generic& y) {
00382 return t[gen (GEN_TUPLE, x, y)];
00383 }
00384
00385 template<typename D> inline D&
00386 table_write (table<D,generic>& t, const generic& x, const generic& y) {
00387 return t[gen (GEN_TUPLE, x, y)];
00388 }
00389
00390 template<typename D> inline void
00391 table_set (const table<D,generic>& t, const generic& x, const generic& y,
00392 const D& v) {
00393 inside (t) -> set (gen (GEN_TUPLE, x, y)) = v;
00394 }
00395
00396
00397
00398
00399
00400 template<typename T> inline bool
00401 iterator_busy (const iterator<T>& it) {
00402 return busy (it);
00403 }
00404
00405 template<typename T> inline T
00406 iterator_current (const iterator<T>& it) {
00407 return *it;
00408 }
00409
00410 template<typename T> inline void
00411 iterator_increase (const iterator<T>& it) {
00412 ++it;
00413 }
00414
00415 template<typename T> inline vector<T>
00416 iterator_explode (const iterator<T>& it) {
00417 return vector<T> (it);
00418 }
00419
00420 template<typename S, typename T> inline iterator<S>
00421 iterator_strict_range (const S& start, const T& end) {
00422 return range_iterator (start, outplace_set_as<S> (end),
00423 outplace_set_as<S> (1), true);
00424 }
00425
00426 template<typename S, typename T> inline iterator<S>
00427 iterator_natural_range (const S& start, const T& end) {
00428 return range_iterator (start, outplace_set_as<S> (end),
00429 outplace_set_as<S> (1), false);
00430 }
00431
00432 template<typename S, typename T> inline iterator<S>
00433 iterator_downwards_range (const S& start, const T& end) {
00434 return range_iterator (start, outplace_set_as<S> (end),
00435 outplace_set_as<S> (-1), false);
00436 }
00437
00438 template<typename T> iterator<T>
00439 iterator_nil () {
00440 return iterator<T> ();
00441 }
00442
00443 template<typename T> iterator<T>
00444 iterator_nil (const format<T>& fm) {
00445 return iterator<T> (fm);
00446 }
00447
00448 template<typename T> iterator<T>
00449 iterator_cons (const T& c, const iterator<T>& tail) {
00450 return iterator<T> (c) * tail;
00451 }
00452
00453 template<typename T> iterator<T>
00454 iterator_append (const iterator<T>& head, const iterator<T>& tail) {
00455 return head * tail;
00456 }
00457
00458
00459
00460
00461
00462 template<typename T, typename U>
00463 class lift_iterator_rep: public iterator_rep<U> {
00464 iterator<T> it;
00465
00466 public:
00467 lift_iterator_rep (const iterator<T>& it2, const format<U>& fm):
00468 iterator_rep<U> (fm), it (it2) {}
00469
00470 protected:
00471 bool is_busy () { return busy (it); }
00472 void advance () { ++it; }
00473 bool is_init () { return init (it); }
00474 void regress () { --it; }
00475 U current () { return as<U> (*it); }
00476 iterator_rep<U>* clone () {
00477 return new lift_iterator_rep (copy (it), (format<U>) *this); }
00478 };
00479
00480 template<typename T, typename U> iterator<U>
00481 iterator_lift (const iterator<T>& it) {
00482 return iterator<U> (new lift_iterator_rep<T,U> (it, format<U> ()));
00483 }
00484
00485 template<typename T> iterator<T>
00486 iterator_lift_from_generic (const iterator<generic>& it) {
00487 return iterator<T> (new lift_iterator_rep<generic,T> (it, format<T> ()));
00488 }
00489
00490 template<typename T> iterator<T>
00491 iterator_lift_from_generic (const iterator<generic>& it,
00492 const format<T>& fm) {
00493 return iterator<T> (new lift_iterator_rep<generic,T> (it, fm));
00494 }
00495
00496 template<typename T, typename U>
00497 class lift_arg_iterator_rep: public iterator_rep<U> {
00498 function_1<U,Argument(T) > fun;
00499 iterator<T> it;
00500
00501 public:
00502 lift_arg_iterator_rep (const function_1<U,Argument(T) >& fun2,
00503 const iterator<T>& it2, const format<U>& fm):
00504 iterator_rep<U> (fm), fun (fun2), it (it2) {}
00505
00506 protected:
00507 bool is_busy () { return busy (it); }
00508 void advance () { ++it; }
00509 bool is_init () { return init (it); }
00510 void regress () { --it; }
00511 U current () { return fun (*it); }
00512 iterator_rep<U>* clone () {
00513 return new lift_arg_iterator_rep (fun, copy (it), (format<U>) *this); }
00514 };
00515
00516 template<typename T, typename U> iterator<U>
00517 iterator_lift (const function_1<U,Argument(T) >& fun,
00518 const iterator<T>& it)
00519 {
00520 return iterator<U> (new lift_arg_iterator_rep<T,U> (fun, it, format<U> ()));
00521 }
00522
00523 template<typename T, typename U> iterator<U>
00524 iterator_lift (const function_1<U,Argument(T) >& fun,
00525 const iterator<T>& it, const format<U>& fm)
00526 {
00527 return iterator<U> (new lift_arg_iterator_rep<T,U> (fun, it, fm));
00528 }
00529
00530 template<typename T, typename U> vector<U>
00531 iterator_lift_vector (const function_1<U,Argument(T) >& fun,
00532 const iterator<T>& it)
00533 {
00534 return vector_lift (fun, vector<T> (it));
00535 }
00536
00537 template<typename T, typename U> vector<U>
00538 iterator_lift_vector (const function_1<U,Argument(T) >& fun,
00539 const iterator<T>& it, const format<U>& fm)
00540 {
00541 return vector_lift (fun, vector<T> (it), fm);
00542 }
00543
00544 template<typename T, typename U> iterator<U>
00545 vector_lift_iterator (const function_1<U,Argument(T) >& fun,
00546 const vector<T>& v)
00547 {
00548 return iterate (vector_lift (fun, v));
00549 }
00550
00551 template<typename T, typename U> iterator<U>
00552 vector_lift_iterator (const function_1<U,Argument(T) >& fun,
00553 const vector<T>& v, const format<U>& fm)
00554 {
00555 return iterate (vector_lift (fun, v, fm));
00556 }
00557
00558 template<typename T, typename U> iterator<U>
00559 map (const function_1<U,Argument(T) >& fun,
00560 const iterator<T>& it, const format<U>& fm)
00561 {
00562 return iterator<U> (new lift_arg_iterator_rep<T,U> (fun, it, fm));
00563 }
00564
00565
00566
00567
00568
00569 template<typename T, typename U>
00570 class where_iterator_rep: public iterator_rep<U> {
00571 function_1<U,Argument(T) > fun;
00572 iterator<T> it;
00573
00574 public:
00575 where_iterator_rep (const function_1<U,Argument(T) >& fun2,
00576 const iterator<T>& it2, const format<U>& fm):
00577 iterator_rep<U> (fm), fun (fun2), it (it2) {}
00578
00579 protected:
00580 bool is_busy () { return busy (it); }
00581 void advance () { ++it; }
00582 bool is_init () { return init (it); }
00583 void regress () { --it; }
00584 U current () { return fun (*it); }
00585 iterator_rep<U>* clone () {
00586 return new where_iterator_rep (fun, copy (it), (format<U>) *this); }
00587 };
00588
00589 template<typename T, typename U> iterator<U>
00590 iterator_where (const function_1<U,Argument(T) >& fun, const iterator<T>& it) {
00591 return iterator<U> (new where_iterator_rep<T,U> (fun, it, format<U> ()));
00592 }
00593
00594 template<typename T, typename U> iterator<U>
00595 iterator_where (const function_1<U,Argument(T) >& fun, const iterator<T>& it,
00596 const format<U>& fm) {
00597 return iterator<U> (new where_iterator_rep<T,U> (fun, it, fm));
00598 }
00599
00600
00601
00602
00603
00604 template<typename T>
00605 class filter_iterator_rep: public iterator_rep<T> {
00606 function_1<bool,Argument(T) > cond;
00607 iterator<T> it;
00608
00609 protected:
00610 void spool () { while (busy (it) && !cond (*it)) ++it; }
00611
00612 public:
00613 filter_iterator_rep (const function_1<bool,Argument(T) >& cond2,
00614 const iterator<T>& it2):
00615 iterator_rep<T> (CF (it)), cond (cond2), it (it2) { spool (); }
00616 filter_iterator_rep (const function_1<bool,Argument(T) >& cond2,
00617 const iterator<T>& it2, const format<T>& fm):
00618 iterator_rep<T> (fm), cond (cond2), it (it2) { spool (); }
00619
00620 protected:
00621 bool is_busy () { return busy (it); }
00622 void advance () { ++it; spool (); }
00623 T current () { return *it; }
00624 iterator_rep<T>* clone () {
00625 return new filter_iterator_rep (cond, copy (it)); }
00626 };
00627
00628 template<typename T> iterator<T>
00629 iterator_filter (const function_1<bool,Argument(T) >& cond,
00630 const iterator<T>& it)
00631 {
00632 return iterator<T> (new filter_iterator_rep<T> (cond, it));
00633 }
00634
00635 template<typename T> iterator<T>
00636 iterator_filter (const function_1<bool,Argument(T) >& cond,
00637 const iterator<T>& it, const format<T>& fm)
00638 {
00639 return iterator<T> (new filter_iterator_rep<T> (cond, it, fm));
00640 }
00641
00642 template<typename T, typename U> iterator<U>
00643 iterator_cond_where (const function_1<U,Argument(T) >& fun,
00644 const iterator<T>& it,
00645 const function_1<bool,Argument(T) >& cond)
00646 {
00647 return iterator_where (fun, iterator_filter (cond, it));
00648 }
00649
00650 template<typename T, typename U> iterator<U>
00651 iterator_cond_where (const function_1<U,Argument(T) >& fun,
00652 const iterator<T>& it,
00653 const function_1<bool,Argument(T) >& cond,
00654 const format<T>& fmT,
00655 const format<U>& fmU)
00656 {
00657 return iterator_where (fun, iterator_filter (cond, it, fmT), fmU);
00658 }
00659
00660
00661
00662
00663
00664 template<typename T>
00665 class unnest_iterator_rep: public iterator_rep<T> {
00666 iterator<iterator<T> > it;
00667 iterator<T> inner;
00668
00669 protected:
00670 void spool () {
00671 while (true) {
00672 if (busy (inner) || !busy (it)) break;
00673 ++it;
00674 if (!busy (it)) break;
00675 inner= *it;
00676 }
00677 }
00678
00679 public:
00680 unnest_iterator_rep (const iterator<iterator<T> >& it2):
00681 iterator_rep<T> (CF (it2)), it (it2), inner (*it) { spool (); }
00682 unnest_iterator_rep (const iterator<iterator<T> >& it2,
00683 const iterator<T>& inner2):
00684 iterator_rep<T> (CF (inner2)), it (it2), inner (inner2) {}
00685
00686 protected:
00687 bool is_busy () { return busy (inner); }
00688 void advance () { ++inner; spool (); }
00689 T current () { return *inner; }
00690 iterator_rep<T>* clone () {
00691 return new unnest_iterator_rep (copy (it), copy (inner)); }
00692 };
00693
00694 template<typename T> iterator<T>
00695 iterator_unnest (const iterator<iterator<T> >& it) {
00696 return iterator<T> (new unnest_iterator_rep<T> (it));
00697 }
00698
00699
00700
00701
00702
00703 template<typename T,typename U> inline pair<T,U>
00704 make_pair (const T& x, const U& y) {
00705 return pair<T,U> (x, y);
00706 }
00707
00708 template<typename T, typename U1, typename U2> syntactic
00709 flatten (const pair<T,pair<U1,U2> >& p) {
00710 vector<syntactic> args;
00711 args << flatten (p.x1);
00712 args << arguments (flatten (p.x2));
00713 return apply (GEN_SQTUPLE, args);
00714 }
00715
00716 template<typename T1, typename T2, typename U> syntactic
00717 flatten (const pair<pair<T1,T2>,U >& p) {
00718 vector<syntactic> args;
00719 args << arguments (flatten (p.x1));
00720 args << flatten (p.x2);
00721 return apply (GEN_SQTUPLE, args);
00722 }
00723
00724 template<typename T1, typename T2, typename U1, typename U2> syntactic
00725 flatten (const pair<pair<T1,T2>,pair<U1,U2> >& p) {
00726 vector<syntactic> args;
00727 args << arguments (flatten (p.x1));
00728 args << arguments (flatten (p.x2));
00729 return apply (GEN_SQTUPLE, args);
00730 }
00731
00732
00733
00734
00735
00736 #define TMPL template<typename R>
00737
00738 template<typename R>
00739 struct Indirect {
00740 R* rep;
00741 inline const R* operator -> () const { return rep; }
00742 inline Indirect (): rep (new R ()) {}
00743 inline ~Indirect () { DEC_COUNT (rep); }
00744 inline Indirect (const Indirect<R> &x): rep (x.rep) { INC_COUNT (rep); }
00745 inline Indirect<R> &operator = (const Indirect<R> &x) {
00746 INC_COUNT (x.rep);
00747 DEC_COUNT (rep);
00748 rep = x.rep;
00749 return *this; }
00750 };
00751
00752 TMPL inline R* access (Indirect<R>& x) {
00753 return x.rep; }
00754 TMPL inline bool operator == (const Indirect<R> &x, const Indirect<R> &y) {
00755 return x.rep == y.rep; }
00756 TMPL inline bool operator != (const Indirect<R> &x, const Indirect<R> &y) {
00757 return x.rep != y.rep; }
00758 TMPL inline bool exact_eq (const Indirect<R> &x, const Indirect<R> &y) {
00759 return x.rep == y.rep; }
00760 TMPL inline bool exact_neq (const Indirect<R> &x, const Indirect<R> &y) {
00761 return x.rep != y.rep; }
00762 TMPL inline bool hard_eq (const Indirect<R> &x, const Indirect<R> &y) {
00763 return x.rep == y.rep; }
00764 TMPL inline bool hard_neq (const Indirect<R> &x, const Indirect<R> &y) {
00765 return x.rep != y.rep; }
00766 TMPL inline nat hash (const Indirect<R> &x) {
00767 return as_hash (x.rep); }
00768 TMPL inline nat exact_hash (const Indirect<R> &x) {
00769 return as_hash (x.rep); }
00770 TMPL inline nat hard_hash (const Indirect<R> &x) {
00771 return as_hash (x.rep); }
00772 TMPL inline syntactic flatten (const Indirect<R> &x) {
00773 return syntactic ("category"); }
00774
00775 #undef TMPL
00776
00777 }
00778
00779 using namespace mmx;
00780 #endif // __MMC_GLUE_HPP