]> www.ginac.de Git - ginac.git/blobdiff - ginac/parser/default_reader.tpl
Use C style cast when converting void* into function pointer.
[ginac.git] / ginac / parser / default_reader.tpl
index 244074fa17fb731ff49e6f448ff8f905fd114911..006fb908c28402f2d61fa5cacdee904788a091b7 100644 (file)
@@ -19,6 +19,13 @@ COMMENT a part of GiNaC parser -- construct functions from a byte stream.
 #include "power.h"
 #include "operators.h"
 #include "inifcns.h"
 #include "power.h"
 #include "operators.h"
 #include "inifcns.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h> // for uintptr_t
+#endif
 
 namespace GiNaC
 {
 
 namespace GiNaC
 {
@@ -31,31 +38,108 @@ static ex [+ (get "name") +]_reader(const exvector& ev)
                  (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]);
 }[+ ENDFOR +]
 
                  (format '#f "~{ev[~a]~^, ~}" (sequence 0 (- nargs 1)))) +]);
 }[+ ENDFOR +]
 
+// function::registered_functions() is protected, but we need to access it
+class registered_functions_hack : public function
+{
+public:
+       static const std::vector<function_options>& get_registered_functions()
+       {
+               return function::registered_functions();
+       }
+private:
+       registered_functions_hack();
+       registered_functions_hack(const registered_functions_hack&);
+       registered_functions_hack& operator=(const registered_functions_hack&);
+};
+
+// Encode an integer into a pointer to a function. Since functions
+// are aligned (the minimal alignment depends on CPU architecture)
+// we can distinguish between pointers and integers.
+static reader_func encode_serial_as_reader_func(unsigned serial)
+{
+       uintptr_t u = (uintptr_t)serial;
+       u = (u << 1) | (uintptr_t)1;
+       reader_func ptr = (reader_func)((void *)u);
+       return ptr;
+}
+
 const prototype_table& get_default_reader()
 {
        using std::make_pair;
        static bool initialized = false;
        static prototype_table reader;
        if (!initialized) {
 const prototype_table& get_default_reader()
 {
        using std::make_pair;
        static bool initialized = false;
        static prototype_table reader;
        if (!initialized) {
-               try {
-                       for ( unsigned ser=0; ; ++ser ) {
-                               GiNaC::function f(ser);
-                               std::string name = f.get_name();
-                               for ( std::size_t nargs=0; ; ++nargs ) {
-                                       try {
-                                               function::find_function(name, nargs);
-                                               prototype proto = std::pair<std::string, std::size_t>(name, nargs);
-                                               std::pair<prototype_table::iterator, bool> ins = reader.insert(std::pair<prototype,reader_func>(proto, (reader_func)ser));
-                                               if ( ins.second ) break;
-                                       }
-                                       catch ( std::runtime_error ) { }
-                               }
-                       }
+               [+ FOR function +]
+               reader[make_pair("[+ (get "name") +]", [+ 
+                       (if (exist? "args") (get "args") "1")
+                       +])] = [+ (get "name") +]_reader;[+
+               ENDFOR +]
+               std::vector<function_options>::const_iterator it =
+                       registered_functions_hack::get_registered_functions().begin();
+               std::vector<function_options>::const_iterator end =
+                       registered_functions_hack::get_registered_functions().end();
+               unsigned serial = 0;
+               for (; it != end; ++it) {
+                       prototype proto = make_pair(it->get_name(), it->get_nparams());
+                       reader[proto] = encode_serial_as_reader_func(serial);
+                       ++serial;
+               }
+               initialized = true;
+       }
+       return reader;
+}
+
+const prototype_table& get_builtin_reader()
+{
+       using std::make_pair;
+       static bool initialized = false;
+       static prototype_table reader;
+       if (!initialized) {
+               [+ FOR function +]
+               reader[make_pair("[+ (get "name") +]", [+ 
+                       (if (exist? "args") (get "args") "1")
+                       +])] = [+ (get "name") +]_reader;[+
+               ENDFOR +]
+               enum {
+                       log,
+                       exp,
+                       sin,
+                       cos,
+                       tan,
+                       asin,
+                       acos,
+                       atan,
+                       sinh,
+                       cosh,
+                       tanh,
+                       asinh,
+                       acosh,
+                       atanh,
+                       atan2,
+                       Li2,
+                       Li3,
+                       zetaderiv,
+                       Li,
+                       S,
+                       H,
+                       lgamma,
+                       tgamma,
+                       beta,
+                       factorial,
+                       binomial,
+                       Order,
+                       NFUNCTIONS
+               };
+               std::vector<function_options>::const_iterator it =
+                       registered_functions_hack::get_registered_functions().begin();
+               unsigned serial = 0;
+               for ( ; serial<NFUNCTIONS; ++it, ++serial ) {
+                       prototype proto = make_pair(it->get_name(), it->get_nparams());
+                       reader[proto] = encode_serial_as_reader_func(serial);
                }
                }
-               catch ( std::runtime_error ) { }
                initialized = true;
        }
        return reader;
 }
                initialized = true;
        }
        return reader;
 }
-} // namespace GiNaC
 
 
+} // namespace GiNaC