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
00014
00015
00016
00017
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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
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
00070
00071 owned = true;
00072 }
00073 bool stripped = false;
00074 while(retType.IsTypedef()) {
00075 retType = retType.ToType(); stripped = true;
00076 }
00077 bool isPtr = retType.IsPointer() ;
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 }