Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:24:18

0001 #ifndef PhysicsTools_Utilities_Expression_h
0002 #define PhysicsTools_Utilities_Expression_h
0003 #include "PhysicsTools/Utilities/interface/FunctionsIO.h"
0004 #include <ostream>
0005 #include <memory>
0006 
0007 namespace funct {
0008 
0009   struct AbsExpression {
0010     virtual ~AbsExpression() {}
0011     virtual double operator()() const = 0;
0012     virtual AbsExpression* clone() const = 0;
0013     virtual std::ostream& print(std::ostream& cout) const = 0;
0014   };
0015 
0016   template <typename F>
0017   struct ExpressionT : public AbsExpression {
0018     inline ExpressionT(const F& f) : _f(f) {}
0019     ~ExpressionT() override {}
0020     double operator()() const override { return _f(); }
0021     AbsExpression* clone() const override { return new ExpressionT<F>(_f); }
0022     std::ostream& print(std::ostream& cout) const override { return cout << _f; }
0023 
0024   private:
0025     F _f;
0026   };
0027 
0028   struct Expression {
0029     inline Expression() {}
0030     template <typename F>
0031     inline Expression(const F& f) : _f(new ExpressionT<F>(f)) {}
0032     inline Expression(const Expression& e) : _f(e._f->clone()) {}
0033     inline Expression& operator=(const Expression& e) {
0034       _f.reset(e._f->clone());
0035       return *this;
0036     }
0037     inline double operator()() const { return (*_f)(); }
0038     inline std::ostream& print(std::ostream& cout) const { return _f->print(cout); }
0039 
0040   private:
0041     std::unique_ptr<AbsExpression> _f;
0042   };
0043 
0044   inline std::ostream& operator<<(std::ostream& cout, const Expression& e) {
0045     e.print(cout);
0046     return cout;
0047   }
0048 
0049   struct AbsFunctExpression {
0050     virtual ~AbsFunctExpression() {}
0051     virtual double operator()(double x) const = 0;
0052     virtual AbsFunctExpression* clone() const = 0;
0053   };
0054 
0055   template <typename F>
0056   struct FunctExpressionT : public AbsFunctExpression {
0057     inline FunctExpressionT(const F& f) : _f(f) {}
0058     ~FunctExpressionT() override {}
0059     double operator()(double x) const override { return _f(x); }
0060     AbsFunctExpression* clone() const override { return new FunctExpressionT<F>(_f); }
0061 
0062   private:
0063     F _f;
0064   };
0065 
0066   struct FunctExpression {
0067     inline FunctExpression() {}
0068     template <typename F>
0069     inline FunctExpression(const F& f) : _f(new FunctExpressionT<F>(f)) {}
0070     inline FunctExpression(const FunctExpression& e) : _f(e._f->clone()) {}
0071     inline FunctExpression& operator=(const FunctExpression& e) {
0072       _f.reset(e._f->clone());
0073       return *this;
0074     }
0075     inline double operator()(double x) const { return (*_f)(x); }
0076 
0077   private:
0078     std::unique_ptr<AbsFunctExpression> _f;
0079   };
0080 
0081 }  // namespace funct
0082 
0083 #endif