$declare_function_macro = generate(
<<'END_OF_DECLARE_FUNCTION_MACRO','typename T${N}','const T${N} & p${N}','GiNaC::ex(p${N})');
#define DECLARE_FUNCTION_${N}P(NAME) \\
-extern const unsigned function_index_##NAME; \\
-template<${SEQ1}> \\
-inline const GiNaC::function NAME(${SEQ2}) { \\
- return GiNaC::function(function_index_##NAME, ${SEQ3}); \\
+class NAME##_SERIAL { public: static unsigned serial; }; \\
+template<${SEQ1}> const GiNaC::function NAME(${SEQ2}) { \\
+ return GiNaC::function(NAME##_SERIAL::serial, ${SEQ3}); \\
}
END_OF_DECLARE_FUNCTION_MACRO
// end of generated lines
#define REGISTER_FUNCTION(NAME,OPT) \\
-const unsigned function_index_##NAME= \\
+unsigned NAME##_SERIAL::serial = \\
GiNaC::function::register_new(GiNaC::function_options(#NAME).OPT);
namespace GiNaC {
return obj.tinfo()==TINFO_function;
}
-#define is_ex_the_function(OBJ, FUNCNAME) \\
- (GiNaC::is_exactly_a<GiNaC::function>(OBJ) && GiNaC::ex_to<GiNaC::function>(OBJ).get_serial() == GiNaC::function_index_##FUNCNAME)
+template <typename T>
+inline bool is_the_function(const ex & x)
+{
+ return is_exactly_a<function>(x)
+ && ex_to<function>(x).get_serial() == T::serial;
+}
+
+// Check whether OBJ is the specified symbolic function.
+#define is_ex_the_function(OBJ, FUNCNAME) (GiNaC::is_the_function<FUNCNAME##_SERIAL>(OBJ))
} // namespace GiNaC
{
ex result;
- if (serial == function_index_Order) {
+ if (serial == Order_SERIAL::serial) {
// Order Term function only differentiates the argument
return Order(seq[0].diff(s));
} else {
/* Force inclusion of functions from inifcns_gamma and inifcns_zeta
* for static lib (so ginsh will see them). */
-unsigned force_include_tgamma = function_index_tgamma;
-unsigned force_include_zeta1 = function_index_zeta1;
+unsigned force_include_tgamma = tgamma_SERIAL::serial;
+unsigned force_include_zeta1 = zeta1_SERIAL::serial;
} // namespace GiNaC
// overloading at work: we cannot use the macros here
/** Riemann's Zeta-function. */
-extern const unsigned function_index_zeta1;
+class zeta1_SERIAL { public: static unsigned serial; };
template<typename T1>
inline function zeta(const T1 & p1) {
- return function(function_index_zeta1, ex(p1));
+ return function(zeta1_SERIAL::serial, ex(p1));
}
/** Derivatives of Riemann's Zeta-function. */
-extern const unsigned function_index_zeta2;
+class zeta2_SERIAL { public: static unsigned serial; };
template<typename T1, typename T2>
inline function zeta(const T1 & p1, const T2 & p2) {
- return function(function_index_zeta2, ex(p1), ex(p2));
+ return function(zeta2_SERIAL::serial, ex(p1), ex(p2));
+}
+class zeta_SERIAL;
+template<> inline bool is_the_function<class zeta_SERIAL>(const ex & x)
+{
+ return is_the_function<zeta1_SERIAL>(x) || is_the_function<zeta2_SERIAL>(x);
}
/** Gamma-function. */
// overloading at work: we cannot use the macros here
/** Psi-function (aka digamma-function). */
-extern const unsigned function_index_psi1;
+class psi1_SERIAL { public: static unsigned serial; };
template<typename T1>
inline function psi(const T1 & p1) {
- return function(function_index_psi1, ex(p1));
+ return function(psi1_SERIAL::serial, ex(p1));
}
/** Derivatives of Psi-function (aka polygamma-functions). */
-extern const unsigned function_index_psi2;
+class psi2_SERIAL { public: static unsigned serial; };
template<typename T1, typename T2>
inline function psi(const T1 & p1, const T2 & p2) {
- return function(function_index_psi2, ex(p1), ex(p2));
+ return function(psi2_SERIAL::serial, ex(p1), ex(p2));
+}
+class psi_SERIAL;
+template<> inline bool is_the_function<class psi_SERIAL>(const ex & x)
+{
+ return is_the_function<psi1_SERIAL>(x) || is_the_function<psi2_SERIAL>(x);
}
/** Factorial function. */
return (psi(arg+m+_ex1)-recur).series(rel, order, options);
}
-const unsigned function_index_psi1 =
+unsigned psi1_SERIAL::serial =
function::register_new(function_options("psi").
eval_func(psi1_eval).
evalf_func(psi1_evalf).
return (psi(n, arg+m+_ex1)-recur).series(rel, order, options);
}
-const unsigned function_index_psi2 =
+unsigned psi2_SERIAL::serial =
function::register_new(function_options("psi").
eval_func(psi2_eval).
evalf_func(psi2_evalf).
return zeta(_ex1, x);
}
-const unsigned function_index_zeta1 =
+unsigned zeta1_SERIAL::serial =
function::register_new(function_options("zeta").
eval_func(zeta1_eval).
evalf_func(zeta1_evalf).
return zeta(n+1,x);
}
-const unsigned function_index_zeta2 =
+unsigned zeta2_SERIAL::serial =
function::register_new(function_options("zeta").
eval_func(zeta2_eval).
derivative_func(zeta2_deriv).