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