CMS 3D CMS Logo

ExpressionVar.cc

Go to the documentation of this file.
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       //std::cout << "Should delete Object at " << it->Address() << ", type = " << it->TypeOf().Name() << std::endl;
00048       //it->Destruct(); // this is not ok, it uses "free" while we need "delete"
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 }

Generated on Tue Jun 9 17:42:52 2009 for CMSSW by  doxygen 1.5.4