00001 #ifndef PhysicsTools_Utilities_Function_h 00002 #define PhysicsTools_Utilities_Function_h 00003 #include "PhysicsTools/Utilities/interface/Variables.h" 00004 #include "PhysicsTools/Utilities/interface/Expression.h" 00005 #include <boost/mpl/for_each.hpp> 00006 00007 namespace funct { 00008 00009 struct null_var; 00010 00011 template<typename X1 = null_var, typename X2 = null_var, typename X3 = null_var> 00012 struct Function { 00013 template<typename F> 00014 Function(const F& f) : _f(f) { } 00015 double operator()(typename X1::type x1, 00016 typename X2::type x2, 00017 typename X3::type x3) const { 00018 X1::set(x1); X2::set(x2); X3::set(x3); return _f(); 00019 } 00020 std::ostream& print(std::ostream& cout) const { return _f.print(cout); } 00021 private: 00022 Expression _f; 00023 }; 00024 00025 template<typename X1, typename X2> 00026 struct Function<X1, X2, null_var> { 00027 template<typename F> 00028 Function(const F& f) : _f(f) { } 00029 double operator()(typename X1::type x1, 00030 typename X2::type x2) const { 00031 X1::set(x1); X2::set(x2); return _f(); 00032 } 00033 std::ostream& print(std::ostream& cout) const { return _f.print(cout); } 00034 private: 00035 Expression _f; 00036 }; 00037 00038 template<typename X1> 00039 struct Function<X1, null_var, null_var> { 00040 template<typename F> 00041 Function(const F& f) : _f(f) { } 00042 double operator()(typename X1::type x1) const { X1::set(x1); return _f(); } 00043 std::ostream& print(std::ostream& cout) const { return _f.print(cout); } 00044 private: 00045 Expression _f; 00046 }; 00047 00048 template<typename X1, typename X2, typename X3> 00049 std::ostream& operator<<(std::ostream& cout, const Function<X1, X2, X3>& f) { 00050 return f.print(cout); 00051 } 00052 00053 } 00054 00055 00056 #endif