basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : glue.hpp 00004 * DESCRIPTION: Routines for defining glue 00005 * COPYRIGHT : (C) 2006 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 __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 * Register and call glued functions 00033 ******************************************************************************/ 00034 00035 void register_glue (const string&, void(*)(void)); 00036 void call_glue (const string&); 00037 00038 /****************************************************************************** 00039 * Accelerators 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 * Main functions for gluing routines to the current evaluator 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 * Gluing new data types 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 } // namespace mmx 00300 #endif // __GLUE_HPP