CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MethodInvoker.cc
Go to the documentation of this file.
7 
8 #include <algorithm>
9 using namespace reco::parser;
10 using namespace std;
11 
12 MethodInvoker::MethodInvoker(const edm::FunctionWithDict & method, const vector<AnyMethodArgument> & ints) :
13  method_(method), member_(), ints_(ints), isFunction_(true)
14 {
15  setArgs();
16  /*std::cout << "Booking " << methodName()
17  << " from " << method_.declaringType().name()
18  << " with " << args_.size() << " arguments"
19  << " (were " << ints.size() << ")"
20  << std::endl;*/
21 }
22 
24  method_(), member_(member), ints_(), isFunction_(false)
25 {
26  setArgs();
27  /*std::cout << "Booking " << methodName()
28  << " from " << member_.declaringType().name()
29  << " with " << args_.size() << " arguments"
30  << " (were " << ints.size() << ")"
31  << std::endl;*/
32 }
33 
35  method_(other.method_), member_(other.member_), ints_(other.ints_), isFunction_(other.isFunction_) {
36  setArgs();
37 }
38 
40  method_ = other.method_;
41  member_ = other.member_;
42  ints_ = other.ints_;
43  isFunction_ = other.isFunction_;
44  setArgs();
45  return *this;
46 }
47 
49  for(size_t i = 0; i < ints_.size(); ++i) {
50  args_.push_back( boost::apply_visitor( AnyMethodArgument2VoidPtr(), ints_[i] ) );
51  }
52 }
53 
56  if(isFunction_) {
57  return method_.name();
58  }
59  return member_.name();
60 }
61 
64  if(isFunction_) {
65  return method_.typeOf().qualifiedName();
66  }
67  return member_.typeOf().qualifiedName();
68 }
69 
72  edm::ObjectWithDict ret = retstore;
73  edm::TypeWithDict retType;
74  if(isFunction_) {
75  /*std::cout << "Invoking " << methodName()
76  << " from " << method_.declaringType().qualifiedName()
77  << " on an instance of " << o.dynamicType().qualifiedName()
78  << " at " << o.address()
79  << " with " << args_.size() << " arguments"
80  << std::endl; */
81  method_.invoke(o, &ret, args_);
82  retType = method_.finalReturnType(); // this is correct, it takes pointers and refs into account
83  } else {
84  /*std::cout << "Invoking " << methodName()
85  << " from " << member_.declaringType().qualifiedName()
86  << " on an instance of " << o.dynamicType().qualifiedName()
87  << " at " << o.address()
88  << " with " << args_.size() << " arguments"
89  << std::endl; */
90  ret = member_.get(o);
91  retType = member_.typeOf();
92  }
93  void * addr = ret.address();
94  //std::cout << "Stored result of " << methodName() << " (type " << returnTypeName() << ") at " << addr << std::endl;
95  if(addr==0) {
97  << "method \"" << methodName() << "\" called with " << args_.size()
98  << " arguments returned a null pointer ";
99  }
100  //std::cout << "Return type is " << retType.qualifiedName() << std::endl;
101 
102  if(retType.isPointer() || retType.isReference()) { // both need (void **)->(void *) conversion
103  if (retType.isPointer()) {
104  retType = retType.toType(); // for Pointers, I get the real type this way
105  } else {
106  retType = edm::TypeWithDict(retType, 0L); // strip cv & ref flags
107  }
108  ret = edm::ObjectWithDict(retType, *static_cast<void **>(addr));
109  //std::cout << "Now type is " << retType.qualifiedName() << std::endl;
110  }
111  if(!ret) {
113  << "method \"" << methodName()
114  << "\" returned void invoked on object of type \""
115  << o.typeOf().qualifiedName() << "\"\n";
116  }
117  return ret;
118 }
119 
120 LazyInvoker::LazyInvoker(const std::string &name, const std::vector<AnyMethodArgument> & args) :
121  name_(name),
122  argsBeforeFixups_(args)
123 {
124 }
125 
127 {
128 }
129 
130 const SingleInvoker &
132 {
133  //std::cout << "LazyInvoker for " << name_ << " called on type " << type.qualifiedName() << std::endl;
135  if (!invoker) {
136  //std::cout << " Making new invoker for " << name_ << " on type " << type.qualifiedName() << std::endl;
137  invoker.reset(new SingleInvoker(type, name_, argsBeforeFixups_));
138  }
139  return * invoker;
140 }
141 
143 LazyInvoker::invoke(const edm::ObjectWithDict & o, std::vector<edm::ObjectWithDict> &v) const
144 {
145  pair<edm::ObjectWithDict, bool> ret(o,false);
146  do {
147  edm::TypeWithDict type = ret.first.typeOf();
148  if (type.isClass()) type = ret.first.dynamicType();
149  ret = invoker(type).invoke(edm::ObjectWithDict(type, ret.first.address()), v);
150  } while (ret.second == false);
151  return ret.first;
152 }
153 
154 double
155 LazyInvoker::invokeLast(const edm::ObjectWithDict & o, std::vector<edm::ObjectWithDict> &v) const
156 {
157  pair<edm::ObjectWithDict, bool> ret(o,false);
158  const SingleInvoker *i = 0;
159  do {
160  edm::TypeWithDict type = ret.first.typeOf();
161  if (type.isClass()) type = ret.first.dynamicType();
162  i = & invoker(type);
163  ret = i->invoke(edm::ObjectWithDict(type, ret.first.address()), v);
164  } while (ret.second == false);
165  return i->retToDouble(ret.first);
166 }
167 
169  const std::string &name,
170  const std::vector<AnyMethodArgument> &args)
171 {
172  TypeStack typeStack(1, type);
173  LazyMethodStack dummy;
174  MethodArgumentStack dummy2;
175  MethodSetter setter(invokers_, dummy, typeStack, dummy2, false);
176  isRefGet_ = !setter.push(name, args, "LazyInvoker dynamic resolution", false);
177  //std::cerr << "SingleInvoker on type " << type.qualifiedName() << ", name " << name << (isRefGet_ ? " is just a ref.get " : " is real") << std::endl;
178  if(invokers_.front().isFunction()) {
179  edm::TypeWithDict retType = invokers_.front().method().finalReturnType();
181  } else {
183  storageNeedsDestructor_ = false;
184  }
185  retType_ = reco::typeCode(typeStack[1]); // typeStack[0] = type of self, typeStack[1] = type of ret
186 }
187 
189 {
191 }
192 
193 pair<edm::ObjectWithDict,bool>
194 SingleInvoker::invoke(const edm::ObjectWithDict & o, std::vector<edm::ObjectWithDict> &v) const
195 {
196  /* std::cerr << "[SingleInvoker::invoke] member " << invokers_.front().method().qualifiedName() <<
197  " of type " << o.typeOf().qualifiedName() <<
198  (!isRefGet_ ? " is one shot" : " needs another round") << std::endl; */
199  pair<edm::ObjectWithDict,bool> ret(invokers_.front().invoke(o, storage_), !isRefGet_);
201  //std::cout << "Storage type: " << storage_.typeOf().qualifiedName() << ", I have to call the destructor." << std::endl;
202  v.push_back(storage_);
203  }
204  return ret;
205 }
206 
207 double
211  }
213 }
214 
215 void
218  << "member \"" << invokers_.back().methodName()
219  << "\" return type is \"" << invokers_.back().returnTypeName()
220  << "\" retured a \"" << o.typeOf().qualifiedName()
221  << "\" which is not convertible to double.";
222 }
SingleInvoker(const edm::TypeWithDict &t, const std::string &name, const std::vector< AnyMethodArgument > &args)
type
Definition: HCALResponse.h:21
int i
Definition: DBlmapReader.cc:9
method::TypeCode retType_
Definition: MethodInvoker.h:63
std::vector< void * > args_
Definition: MethodInvoker.h:38
MethodInvoker & operator=(const MethodInvoker &)
MethodInvoker(const edm::FunctionWithDict &method, const std::vector< AnyMethodArgument > &ints=std::vector< AnyMethodArgument >())
void invoke(ObjectWithDict const &obj, ObjectWithDict *ret, std::vector< void * > const &values=std::vector< void * >()) const
edm::FunctionWithDict method_
Definition: MethodInvoker.h:35
bool isRefGet_
true if this invoker just pops out a ref and returns (ref.get(), false)
Definition: MethodInvoker.h:68
void * address() const
std::pair< edm::ObjectWithDict, bool > invoke(const edm::ObjectWithDict &o, std::vector< edm::ObjectWithDict > &v) const
bool push(const std::string &, const std::vector< AnyMethodArgument > &, const char *, bool deep=true) const
Definition: MethodSetter.cc:43
static bool makeStorage(edm::ObjectWithDict &obj, const edm::TypeWithDict &retType)
std::vector< edm::TypeWithDict > TypeStack
Definition: TypeStack.h:17
std::string qualifiedName() const
std::string name() const
double invokeLast(const edm::ObjectWithDict &o, std::vector< edm::ObjectWithDict > &v) const
invoke and coerce result to double
static void delStorage(edm::ObjectWithDict &obj)
boost::shared_ptr< SingleInvoker > SingleInvokerPtr
Definition: MethodInvoker.h:87
TypeWithDict toType() const
static bool isValidReturnType(method::TypeCode)
std::vector< AnyMethodArgument > MethodArgumentStack
static double objToDouble(const edm::ObjectWithDict &obj, method::TypeCode type)
bool isClass() const
std::string name() const
edm::ObjectWithDict storage_
Definition: MethodInvoker.h:65
TypeCode typeCode(const edm::TypeWithDict &t)
Definition: returnType.cc:38
ObjectWithDict get() const
TypeWithDict typeOf() const
edm::ObjectWithDict invoke(const edm::ObjectWithDict &o, std::vector< edm::ObjectWithDict > &v) const
TypeWithDict const & typeOf() const
TypeWithDict typeOf() const
TypeWithDict finalReturnType() const
std::vector< LazyInvoker > LazyMethodStack
Definition: MethodStack.h:18
std::string returnTypeName() const
double retToDouble(const edm::ObjectWithDict &o) const
bool isReference() const
edm::ObjectWithDict invoke(const edm::ObjectWithDict &o, edm::ObjectWithDict &retstore) const
std::vector< AnyMethodArgument > ints_
Definition: MethodInvoker.h:37
const SingleInvoker & invoker(const edm::TypeWithDict &t) const
std::type_info const & id() const
void throwFailedConversion(const edm::ObjectWithDict &o) const
std::vector< AnyMethodArgument > argsBeforeFixups_
Definition: MethodInvoker.h:86
std::string methodName() const
volatile std::atomic< bool > shutdown_flag false
std::vector< MethodInvoker > invokers_
Definition: MethodInvoker.h:64
bool isPointer() const
std::map< edm::TypeID, SingleInvokerPtr > invokers_
Definition: MethodInvoker.h:88
LazyInvoker(const std::string &name, const std::vector< AnyMethodArgument > &args)
edm::MemberWithDict member_
Definition: MethodInvoker.h:36