CMS 3D CMS Logo

MethodInvoker.cc

Go to the documentation of this file.
00001 #include "PhysicsTools/Utilities/src/MethodInvoker.h"
00002 #include "PhysicsTools/Utilities/src/findMethod.h"
00003 #include "FWCore/Utilities/interface/EDMException.h"
00004 #include <algorithm>
00005 using namespace reco::parser;
00006 using namespace ROOT::Reflex;
00007 using namespace std;
00008 
00009 MethodInvoker::MethodInvoker(const Member & method, const vector<AnyMethodArgument> & ints) :
00010   method_(method), ints_(ints), isFunction_(method.IsFunctionMember())
00011 { 
00012   setArgs();
00013   /*std::cout << "Booking " << method_.Name() 
00014             << " from " << method_.DeclaringType().Name() 
00015             << " with " << args_.size() << " arguments"
00016             << " (were " << ints.size() << ")"
00017             << std::endl; */
00018 }
00019 
00020 MethodInvoker::MethodInvoker(const MethodInvoker & other) :
00021   method_(other.method_), ints_(other.ints_), isFunction_(other.isFunction_) {
00022   setArgs();
00023 }
00024 
00025 MethodInvoker & MethodInvoker::operator=(const MethodInvoker & other) {
00026   method_ = other.method_;
00027   ints_ = other.ints_;
00028   isFunction_ = other.isFunction_;
00029   setArgs();
00030   return *this;
00031 }
00032 
00033 void MethodInvoker::setArgs() {
00034   for(size_t i = 0; i < ints_.size(); ++i) {
00035       args_.push_back( boost::apply_visitor( AnyMethodArgument2VoidPtr(), ints_[i] ) );
00036   }
00037 }
00038 
00039 std::pair<Object,bool> MethodInvoker::value(const Object & o) const {
00040   Object ret;
00041   bool   owned = false;
00042   /* no need to check the type at run time
00043   if(method_.IsVirtual()) {
00044     Type dynType = o.DynamicType();
00045     Member met = reco::findMethod(dynType, method_.Name(), args_.size()).first;
00046     if(!met)
00047       throw edm::Exception(edm::errors::InvalidReference)
00048         << "method \"" << method_.Name() << "\" not found in dynamic type \"" 
00049         << dynType.Name() << "\"\n";
00050     ret = met.Invoke(Object(dynType, o.Address()), args_);
00051     } else */
00052   /*std::cout << "Invoking " << method_.Name() 
00053             << " from " << method_.DeclaringType().Name() 
00054             << " on an instance of " << o.DynamicType().Name() 
00055             << " with " << args_.size() << " arguments"
00056             << std::endl;*/
00057   if(isFunction_) {
00058      ret = method_.Invoke(o, args_);
00059   } else {
00060      ret = method_.Get(o);
00061   }
00062   void * addr = ret.Address(); 
00063   if(addr==0)
00064     throw edm::Exception(edm::errors::InvalidReference)
00065       << "method \"" << method_.Name() << "\" called with " << args_.size() 
00066       << " arguments returned a null pointer ";   
00067   Type retType = ret.TypeOf();
00068   if (retType.IsClass() && !retType.IsPointer() && !retType.IsReference()) {
00069     //std::cout << "Object, and not pointer, at " << addr << ", type " <<  retType.Name() 
00070     //          << ", from " << method_.Name() << ": I need to delete it" << std::endl;
00071     owned = true;
00072   }
00073   bool stripped = false;
00074   while(retType.IsTypedef()) { 
00075     retType = retType.ToType(); stripped = true; 
00076   }
00077   bool isPtr = retType.IsPointer() /* isRef = retType.IsReference() */;
00078   if(isPtr) {
00079     if(!stripped) {
00080       stripped = true;
00081       retType = retType.ToType();
00082       while(retType.IsTypedef()) {
00083         retType = retType.ToType();
00084       }
00085     }
00086   }
00087   if(stripped)
00088     ret = Object(retType, addr);
00089   if(!ret) 
00090      throw edm::Exception(edm::errors::Configuration)
00091       << "method \"" << method_.Name() 
00092       << "\" returned void invoked on object of type \"" 
00093       << o.TypeOf().Name() << "\"\n";
00094   return std::make_pair(ret,owned);
00095 }

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