File indexing completed on 2025-12-16 10:29:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_Math_ParamFunctor
0015 #define ROOT_Math_ParamFunctor
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include "RtypesCore.h"
0028 #include <functional>
0029 #include <iostream>
0030
0031 namespace ROOT {
0032
0033 namespace Math {
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 template<class T>
0045 class ParamFunctionBase {
0046 public:
0047 virtual ~ParamFunctionBase() {}
0048 virtual T operator() (const T * x, const double *p) = 0;
0049 virtual T operator() (T * x, double *p) = 0;
0050 virtual ParamFunctionBase * Clone() const = 0;
0051 };
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template<class ParentFunctor, class Func >
0066 class ParamFunctorHandler : public ParentFunctor::Impl {
0067
0068 typedef typename ParentFunctor::EvalType EvalType;
0069 typedef typename ParentFunctor::Impl Base;
0070
0071 public:
0072
0073
0074 ParamFunctorHandler(const Func & fun) : fFunc(fun) {}
0075
0076
0077 virtual ~ParamFunctorHandler() {}
0078
0079
0080
0081 inline EvalType operator() (EvalType x, double *p) {
0082 return fFunc(x,p);
0083 }
0084
0085
0086
0087
0088
0089
0090
0091 inline EvalType operator() (EvalType * x, double *p) override {
0092 return FuncEvaluator<Func, EvalType>::Eval(fFunc,x,p);
0093 }
0094
0095 inline EvalType operator() (const EvalType * x, const double *p) override {
0096 return FuncEvaluator<Func, EvalType>::EvalConst(fFunc,x,p);
0097 }
0098
0099
0100 ParamFunctorHandler * Clone() const override {
0101 return new ParamFunctorHandler(fFunc);
0102 }
0103
0104
0105 private :
0106
0107 Func fFunc;
0108
0109
0110 template <typename F,typename T> struct FuncEvaluator {
0111 inline static T Eval( F & f, T *x, double * p) {
0112 return f(x, p);
0113 }
0114
0115 inline static T EvalConst( F & f, const T *x, const double * p) {
0116 return f((T*)x, (double*)p);
0117 }
0118 };
0119
0120 template <typename F, typename T> struct FuncEvaluator<F*, T> {
0121 inline static T Eval( F * f, T *x, double * p) {
0122 return (*f)(x, p);
0123 }
0124
0125 inline static T EvalConst( F * f, const T *x, const double * p) {
0126 return (*f)((T*)x, (double*)p);
0127
0128 }
0129 };
0130
0131 template <typename F,typename T> struct FuncEvaluator<F* const, T> {
0132 inline static T Eval( const F * f, T *x, double * p) {
0133 return (*f)(x, p);
0134 }
0135
0136 inline static T EvalConst( const F * f, const T *x, const double * p) {
0137 return (*f)((T*)x, (double*)p);
0138 }
0139 };
0140
0141
0142 };
0143
0144
0145 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0146
0147
0148 template<class ParentFunctor>
0149 class ParamFunctorHandler<ParentFunctor,TRootIOCtor *> : public ParentFunctor::Impl
0150 {
0151 public:
0152
0153 ParamFunctorHandler(TRootIOCtor *) {}
0154
0155 double operator() (double *, double * ) { return 0; }
0156
0157 double operator() (const double *, const double * ) { return 0; }
0158
0159 ParamFunctorHandler * Clone() const {
0160 return 0;
0161 }
0162
0163 };
0164 #endif
0165
0166
0167
0168
0169
0170
0171
0172 template <class ParentFunctor, typename PointerToObj,
0173 typename PointerToMemFn>
0174 class ParamMemFunHandler : public ParentFunctor::Impl
0175 {
0176 typedef typename ParentFunctor::Impl Base;
0177
0178
0179 public:
0180
0181
0182 ParamMemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
0183 : fObj(pObj), fMemFn(pMemFn)
0184 {}
0185
0186 virtual ~ParamMemFunHandler() {}
0187
0188
0189
0190
0191
0192 inline double operator() (double x, double * p) {
0193 return ((*fObj).*fMemFn)(x,p);
0194 }
0195
0196
0197
0198
0199
0200 inline double operator() (double * x, double * p) override {
0201 return MemFuncEvaluator<PointerToObj,PointerToMemFn, double>::Eval(fObj,fMemFn,x,p);
0202 }
0203
0204 inline double operator() (const double * x, const double * p) override {
0205 return MemFuncEvaluator<PointerToObj,PointerToMemFn, double>::EvalConst(fObj,fMemFn,x,p);
0206 }
0207
0208
0209 ParamMemFunHandler * Clone() const override {
0210 return new ParamMemFunHandler(fObj, fMemFn);
0211 }
0212
0213 private:
0214
0215
0216 template <typename PObj, typename F,typename T> struct MemFuncEvaluator {
0217 inline static T Eval(PObj & pobj, F & f, T *x, double * p) {
0218 return ((*pobj).*f)(x, p);
0219 }
0220
0221 inline static T EvalConst(PObj & pobj, F & f, const T *x, const double * p) {
0222 return ((*pobj).*f)((T*)x, (double*)p);
0223 }
0224 };
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 private :
0250 ParamMemFunHandler(const ParamMemFunHandler&) = delete;
0251 ParamMemFunHandler& operator=(const ParamMemFunHandler&) = delete;
0252
0253 PointerToObj fObj;
0254 PointerToMemFn fMemFn;
0255
0256 };
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 template<class T>
0274 class ParamFunctorTempl {
0275
0276
0277 public:
0278
0279 typedef T EvalType;
0280 typedef ParamFunctionBase<T> Impl;
0281
0282
0283
0284
0285
0286 ParamFunctorTempl () : fImpl(nullptr) {}
0287
0288
0289
0290
0291
0292 template <class PtrObj, typename MemFn>
0293 ParamFunctorTempl(const PtrObj& p, MemFn memFn)
0294 : fImpl(new ParamMemFunHandler<ParamFunctorTempl<T>, PtrObj, MemFn>(p, memFn))
0295 {}
0296
0297
0298
0299
0300
0301
0302 template <typename Func>
0303 explicit ParamFunctorTempl( const Func & f) :
0304 fImpl(new ParamFunctorHandler<ParamFunctorTempl<T>,Func>(f) )
0305 {}
0306
0307
0308
0309
0310 typedef T (* FreeFunc ) (T * , double *);
0311 ParamFunctorTempl(FreeFunc f) :
0312 fImpl(new ParamFunctorHandler<ParamFunctorTempl<T>,FreeFunc>(f) )
0313 {
0314 }
0315
0316
0317 ParamFunctorTempl(const std::function<T(const T *f, const Double_t *param)> &func) :
0318 fImpl(new ParamFunctorHandler<ParamFunctorTempl<T>, const std::function<T(const T *f, const Double_t *param)>>(func))
0319 {
0320 }
0321
0322
0323
0324
0325 virtual ~ParamFunctorTempl () {
0326 if (fImpl) delete fImpl;
0327 }
0328
0329
0330
0331
0332 ParamFunctorTempl(const ParamFunctorTempl & rhs) :
0333 fImpl(nullptr)
0334 {
0335
0336
0337 if (rhs.fImpl) fImpl = rhs.fImpl->Clone();
0338 }
0339
0340
0341
0342
0343 ParamFunctorTempl & operator = (const ParamFunctorTempl & rhs) {
0344
0345
0346
0347
0348
0349
0350 if(this != &rhs) {
0351 if (fImpl) delete fImpl;
0352 fImpl = nullptr;
0353 if (rhs.fImpl)
0354 fImpl = rhs.fImpl->Clone();
0355 }
0356 return *this;
0357 }
0358
0359 void * GetImpl() { return (void *) fImpl; }
0360
0361
0362 T operator() ( T * x, double * p) {
0363 return (*fImpl)(x,p);
0364 }
0365
0366 T operator() (const T * x, const double * p) {
0367 return (*fImpl)(x,p);
0368 }
0369
0370
0371 bool Empty() const { return !fImpl; }
0372
0373
0374 void SetFunction(Impl * f) {
0375 fImpl = f;
0376 }
0377
0378 private :
0379
0380
0381
0382 Impl * fImpl;
0383
0384
0385 };
0386
0387
0388 using ParamFunctor = ParamFunctorTempl<double>;
0389
0390 }
0391
0392 }
0393
0394
0395 #endif