00001 #include "PhysicsTools/Utilities/src/ExpressionVar.h"
00002 #include "Reflex/Object.h"
00003 #include <Reflex/Builder/NewDelFunctions.h>
00004 #include <map>
00005 #include <assert.h>
00006 using namespace reco::parser;
00007 using namespace ROOT::Reflex;
00008 using namespace std;
00009
00010 ExpressionVar::ExpressionVar(const vector<MethodInvoker>& methods, method::TypeCode retType) :
00011 methods_(methods), retType_(retType) {
00012 }
00013
00014 bool ExpressionVar::isValidReturnType(method::TypeCode retType)
00015 {
00016 using namespace method;
00017 bool ret = false;
00018 switch(retType) {
00019 case(doubleType) : ret = true; break;
00020 case(floatType ) : ret = true; break;
00021 case(intType ) : ret = true; break;
00022 case(uIntType ) : ret = true; break;
00023 case(shortType ) : ret = true; break;
00024 case(uShortType) : ret = true; break;
00025 case(longType ) : ret = true; break;
00026 case(uLongType ) : ret = true; break;
00027 case(charType ) : ret = true; break;
00028 case(uCharType ) : ret = true; break;
00029 case(boolType ) : ret = true; break;
00030 case(invalid):
00031 default:
00032 break;
00033 }
00034 return ret;
00035 }
00036
00037 double ExpressionVar::value(const Object & o) const {
00038 using namespace method;
00039 std::pair<Object,bool> ro(o,false);
00040 std::vector<Object> toBeDeleted;
00041 for(vector<MethodInvoker>::const_iterator m = methods_.begin();
00042 m != methods_.end(); ++m) {
00043 if (ro.second) { toBeDeleted.push_back(ro.first); }
00044 ro = m->value(ro.first);
00045 }
00046 for (std::vector<Object>::iterator it = toBeDeleted.begin(), ed = toBeDeleted.end(); it != ed; ++it) {
00047
00048
00049 trueDelete(*it);
00050 }
00051 void * addr = ro.first.Address();
00052 double ret = 0;
00053 switch(retType_) {
00054 case(doubleType) : ret = * static_cast<double *>(addr); break;
00055 case(floatType ) : ret = * static_cast<float *>(addr); break;
00056 case(intType ) : ret = * static_cast<int *>(addr); break;
00057 case(uIntType ) : ret = * static_cast<unsigned int *>(addr); break;
00058 case(shortType ) : ret = * static_cast<short *>(addr); break;
00059 case(uShortType) : ret = * static_cast<unsigned short *>(addr); break;
00060 case(longType ) : ret = * static_cast<long *>(addr); break;
00061 case(uLongType ) : ret = * static_cast<unsigned long *>(addr); break;
00062 case(charType ) : ret = * static_cast<char *>(addr); break;
00063 case(uCharType ) : ret = * static_cast<unsigned char *>(addr); break;
00064 case(boolType ) : ret = * static_cast<bool *>(addr); break;
00065 default:
00066 assert(false);
00067 };
00068 return ret;
00069 }
00070
00071 void ExpressionVar::trueDelete(ROOT::Reflex::Object & obj) {
00072 static std::map<void *, ROOT::Reflex::NewDelFunctions *> deleters_;
00073 void * reflexTypeId = obj.TypeOf().Id();
00074 std::map<void *, ROOT::Reflex::NewDelFunctions *>::iterator match = deleters_.find(reflexTypeId);
00075 if (match == deleters_.end()) {
00076 ROOT::Reflex::Object newDel = obj.Invoke("__getNewDelFunctions");
00077 ROOT::Reflex::NewDelFunctions *ptr = static_cast<ROOT::Reflex::NewDelFunctions *>(newDel.Address());
00078 match = deleters_.insert(std::make_pair(reflexTypeId, ptr)).first;
00079 }
00080 (*match->second->fDelete)(obj.Address());
00081 }