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