diff --git a/README/ReleaseNotes/v642/index.md b/README/ReleaseNotes/v642/index.md index e83165d9f748d..ef6d25c58356c 100644 --- a/README/ReleaseNotes/v642/index.md +++ b/README/ReleaseNotes/v642/index.md @@ -64,6 +64,7 @@ Users are encouraged to export their models to ONNX and use the retained ONNX pa * The **RooStats::DebuggingSampler** and **RooStats::DebuggingTestStat** classes are removed. They were mock implementations of the `TestStatSampler` and `TestStatistic` interfaces that returned uniform random numbers independent of the data, only meant for debugging the RooStats framework itself during its initial development. * The `RooTrace` class is deprecated and will be removed in ROOT 6.44. It was a RooFit-specific memory tracer whose instrumentation hooks are compiled out by default, so it has been inert and untested for years. For memory debugging, please use general-purpose tools such as AddressSanitizer or Valgrind instead. * Support for the AIX operating system has been removed from the codebase. This support has not been tested since the late v5 releases and the LLVM JIT is not yet supporting AIX. +* The `ROOT::Math::ParamFunctionBase`, `ROOT::Math::ParamFunctorHandler` and `ROOT::Math::ParamMemFunHandler` classes in `Math/ParamFunctor.h` are removed, together with the `ParamFunctor::GetImpl()` and `ParamFunctor::SetFunction()` methods that exposed them. They implemented the type erasure that `ParamFunctor` now gets from `std::function`, mirroring what was already done for `ROOT::Math::Functor`. Constructing and calling a `ParamFunctor` is unchanged. ## Build System diff --git a/hist/hist/src/TEfficiency.cxx b/hist/hist/src/TEfficiency.cxx index 18ceb70536091..5a2221e8554b5 100644 --- a/hist/hist/src/TEfficiency.cxx +++ b/hist/hist/src/TEfficiency.cxx @@ -7,6 +7,7 @@ #include #include #include +#include //ROOT headers #include "Math/DistFuncMathCore.h" diff --git a/hist/hist/src/TF12.cxx b/hist/hist/src/TF12.cxx index 3ce7ba0939bb3..5d41745e241da 100644 --- a/hist/hist/src/TF12.cxx +++ b/hist/hist/src/TF12.cxx @@ -13,6 +13,7 @@ #include "TH1.h" #include "TVirtualPad.h" +#include /** \class TF12 \ingroup Functions diff --git a/hist/hist/test/test_tkde.cxx b/hist/hist/test/test_tkde.cxx index 3d828a9b765eb..0f2fdc0b90d6f 100644 --- a/hist/hist/test/test_tkde.cxx +++ b/hist/hist/test/test_tkde.cxx @@ -10,6 +10,7 @@ #include "TH1.h" #include "Math/DistFuncMathCore.h" +#include struct TestKDE { diff --git a/math/mathcore/inc/Math/ParamFunctor.h b/math/mathcore/inc/Math/ParamFunctor.h index 789192f0b5600..64004bde6e318 100644 --- a/math/mathcore/inc/Math/ParamFunctor.h +++ b/math/mathcore/inc/Math/ParamFunctor.h @@ -9,256 +9,20 @@ **********************************************************************/ // Header file for Functor classes. -// design is inspired by the Loki Functor #ifndef ROOT_Math_ParamFunctor #define ROOT_Math_ParamFunctor -// #ifndef ROOT_Math_IFunction -// #include "Math/IFunction.h" -// #endif - -// #ifndef Root_Math_StaticCheck -// #include "Math/StaticCheck.h" -// #endif - -//#include - #include "RtypesCore.h" + #include -#include +#include +#include namespace ROOT { namespace Math { -/** - * \defgroup ParamFunctor_int N-D parametric functions - * \brief Multi-dimensional parametric functions - * \ingroup Math - */ - -/** class defining the signature for multi-dim parametric functions - - @ingroup ParamFunctor_int - */ -template -class ParamFunctionBase { - public: - virtual ~ParamFunctionBase() {} - virtual T operator() (const T * x, const double *p) = 0; - virtual T operator() (T * x, double *p) = 0; - virtual ParamFunctionBase * Clone() const = 0; -}; - - - -/** - ParamFunctor Handler class is responsible for wrapping any other functor and pointer to - free C functions. - It can be created from any function implementing the correct signature - corresponding to the requested type - - @ingroup ParamFunctor_int - -*/ - -template -class ParamFunctorHandler : public ParentFunctor::Impl { - - typedef typename ParentFunctor::EvalType EvalType; - typedef typename ParentFunctor::Impl Base; - -public: - - // constructor - ParamFunctorHandler(const Func & fun) : fFunc(fun) {} - - - virtual ~ParamFunctorHandler() {} - - - // for 1D functions - inline EvalType operator() (EvalType x, double *p) { - return fFunc(x,p); - } -// inline double operator() (double x, const double *p) const { -// return fFunc(x,p); -// } - // for multi-dimensional functions -// inline double operator() (const double * x, const double *p) const { -// return fFunc(x,p); -// } - inline EvalType operator() (EvalType * x, double *p) override { - return FuncEvaluator::Eval(fFunc,x,p); - } - - inline EvalType operator() (const EvalType * x, const double *p) override { - return FuncEvaluator::EvalConst(fFunc,x,p); - } - - // clone (use same pointer) - ParamFunctorHandler * Clone() const override { - return new ParamFunctorHandler(fFunc); - } - - -private : - - Func fFunc; - - // structure to distinguish pointer types - template struct FuncEvaluator { - inline static T Eval( F & f, T *x, double * p) { - return f(x, p); - } - - inline static T EvalConst( F & f, const T *x, const double * p) { - return f((T*)x, (double*)p); - } - }; - - template struct FuncEvaluator { - inline static T Eval( F * f, T *x, double * p) { - return (*f)(x, p); - } - - inline static T EvalConst( F * f, const T *x, const double * p) { - return (*f)((T*)x, (double*)p); - - } - }; - - template struct FuncEvaluator { - inline static T Eval( const F * f, T *x, double * p) { - return (*f)(x, p); - } - - inline static T EvalConst( const F * f, const T *x, const double * p) { - return (*f)((T*)x, (double*)p); - } - }; - - // need maybe also volatile ? -}; - - -#if defined(__ROOTCLING__) || defined(G__DICTIONARY) -// needed since Cling initialize it with TRootIOCtor -//class TRootIOCtor; -template -class ParamFunctorHandler : public ParentFunctor::Impl -{ -public: - - ParamFunctorHandler(TRootIOCtor *) {} - - double operator() (double *, double * ) { return 0; } - - double operator() (const double *, const double * ) { return 0; } - // clone (use same pointer) - ParamFunctorHandler * Clone() const { - return 0; - } - -}; -#endif - - -/** - ParamFunctor Handler to Wrap pointers to member functions - - @ingroup ParamFunctor_int -*/ -template -class ParamMemFunHandler : public ParentFunctor::Impl -{ - typedef typename ParentFunctor::Impl Base; - - -public: - - /// constructor from a pointer to the class and a pointer to the function - ParamMemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) - : fObj(pObj), fMemFn(pMemFn) - {} - - virtual ~ParamMemFunHandler() {} - -// inline double operator() (double x, const double * p) const { -// return ((*fObj).*fMemFn)(x,p); -// } - - inline double operator() (double x, double * p) { - return ((*fObj).*fMemFn)(x,p); - } - -// inline double operator() (const double * x, const double * p) const { -// return ((*fObj).*fMemFn)(x,p); -// } - - inline double operator() (double * x, double * p) override { - return MemFuncEvaluator::Eval(fObj,fMemFn,x,p); - } - - inline double operator() (const double * x, const double * p) override { - return MemFuncEvaluator::EvalConst(fObj,fMemFn,x,p); - } - - // clone (use same pointer) - ParamMemFunHandler * Clone() const override { - return new ParamMemFunHandler(fObj, fMemFn); - } - -private: - - // structure to distinguish pointer types - template struct MemFuncEvaluator { - inline static T Eval(PObj & pobj, F & f, T *x, double * p) { - return ((*pobj).*f)(x, p); - } - - inline static T EvalConst(PObj & pobj, F & f, const T *x, const double * p) { - return ((*pobj).*f)((T*)x, (double*)p); - } - }; - - - // // these are needed ?? - // template struct MemFuncEvaluator { - // inline static T Eval(PObj & pobj, F * f, T *x, double * p) { - // return ((*pobj).*f)f(x, p); - // } - - // inline static T EvalConst(PObj & pobj, F * f, const T *x, const double * p) { - // return ((*pobj).*f)((T*)x, (double*)p); - - // } - // }; - - // template struct FuncEvaluator { - // inline static T Eval(PObj &, const F * f, T *x, double * p) { - // return ((*pobj).*f)f(x, p); - // } - - // inline static T EvalConst(PObj & pobj, const F * f, const T *x, const double * p) { - // return ((*pobj).*f)((T*)x, (double*)p); - // } - // }; - -private : - ParamMemFunHandler(const ParamMemFunHandler&) = delete; // Not implemented - ParamMemFunHandler& operator=(const ParamMemFunHandler&) = delete; // Not implemented - - PointerToObj fObj; - PointerToMemFn fMemFn; - -}; - - - - /** Param Functor class for Multidimensional functions. It is used to wrap in a very simple and convenient way @@ -270,127 +34,77 @@ private : */ - -template -class ParamFunctorTempl { - +template +class ParamFunctorTempl { public: + typedef T EvalType; - typedef T EvalType; - typedef ParamFunctionBase Impl; - + /// The signature every wrapped callable is normalized to. + using Signature = T(const T *, const double *); - /** - Default constructor - */ - ParamFunctorTempl () : fImpl(nullptr) {} + ParamFunctorTempl() = default; - - /** - construct from a pointer to member function (multi-dim type) - */ + /// Construct from a pointer to a class object and a pointer to one of its member + /// functions, like `Foo::EvalPar(const double *x, const double *p)`. template - ParamFunctorTempl(const PtrObj& p, MemFn memFn) - : fImpl(new ParamMemFunHandler, PtrObj, MemFn>(p, memFn)) - {} - - - - /** - construct from another generic Functor of multi-dimension - */ - template - explicit ParamFunctorTempl( const Func & f) : - fImpl(new ParamFunctorHandler,Func>(f) ) - {} - - - - // specialization used in TF1 - typedef T (* FreeFunc ) (T * , double *); - ParamFunctorTempl(FreeFunc f) : - fImpl(new ParamFunctorHandler,FreeFunc>(f) ) + ParamFunctorTempl(const PtrObj &p, MemFn memFn) + : fFunc{[p, memFn](const T *x, const double *par) { + return ((*p).*memFn)(const_cast(x), const_cast(par)); + }} { } - // specialization used in TF1 - ParamFunctorTempl(const std::function &func) : - fImpl(new ParamFunctorHandler, const std::function>(func)) + /// Construct from any callable object, or from a pointer to one. + template , ParamFunctorTempl>>> + explicit ParamFunctorTempl(Func f) : fFunc{Adapt(std::move(f))} { } - /** - Destructor (no operations) - */ - virtual ~ParamFunctorTempl () { - if (fImpl) delete fImpl; - } - - /** - Copy constructor - */ - ParamFunctorTempl(const ParamFunctorTempl & rhs) : - fImpl(nullptr) - { -// if (rhs.fImpl.get() != 0) -// fImpl = std::unique_ptr( (rhs.fImpl)->Clone() ); - if (rhs.fImpl) fImpl = rhs.fImpl->Clone(); - } - - /** - Assignment operator - */ - ParamFunctorTempl & operator = (const ParamFunctorTempl & rhs) { -// ParamFunctor copy(rhs); - // swap unique_ptr by hand -// Impl * p = fImpl.release(); -// fImpl.reset(copy.fImpl.release()); -// copy.fImpl.reset(p); - - if(this != &rhs) { - if (fImpl) delete fImpl; - fImpl = nullptr; - if (rhs.fImpl) - fImpl = rhs.fImpl->Clone(); - } - return *this; - } - - void * GetImpl() { return (void *) fImpl; } - - - T operator() ( T * x, double * p) { - return (*fImpl)(x,p); - } + // specialization used in TF1 + typedef T (*FreeFunc)(T *, double *); + ParamFunctorTempl(FreeFunc f) : fFunc{Adapt(f)} {} - T operator() (const T * x, const double * p) { - return (*fImpl)(x,p); - } + // specialization used in TF1 + ParamFunctorTempl(std::function f) : fFunc{std::move(f)} {} + T operator()(T *x, double *p) const { return fFunc(x, p); } - bool Empty() const { return !fImpl; } + T operator()(const T *x, const double *p) const { return fFunc(x, p); } + bool Empty() const { return !fFunc; } - void SetFunction(Impl * f) { - fImpl = f; +private: + /// Normalize any supported callable to the `T (const T *, const double *)` signature. + /// + /// A pointer to a callable object is called through without taking ownership of it, and + /// callables that insist on non-const pointers (the classic `T (T *x, double *p)` + /// signature) get their arguments cast for them. + template + static std::function Adapt(Func f) + { + if constexpr (std::is_pointer_v && std::is_class_v>) { + if constexpr (std::is_invocable_v &, const T *, const double *>) { + return [f](const T *x, const double *p) { return (*f)(x, p); }; + } else { + return [f](const T *x, const double *p) { return (*f)(const_cast(x), const_cast(p)); }; + } + } else if constexpr (std::is_invocable_v) { + return std::move(f); + } else { + return [f = std::move(f)](const T *x, const double *p) mutable { + return f(const_cast(x), const_cast(p)); + }; + } } -private : - - - //std::unique_ptr fImpl; - Impl * fImpl; - - + std::function fFunc; }; - using ParamFunctor = ParamFunctorTempl; - } // end namespace Math +} // end namespace Math } // end namespace ROOT - #endif /* ROOT_Math_ParamFunctor */ diff --git a/math/mathcore/test/fit/testGraphFit.cxx b/math/mathcore/test/fit/testGraphFit.cxx index e04772e4f4048..0b8efc9e82149 100644 --- a/math/mathcore/test/fit/testGraphFit.cxx +++ b/math/mathcore/test/fit/testGraphFit.cxx @@ -20,6 +20,7 @@ #include "TStyle.h" #include +#include #include #include diff --git a/math/mathcore/test/testDistSampler.cxx b/math/mathcore/test/testDistSampler.cxx index 2e32a475c2066..6b150abd4cc0b 100644 --- a/math/mathcore/test/testDistSampler.cxx +++ b/math/mathcore/test/testDistSampler.cxx @@ -1,5 +1,7 @@ // program to test distribution sampling +#include + #include "Math/Factory.h" #include "Math/DistSampler.h" #include "TF1.h" diff --git a/test/stress.cxx b/test/stress.cxx index b52e6600a02cd..7d01592e9a24b 100644 --- a/test/stress.cxx +++ b/test/stress.cxx @@ -72,6 +72,7 @@ #ifndef __CLING__ #include +#include #include #include #include diff --git a/tutorials/analysis/unfold/testUnfold2.C b/tutorials/analysis/unfold/testUnfold2.C index 6c997314b268c..0f4a4dbaceb47 100644 --- a/tutorials/analysis/unfold/testUnfold2.C +++ b/tutorials/analysis/unfold/testUnfold2.C @@ -69,6 +69,8 @@ /// /// \author Stefan Schmitt DESY, 14.10.2008 +#include + #include #include #include diff --git a/tutorials/hist/hist101_TH1_autobinning.C b/tutorials/hist/hist101_TH1_autobinning.C index dc19339939595..01f20fffcb52f 100644 --- a/tutorials/hist/hist101_TH1_autobinning.C +++ b/tutorials/hist/hist101_TH1_autobinning.C @@ -9,6 +9,8 @@ /// \date November 2017 /// \author Gerardo Ganis +#include + #include "TF1.h" #include "TH1D.h" #include "TMath.h" diff --git a/tutorials/math/fit/FitHistoInFile.C b/tutorials/math/fit/FitHistoInFile.C index 2b79f43513dbd..e4a11e4d3ec32 100644 --- a/tutorials/math/fit/FitHistoInFile.C +++ b/tutorials/math/fit/FitHistoInFile.C @@ -11,6 +11,8 @@ /// \author Author E. von Toerne /// Based on FittingDemo.C by Rene Brun +#include + #include "TH1.h" #include "TMath.h" #include "TF1.h" diff --git a/tutorials/math/goftest.C b/tutorials/math/goftest.C index 8d36e2071ed7d..d2d1367ca8b94 100644 --- a/tutorials/math/goftest.C +++ b/tutorials/math/goftest.C @@ -14,6 +14,7 @@ /// \author Bartolomeu Rabacal #include +#include #include "TCanvas.h" #include "TPaveText.h" #include "TH1.h"