X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Ffunction.pl;h=e2b4374f4e745701a82a87038ce7a3b23d879def;hb=ed62b717aa0383e08b4a2642cd923498898e1a18;hp=1a1fcbaaf073dac967107b31cf929ab2431755f0;hpb=66c0f31c678e6c1938d637636b230ea376c157c1;p=ginac.git diff --git a/ginac/function.pl b/ginac/function.pl index 1a1fcbaa..e2b4374f 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -31,15 +31,25 @@ sub generate { return $res; } -$declare_function_macro=generate( - <<'END_OF_DECLARE_FUNCTION_MACRO','ex const & p${N}','p${N}'); +$declare_function_macro_namespace=generate( + <<'END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE','GiNaC::ex const & p${N}','p${N}'); #define DECLARE_FUNCTION_${N}P(NAME) \\ -extern unsigned function_index_##NAME; \\ +extern const unsigned function_index_##NAME; \\ +inline GiNaC::function NAME(${SEQ1}) { \\ + return GiNaC::function(function_index_##NAME, ${SEQ2}); \\ +} + +END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE + +$declare_function_macro_no_namespace=generate( + <<'END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE','ex const & p${N}','p${N}'); +#define DECLARE_FUNCTION_${N}P(NAME) \\ +extern const unsigned function_index_##NAME; \\ inline function NAME(${SEQ1}) { \\ return function(function_index_##NAME, ${SEQ2}); \\ } -END_OF_DECLARE_FUNCTION_MACRO +END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE $typedef_eval_funcp=generate( 'typedef ex (* eval_funcp_${N})(${SEQ1});'."\n", @@ -100,7 +110,12 @@ END_OF_DIFF_SWITCH_STATEMENT $series_switch_statement=generate( <<'END_OF_SERIES_SWITCH_STATEMENT','seq[${N}-1]',''); case ${N}: - return ((series_funcp_${N})(registered_functions()[serial].s))(${SEQ1},s,point,order); + try { + res = ((series_funcp_${N})(registered_functions()[serial].s))(${SEQ1},s,point,order); + } catch (do_taylor) { + res = basic::series(s, point, order); + } + return res; break; END_OF_SERIES_SWITCH_STATEMENT @@ -119,13 +134,14 @@ END_OF_REGISTER_NEW_IMPLEMENTATION $interface=< #include + +#ifdef __CINT__ +// CINT needs to work properly with +#include +#endif // def __CINT__ + #include -class function; +#ifndef NO_GINAC_NAMESPACE + +// the following lines have been generated for max. ${maxargs} parameters +$declare_function_macro_namespace +// end of generated lines + +#else // ndef NO_GINAC_NAMESPACE // the following lines have been generated for max. ${maxargs} parameters -$declare_function_macro +$declare_function_macro_no_namespace // end of generated lines +#endif // ndef NO_GINAC_NAMESPACE + +#ifndef NO_GINAC_NAMESPACE + #define REGISTER_FUNCTION(NAME,E,EF,D,S) \\ -unsigned function_index_##NAME=function::register_new(#NAME,E,EF,D,S); +const unsigned function_index_##NAME=GiNaC::function::register_new(#NAME,E,EF,D,S); + +#else // ndef NO_GINAC_NAMESPACE + +#define REGISTER_FUNCTION(NAME,E,EF,D,S) \\ +const unsigned function_index_##NAME=function::register_new(#NAME,E,EF,D,S); + +#endif // ndef NO_GINAC_NAMESPACE #define BEGIN_TYPECHECK \\ bool automatic_typecheck=true; @@ -166,17 +205,34 @@ if (!is_ex_exactly_of_type(VAR,TYPE)) { \\ automatic_typecheck=false; \\ } else +#ifndef NO_GINAC_NAMESPACE + +#define TYPECHECK_INTEGER(VAR) \\ +if (!(VAR).info(GiNaC::info_flags::integer)) { \\ + automatic_typecheck=false; \\ +} else + +#else // ndef NO_GINAC_NAMESPACE + #define TYPECHECK_INTEGER(VAR) \\ if (!(VAR).info(info_flags::integer)) { \\ automatic_typecheck=false; \\ } else +#endif // ndef NO_GINAC_NAMESPACE + #define END_TYPECHECK(RV) \\ {} \\ if (!automatic_typecheck) { \\ return RV.hold(); \\ } +#ifndef NO_GINAC_NAMESPACE +namespace GiNaC { +#endif // ndef NO_GINAC_NAMESPACE + +class function; + typedef ex (* eval_funcp)(); typedef ex (* evalf_funcp)(); typedef ex (* diff_funcp)(); @@ -203,6 +259,9 @@ struct registered_function_info { and user defined functions */ class function : public exprseq { + GINAC_DECLARE_REGISTERED_CLASS(function, exprseq) + + // CINT has a linking problem friend void ginsh_get_ginac_functions(void); // member functions @@ -268,14 +327,27 @@ protected: // utility macros +#ifndef NO_GINAC_NAMESPACE + +#define is_ex_the_function(OBJ, FUNCNAME) \\ + (is_ex_exactly_of_type(OBJ, function) && static_cast(OBJ.bp)->getserial() == function_index_##FUNCNAME) + +#else // ndef NO_GINAC_NAMESPACE + #define is_ex_the_function(OBJ, FUNCNAME) \\ (is_ex_exactly_of_type(OBJ, function) && static_cast(OBJ.bp)->getserial() == function_index_##FUNCNAME) +#endif // ndef NO_GINAC_NAMESPACE + // global constants extern const function some_function; extern type_info const & typeid_function; +#ifndef NO_GINAC_NAMESPACE +} // namespace GiNaC +#endif // ndef NO_GINAC_NAMESPACE + #endif // ndef __GINAC_FUNCTION_H__ END_OF_INTERFACE @@ -283,13 +355,14 @@ END_OF_INTERFACE $implementation=<::const_iterator i = registered_functions().begin(), iend = registered_functions().end(); + while (i != iend) { + if (s == i->name) { + serial = ser; + return; + } + i++; ser++; + } + throw (std::runtime_error("unknown function '" + s + "' in archive")); + } else + throw (std::runtime_error("unnamed function in archive")); +} + +/** Unarchive the object. */ +ex function::unarchive(const archive_node &n, const lst &sym_lst) +{ + return (new function(n, sym_lst))->setflag(status_flags::dynallocated); +} + +/** Archive the object. */ +void function::archive(archive_node &n) const +{ + inherited::archive(n); + GINAC_ASSERT(serial < registered_functions().size()); + n.add_string("name", registered_functions()[serial].name); +} + ////////// // functions overriding virtual functions from bases classes ////////// @@ -411,7 +533,7 @@ void function::printraw(ostream & os) const { debugmsg("function printraw",LOGLEVEL_PRINT); - ASSERT(serial(const_cast(other)); if (serial!=o.serial) { @@ -554,7 +677,7 @@ int function::compare_same_type(basic const & other) const bool function::is_equal_same_type(basic const & other) const { - ASSERT(is_of_type(other, function)); + GINAC_ASSERT(is_of_type(other, function)); function const & o=static_cast(const_cast(other)); if (serial!=o.serial) return false; @@ -591,7 +714,7 @@ unsigned function::return_type_tinfo(void) const ex function::pdiff(unsigned diff_param) const // partial differentiation { - ASSERT(serial