00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __GLUE_HPP
00014 #define __GLUE_HPP
00015 #include <basix/evaluator.hpp>
00016 #include <basix/routine.hpp>
00017 #include <basix/identifiers.hpp>
00018 #include <basix/primitive.hpp>
00019 #include <basix/tuple.hpp>
00020 #include <basix/alias.hpp>
00021
00023
00024 namespace mmx {
00025 #define TMPL template<typename C>
00026 #define Acc accelerator<C>
00027
00028 template<typename C> inline generic type_name ();
00029 void define_prerequisites ();
00030
00031
00032
00033
00034
00035 void register_glue (const string&, void(*)(void));
00036 void call_glue (const string&);
00037
00038
00039
00040
00041
00042 TMPL inline void Acc::set_construct (nat id, const routine& r) {
00043 fill_out (construct, nr_construct, id, r); }
00044 TMPL inline void Acc::set_apply (nat code, const routine& r) {
00045 fill_out (apply, nr_apply, code, r); }
00046
00047 nat accelerate_number ();
00048
00049 TMPL void
00050 accelerate_initialize () {
00051 if (Acc::id == ((nat) (-1)))
00052 Acc::id= accelerate_number ();
00053 }
00054
00055 template<typename C, typename S1> void
00056 accelerate_converter (const generic& name, C (*f) (const S1&)) {
00057 (void) name;
00058 accelerate_initialize<C> ();
00059 accelerate_initialize<S1> ();
00060 generic con= gen (GEN_INTO, type_name<S1> (), type_name<C> ());
00061 routine fun= unary_routine (con, f);
00062 Acc::set_construct (accelerator<S1>::id, fun);
00063 }
00064
00065 template<typename C, typename S> inline void
00066 accelerate_converter (const generic&, C (*) (const alias<S>&)) {}
00067 template<typename C, typename S> inline void
00068 accelerate_converter (const generic&, C (*) (const generic_alias<S>&)) {}
00069 template<typename S> inline void
00070 accelerate_converter (const generic&, int (*) (const S&)) {}
00071 template<typename S> inline void
00072 accelerate_converter (const generic&, int (*) (const alias<S>&)) {}
00073 template<typename S> inline void
00074 accelerate_converter (const generic&, int (*) (const generic_alias<S>&)) {}
00075
00076 template<typename C, typename S1> inline void
00077 accelerate (const generic& name, C (*f) (const S1&)) {
00078 if (name == GEN_CAST)
00079 accelerate_converter (name, f);
00080 }
00081
00082 TMPL void
00083 accelerate (const generic& name, C (*f) (const C&)) {
00084 routine fun= unary_routine (name, f);
00085 if (name == GEN_MINUS)
00086 Acc::set_apply (ACC_NEGATE, fun);
00087 else if (name == GEN_SQUARE)
00088 Acc::set_apply (ACC_SQUARE, fun);
00089 else if (name == GEN_INVERT)
00090 Acc::set_apply (ACC_INVERT, fun);
00091 else if (name == GEN_SQRT)
00092 Acc::set_apply (ACC_SQRT, fun);
00093 else if (name == GEN_EXP)
00094 Acc::set_apply (ACC_EXP, fun);
00095 else if (name == GEN_LOG)
00096 Acc::set_apply (ACC_LOG, fun);
00097 else if (name == GEN_COS)
00098 Acc::set_apply (ACC_COS, fun);
00099 else if (name == GEN_SIN)
00100 Acc::set_apply (ACC_SIN, fun);
00101 else if (name == GEN_TAN)
00102 Acc::set_apply (ACC_TAN, fun);
00103 else if (name == GEN_CH)
00104 Acc::set_apply (ACC_COSH, fun);
00105 else if (name == GEN_SH)
00106 Acc::set_apply (ACC_SINH, fun);
00107 else if (name == GEN_TH)
00108 Acc::set_apply (ACC_TANH, fun);
00109 else if (name == GEN_ARCCOS)
00110 Acc::set_apply (ACC_ACOS, fun);
00111 else if (name == GEN_ARCSIN)
00112 Acc::set_apply (ACC_ASIN, fun);
00113 else if (name == GEN_ARCTAN)
00114 Acc::set_apply (ACC_ATAN, fun);
00115 else if (name == GEN_ARGCH)
00116 Acc::set_apply (ACC_ACOSH, fun);
00117 else if (name == GEN_ARGSH)
00118 Acc::set_apply (ACC_ASINH, fun);
00119 else if (name == GEN_ARGTH)
00120 Acc::set_apply (ACC_ATANH, fun);
00121 else if (name == GEN_DERIVE)
00122 Acc::set_apply (ACC_DERIVE, fun);
00123 else if (name == GEN_INTEGRATE)
00124 Acc::set_apply (ACC_INTEGRATE, fun);
00125 }
00126
00127 template<typename C, typename S1, typename S2> inline void
00128 accelerate (const generic&, C (*) (const S1&, const S2&)) {}
00129
00130 TMPL void
00131 accelerate (const generic& name, C (*f) (const C&, const C&)) {
00132 routine fun= binary_routine (name, f);
00133 if (name == GEN_PLUS)
00134 Acc::set_apply (ACC_ADD, fun);
00135 else if (name == GEN_MINUS)
00136 Acc::set_apply (ACC_SUB, fun);
00137 else if (name == GEN_TIMES)
00138 Acc::set_apply (ACC_MUL, fun);
00139 else if (name == GEN_OVER)
00140 Acc::set_apply (ACC_DIV, fun);
00141 else if (name == GEN_HYPOT)
00142 Acc::set_apply (ACC_HYPOT, fun);
00143 else if (name == GEN_ARCTAN2)
00144 Acc::set_apply (ACC_ATAN2, fun);
00145 else if (name == GEN_POWER)
00146 Acc::set_apply (ACC_POW, fun);
00147 }
00148
00149 TMPL void
00150 accelerate (const generic& name, bool (*f) (const C&, const C&)) {
00151 routine fun= binary_routine (name, f);
00152 if (name == GEN_LESS)
00153 Acc::set_apply (ACC_LESS, fun);
00154 else if (name == GEN_LESSEQ)
00155 Acc::set_apply (ACC_LESSEQ, fun);
00156 else if (name == GEN_GTR)
00157 Acc::set_apply (ACC_GTR, fun);
00158 else if (name == GEN_GTREQ)
00159 Acc::set_apply (ACC_GTREQ, fun);
00160 }
00161
00162 inline void
00163 accelerate (const generic&, bool (*) (const bool&, const bool&)) {}
00164
00165
00166
00167
00168
00169 template<typename D> inline void
00170 define_constant (const generic& name, const D& x) {
00171 current_ev->set (name, as<generic> (x));
00172 }
00173
00174 template<typename D> inline void
00175 define_constructor (generic (*fun) (const D&)) {
00176 current_ev->overload (GEN_NEW, as<generic> (unary_routine (GEN_NEW, fun)));
00177 }
00178
00179 inline void
00180 define_primitive (const generic& name, generic (*fun) (const generic&)) {
00181 current_ev->set (name, as<generic> (primitive (name, fun)));
00182 }
00183
00184 template<typename D> inline void
00185 define (const generic& name, D (*fun) ()) {
00186 current_ev->overload (name, as<generic> (nullary_routine (name, fun)));
00187 }
00188
00189 template<typename D, typename S1> inline void
00190 define (const generic& name, D (*fun) (const S1&)) {
00191 current_ev->overload (name, as<generic> (unary_routine (name, fun)));
00192 accelerate (name, fun);
00193 }
00194
00195 template<typename D, typename S1, typename S2> inline void
00196 define (const generic& name, D (*fun) (const S1&, const S2&)) {
00197 current_ev->overload (name, as<generic> (binary_routine (name, fun)));
00198 accelerate (name, fun);
00199 }
00200
00201 template<typename D, typename S1, typename S2, typename S3>
00202 inline void
00203 define (const generic& name, D (*fun) (const S1&, const S2&, const S3&)) {
00204 current_ev->overload (name, as<generic> (ternary_routine (name, fun)));
00205 }
00206
00207 template<typename D, typename S1, typename S2, typename S3, typename S4>
00208 inline void
00209 define (const generic& name, D (*fun) (const S1&, const S2&, const S3&,
00210 const S4&)) {
00211 current_ev->overload (name, as<generic> (quaternary_routine (name, fun)));
00212 }
00213
00214 template<typename D, typename S1, typename S2, typename S3,
00215 typename S4, typename S5>
00216 inline void
00217 define (const generic& name, D (*fun) (const S1&, const S2&, const S3&,
00218 const S4&, const S5&)) {
00219 current_ev->overload (name, as<generic> (quintary_routine (name, fun)));
00220 }
00221
00222 template<typename C, typename S1> inline void
00223 define_converter (const generic& name, C (*f) (const S1&), nat p) {
00224 generic con= gen (GEN_INTO, type_name<S1> (), type_name<C> ());
00225 routine fun= unary_routine (con, f);
00226 current_ev->overload (name, as<generic> (fun), p);
00227 accelerate_converter (name, f);
00228 }
00229
00230
00231
00232
00233
00234 template<typename C>
00235 struct define_type_helper {
00236 static bool helper_equal (const C& x, const C& y) { return x==y; }
00237 static bool helper_unequal (const C& x, const C& y) { return x!=y; }
00238 static syntactic helper_flatten (const C& x) { return flatten (x); }
00239 static inline void def_type (const generic& name);
00240 static inline void def_default ();
00241 };
00242
00243 template<typename C> inline void
00244 define_type_helper<C>::def_type (const generic& name) {
00245 define_type_sub (name, type_id<C> ());
00246 define_type_sub (gen (GEN_TUPLE_TYPE, name), type_id<tuple<C> > ());
00247 define_type_sub (gen (GEN_ALIAS_TYPE, name), type_id<alias<C> > ());
00248 define_type_sub (gen (GEN_GENERIC_ALIAS_TYPE, name),
00249 type_id<generic_alias<C> > ());
00250
00251 attach_generic_binary_assembler<C> ();
00252 attach_generic_binary_assembler<tuple<C> > ();
00253 attach_generic_binary_assembler<alias<C> > ();
00254 attach_generic_binary_reader<C> ();
00255 attach_generic_binary_reader<tuple<C> > ();
00256 attach_generic_binary_reader<alias<C> > ();
00257
00258 define (GEN_ALIAS, new_alias<C>);
00259 routine specializer= unary_routine (GEN_SPECIALIZE, new_genalias<C>);
00260 alias_specializer (type_id<C> (), specializer);
00261 routine getter= unary_routine (GEN_UNALIAS, get_genalias<C>);
00262 alias_getter (type_id<generic_alias<C> > (), getter);
00263 getter= unary_routine (GEN_UNALIAS, get_alias<C>);
00264 alias_getter (type_id<alias<C> > (), getter);
00265 routine setter= binary_routine (GEN_UNALIAS, set_genalias<C>);
00266 alias_setter (type_id<generic_alias<C> > (), setter);
00267 setter= binary_routine (GEN_UNALIAS, set_alias<C>);
00268 alias_setter (type_id<alias<C> > (), setter);
00269
00270 define_converter<C,alias<C> >
00271 (GEN_REWRITE, get_alias<C>, PENALTY_AUTOMATIC);
00272 define_converter<C,generic_alias<C> >
00273 (GEN_REWRITE, get_genalias<C>, PENALTY_AUTOMATIC);
00274 define_converter<alias<generic>,generic_alias<C> >
00275 (GEN_REWRITE, generalize_genalias<C>, PENALTY_AUTOMATIC);
00276 define_converter<alias<C>,generic_alias<C> >
00277 (GEN_REWRITE, incarnate_genalias<C>, PENALTY_AUTOMATIC);
00278 }
00279
00280 template<typename C> inline void
00281 define_type_helper<C>::def_default () {
00282 define<bool,C,C> (GEN_EQUAL, helper_equal);
00283 define<bool,C,C> (GEN_UNEQUAL, helper_unequal);
00284 define<syntactic,C> (GEN_FLATTEN, helper_flatten);
00285 }
00286
00287 template<> inline void
00288 define_type_helper<generic>::def_default () {
00289 }
00290
00291 template<typename C> inline void
00292 define_type (const generic& name) {
00293 define_type_helper<C>::def_type (name);
00294 define_type_helper<C>::def_default ();
00295 }
00296
00297 #undef TMPL
00298 #undef Acc
00299 }
00300 #endif // __GLUE_HPP