CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/PhysicsTools/Utilities/interface/Expression.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_Utilities_Expression_h
00002 #define PhysicsTools_Utilities_Expression_h
00003 #include "PhysicsTools/Utilities/interface/FunctionsIO.h"
00004 #include <ostream>
00005 #include <memory>
00006 
00007 namespace funct {
00008 
00009   struct AbsExpression {
00010     virtual ~AbsExpression() { }
00011     virtual double operator()() const = 0;
00012     virtual AbsExpression * clone() const = 0;
00013     virtual std::ostream& print(std::ostream& cout) const = 0;
00014   };
00015 
00016   template<typename F>
00017   struct ExpressionT : public AbsExpression {
00018     inline ExpressionT(const F& f) : _f(f) {}
00019     virtual ~ExpressionT() { }
00020     virtual double operator()() const { return _f(); }
00021     virtual AbsExpression * clone() const { return new ExpressionT<F>(_f); }
00022     virtual std::ostream& print(std::ostream& cout) const { return cout << _f; }
00023   private:
00024     F _f;
00025   };
00026 
00027  struct Expression {
00028    inline Expression() { }
00029    template<typename F>
00030    inline Expression(const F& f) : _f(new ExpressionT<F>(f)) { }
00031    inline Expression(const Expression& e) : _f(e._f->clone()) { }
00032    inline Expression& operator=(const Expression& e) { _f.reset(e._f->clone()); return *this; }
00033    inline double operator()() const { return (*_f)(); }
00034    inline std::ostream& print(std::ostream& cout) const { return _f->print(cout); }
00035  private:
00036    std::auto_ptr<AbsExpression> _f;
00037  };
00038 
00039  inline std::ostream& operator<<(std::ostream& cout, const Expression& e) { 
00040    e.print(cout); return cout; 
00041  }
00042 
00043   struct AbsFunctExpression {
00044     virtual ~AbsFunctExpression() { }
00045     virtual double operator()(double x) const = 0;
00046     virtual AbsFunctExpression * clone() const = 0;
00047   };
00048 
00049   template<typename F>
00050   struct FunctExpressionT : public AbsFunctExpression {
00051     inline FunctExpressionT(const F& f) : _f(f) {}
00052     virtual ~FunctExpressionT() { }
00053     virtual double operator()(double x) const { return _f(x); }
00054     virtual AbsFunctExpression * clone() const { return new FunctExpressionT<F>(_f); }
00055   private:
00056     F _f;
00057   };
00058 
00059  struct FunctExpression {
00060    inline FunctExpression() { }
00061    template<typename F>
00062    inline FunctExpression(const F& f) : _f(new FunctExpressionT<F>(f)) { }
00063    inline FunctExpression(const FunctExpression& e) : _f(e._f->clone()) { }
00064    inline FunctExpression& operator=(const FunctExpression& e) { _f.reset(e._f->clone()); return *this; }
00065    inline double operator()(double x) const { return (*_f)(x); }
00066  private:
00067    std::auto_ptr<AbsFunctExpression> _f;
00068  };
00069 
00070 }
00071 
00072 #endif