#ifndef ROOT_Math_ParamFunctor
#define ROOT_Math_ParamFunctor
#include <vector>
#include <iostream>
namespace ROOT {
namespace Math {
class ParamFunctionBase {
public:
virtual ~ParamFunctionBase() {}
virtual double operator() (double * x, double *p) = 0;
virtual ParamFunctionBase * Clone() const = 0;
};
#ifndef __CINT__
template<class ParentFunctor, class Func >
class ParamFunctorHandler : public ParentFunctor::Impl {
typedef typename ParentFunctor::Impl Base;
public:
ParamFunctorHandler(const Func & fun) : fFunc(fun) {}
virtual ~ParamFunctorHandler() {}
inline double operator() (double x, double *p) {
return fFunc(x,p);
}
inline double operator() (double * x, double *p) {
return FuncEvaluator<Func>::Eval(fFunc,x,p);
}
ParamFunctorHandler * Clone() const {
return new ParamFunctorHandler(fFunc);
}
private :
Func fFunc;
template <typename F> struct FuncEvaluator {
inline static double Eval( F & f, double *x, double * p) {
return f(x,p);
}
};
template <typename F> struct FuncEvaluator<F*> {
inline static double Eval( F * f, double *x, double * p) {
return (*f)(x,p);
}
};
template <typename F> struct FuncEvaluator<F* const> {
inline static double Eval( const F * f, double *x, double * p) {
return (*f)(x,p);
}
};
};
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
template<class ParentFunctor>
class ParamFunctorHandler<ParentFunctor,TRootIOCtor *> : public ParentFunctor::Impl
{
public:
ParamFunctorHandler(TRootIOCtor *) {}
double operator() (double *, double * ) { return 0; }
ParamFunctorHandler * Clone() const {
return 0;
}
};
#endif
template <class ParentFunctor, typename PointerToObj,
typename PointerToMemFn>
class ParamMemFunHandler : public ParentFunctor::Impl
{
typedef typename ParentFunctor::Impl Base;
public:
ParamMemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
: fObj(pObj), fMemFn(pMemFn)
{}
virtual ~ParamMemFunHandler() {}
inline double operator() (double x, double * p) {
return ((*fObj).*fMemFn)(x,p);
}
inline double operator() (double * x, double * p) {
return ((*fObj).*fMemFn)(x,p);
}
ParamMemFunHandler * Clone() const {
return new ParamMemFunHandler(fObj, fMemFn);
}
private :
ParamMemFunHandler(const ParamMemFunHandler&);
ParamMemFunHandler& operator=(const ParamMemFunHandler&);
PointerToObj fObj;
PointerToMemFn fMemFn;
};
#endif
class ParamFunctor {
public:
typedef ParamFunctionBase Impl;
ParamFunctor () : fImpl(0) {}
template <class PtrObj, typename MemFn>
ParamFunctor(const PtrObj& p, MemFn memFn)
: fImpl(new ParamMemFunHandler<ParamFunctor, PtrObj, MemFn>(p, memFn))
{}
template <typename Func>
explicit ParamFunctor( const Func & f) :
fImpl(new ParamFunctorHandler<ParamFunctor,Func>(f) )
{}
typedef double (* FreeFunc ) (double * , double *);
ParamFunctor(FreeFunc f) :
fImpl(new ParamFunctorHandler<ParamFunctor,FreeFunc>(f) )
{
}
virtual ~ParamFunctor () {
if (fImpl) delete fImpl;
}
ParamFunctor(const ParamFunctor & rhs) :
fImpl(0)
{
if (rhs.fImpl != 0) fImpl = rhs.fImpl->Clone();
}
ParamFunctor & operator = (const ParamFunctor & rhs) {
if(this != &rhs) {
if (fImpl) delete fImpl;
fImpl = 0;
if (rhs.fImpl != 0)
fImpl = rhs.fImpl->Clone();
}
return *this;
}
void * GetImpl() { return (void *) fImpl; }
double operator() (double * x, double * p) {
return (*fImpl)(x,p);
}
bool Empty() { return fImpl == 0; }
void SetFunction(Impl * f) {
fImpl = f;
}
private :
Impl * fImpl;
};
}
}
#endif /* ROOT_Math_ParamFunctor */