00001 #ifndef PhysicsTools_Utilities_AnyMethodArgument_h
00002 #define PhysicsTools_Utilities_AnyMethodArgument_h
00003
00004 #include "Reflex/Object.h"
00005 #include "Reflex/Member.h"
00006 #include "PhysicsTools/Utilities/interface/Exception.h"
00007 #include <algorithm>
00008
00009 #include <string>
00010 #include <boost/variant.hpp>
00011
00012 namespace reco {
00013 namespace parser {
00014
00015 typedef boost::variant<
00016 int8_t, uint8_t,
00017 int16_t, uint16_t,
00018 int32_t, uint32_t,
00019 int64_t, uint64_t,
00020 double,float,
00021 std::string> AnyMethodArgument;
00022
00023 class AnyMethodArgumentFixup : public boost::static_visitor<std::pair<AnyMethodArgument, int> > {
00024 private:
00025 ROOT::Reflex::Type rflxType_;
00026 const std::type_info & type_;
00027 template<typename From, typename To>
00028 std::pair<AnyMethodArgument, int> retOk_(const From &f, int cast) const {
00029 return std::pair<AnyMethodArgument,int>(AnyMethodArgument(static_cast<To>(f)), cast);
00030 }
00031
00032
00033 std::pair<AnyMethodArgument,int> doInt(int t) const {
00034 if (type_ == typeid(int8_t)) { return retOk_<int,int8_t> (t,0); }
00035 if (type_ == typeid(uint8_t)) { return retOk_<int,uint8_t> (t,0); }
00036 if (type_ == typeid(int16_t)) { return retOk_<int,int16_t> (t,0); }
00037 if (type_ == typeid(uint16_t)) { return retOk_<int,uint16_t>(t,0); }
00038 if (type_ == typeid(int32_t)) { return retOk_<int,int32_t> (t,0); }
00039 if (type_ == typeid(uint32_t)) { return retOk_<int,uint32_t>(t,0); }
00040 if (type_ == typeid(int64_t)) { return retOk_<int,int64_t> (t,0); }
00041 if (type_ == typeid(uint64_t)) { return retOk_<int,uint64_t>(t,0); }
00042 if (type_ == typeid(double)) { return retOk_<int,double> (t,1); }
00043 if (type_ == typeid(float)) { return retOk_<int,float> (t,1); }
00044 return std::pair<AnyMethodArgument,int>(t,-1);
00045 }
00046 public:
00047 AnyMethodArgumentFixup(ROOT::Reflex::Type type) :
00048 rflxType_(type),
00049 type_(type.Name() == "string" ? typeid(std::string) : type.TypeInfo())
00050 {
00051 while (rflxType_.IsTypedef()) rflxType_ = rflxType_.ToType();
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 }
00062
00063
00064 std::pair<AnyMethodArgument,int> operator()(const int8_t &t) const { return doInt(t); }
00065 std::pair<AnyMethodArgument,int> operator()(const uint8_t &t) const { return doInt(t); }
00066 std::pair<AnyMethodArgument,int> operator()(const int16_t &t) const { return doInt(t); }
00067 std::pair<AnyMethodArgument,int> operator()(const uint16_t &t) const { return doInt(t); }
00068 std::pair<AnyMethodArgument,int> operator()(const int32_t &t) const { return doInt(t); }
00069 std::pair<AnyMethodArgument,int> operator()(const uint32_t &t) const { return doInt(t); }
00070 std::pair<AnyMethodArgument,int> operator()(const int64_t &t) const { return doInt(t); }
00071 std::pair<AnyMethodArgument,int> operator()(const uint64_t &t) const { return doInt(t); }
00072
00073 std::pair<AnyMethodArgument,int> operator()(const float &t) const {
00074 if (type_ == typeid(double)) { return retOk_<float,double>(t,0); }
00075 if (type_ == typeid(float)) { return retOk_<float,float> (t,0); }
00076 return std::pair<AnyMethodArgument,int>(t,-1);
00077 }
00078 std::pair<AnyMethodArgument,int> operator()(const double &t) const {
00079 if (type_ == typeid(double)) { return retOk_<double,double>(t,0); }
00080 if (type_ == typeid(float)) { return retOk_<double,float> (t,0); }
00081 return std::pair<AnyMethodArgument,int>(t,-1);
00082 }
00083 std::pair<AnyMethodArgument,int> operator()(const std::string &t) const {
00084 if (type_ == typeid(std::string)) { return std::pair<AnyMethodArgument,int>(t,0); }
00085 if (rflxType_.IsEnum()) {
00086 ROOT::Reflex::Member value = rflxType_.MemberByName(t);
00087
00088 if (!value)
00089 throw parser::Exception(t.c_str()) << "Can't convert '" << t << "' to a value for enumerator '" << rflxType_.Name() << "'\n";
00090
00091 if (value.TypeOf().TypeInfo() != typeid(int))
00092 throw parser::Exception(t.c_str()) << "Enumerator '" << rflxType_.Name() << "' is not implemented by type 'int' !!??\n";
00093
00094 int ival = * reinterpret_cast<const int *>(value.Get().Address());
00095
00096 return std::pair<AnyMethodArgument,int>(ival,1);
00097 }
00098 return std::pair<AnyMethodArgument,int>(t,-1);
00099 }
00100
00101 };
00102
00103 class AnyMethodArgument2VoidPtr : public boost::static_visitor<void *> {
00104 public:
00105 template<typename T>
00106 void * operator()(const T &t) const { return const_cast<void*>(static_cast<const void *>(&t)); }
00107 };
00108 }
00109 }
00110
00111 #endif