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.
2 
8 
9 #include <algorithm>
10 using namespace reco::parser;
11 using namespace std;
12 
15  const vector<AnyMethodArgument>& ints)
16  : method_(method)
17  , member_()
18  , ints_(ints)
19  , isFunction_(true)
20 {
21  setArgs();
22  if (isFunction_) {
24  }
25  //std::cout <<
26  // "Booking " <<
27  // methodName() <<
28  // " from " <<
29  // method_.declaringType().name() <<
30  // " with " <<
31  // args_.size() <<
32  // " arguments" <<
33  // " (were " <<
34  // ints.size() <<
35  // ")" <<
36  // std::endl;
37 }
38 
41  : method_()
42  , member_(member)
43  , ints_()
44  , isFunction_(false)
45 {
46  setArgs();
47  //std::cout <<
48  // "Booking " <<
49  // methodName() <<
50  // " from " <<
51  // member_.declaringType().name() <<
52  // " with " <<
53  // args_.size() <<
54  // " arguments" <<
55  // " (were " <<
56  // ints.size() <<
57  // ")" <<
58  // std::endl;
59 }
60 
63  : method_(rhs.method_)
64  , member_(rhs.member_)
65  , ints_(rhs.ints_)
66  , isFunction_(rhs.isFunction_)
67  , retTypeFinal_(rhs.retTypeFinal_)
68 {
69  setArgs();
70 }
71 
75 {
76  if (this != &rhs) {
77  method_ = rhs.method_;
78  member_ = rhs.member_;
79  ints_ = rhs.ints_;
82 
83  setArgs();
84  }
85  return *this;
86 }
87 
88 void
91 {
92  for (size_t i = 0; i < ints_.size(); ++i) {
93  args_.push_back(boost::apply_visitor(AnyMethodArgument2VoidPtr(), ints_[i]));
94  }
95 }
96 
99 methodName() const
100 {
101  if (isFunction_) {
102  return method_.name();
103  }
104  return member_.name();
105 }
106 
110 {
111  if (isFunction_) {
112  return method_.typeName();
113  }
114  return member_.typeOf().qualifiedName();
115 }
116 
120 {
121  edm::ObjectWithDict ret = retstore;
122  edm::TypeWithDict retType;
123  if (isFunction_) {
124  //std::cout << "Invoking " << methodName()
125  // << " from " << method_.declaringType().qualifiedName()
126  // << " on an instance of " << o.dynamicType().qualifiedName()
127  // << " at " << o.address()
128  // << " with " << args_.size() << " arguments"
129  // << std::endl;
130  method_.invoke(o, &ret, args_);
131  // this is correct, it takes pointers and refs into account
132  retType = retTypeFinal_;
133  }
134  else {
135  //std::cout << "Invoking " << methodName()
136  // << " from " << member_.declaringType().qualifiedName()
137  // << " on an instance of " << o.dynamicType().qualifiedName()
138  // << " at " << o.address()
139  // << " with " << args_.size() << " arguments"
140  // << std::endl;
141  ret = member_.get(o);
142  retType = member_.typeOf();
143  }
144  void* addr = ret.address();
145  //std::cout << "Stored result of " << methodName() << " (type " <<
146  // returnTypeName() << ") at " << addr << std::endl;
147  if (addr == 0) {
149  << "method \"" << methodName() << "\" called with " << args_.size()
150  << " arguments returned a null pointer ";
151  }
152  //std::cout << "Return type is " << retType.qualifiedName() << std::endl;
153  if (retType.isPointer() || retType.isReference()) {
154  // both need void** -> void* conversion
155  if (retType.isPointer()) {
156  retType = retType.toType();
157  }
158  else {
159  // strip cv & ref flags
160  // FIXME: This is only true if the propery passed to the constructor
161  // overrides the const and reference flags.
162  retType = retType.stripConstRef();
163  }
164  ret = edm::ObjectWithDict(retType, *static_cast<void**>(addr));
165  //std::cout << "Now type is " << retType.qualifiedName() << std::endl;
166  }
167  if (!bool(ret)) {
169  << "method \"" << methodName()
170  << "\" returned void invoked on object of type \""
171  << o.typeOf().qualifiedName() << "\"\n";
172  }
173  return ret;
174 }
175 
178  const std::vector<AnyMethodArgument>& args)
179  : name_(name)
180  , argsBeforeFixups_(args)
181 {
182 }
183 
185 {
186 }
187 
188 const SingleInvoker&
191 {
192  //std::cout << "LazyInvoker for " << name_ << " called on type " <<
193  // type.qualifiedName() << std::endl;
195  if (!invoker) {
196  //std::cout << " Making new invoker for " << name_ << " on type " <<
197  // type.qualifiedName() << std::endl;
198  invoker.reset(new SingleInvoker(type, name_, argsBeforeFixups_));
199  }
200  return *invoker;
201 }
202 
205 invoke(const edm::ObjectWithDict& o, std::vector<edm::ObjectWithDict>& v) const
206 {
207  pair<edm::ObjectWithDict, bool> ret(o, false);
208  do {
209  edm::TypeWithDict type = ret.first.typeOf();
210  if (type.isClass()) {
211  type = ret.first.dynamicType();
212  }
213  ret = invoker(type).invoke(edm::ObjectWithDict(type, ret.first.address()), v);
214  }
215  while (ret.second == false);
216  return ret.first;
217 }
218 
219 double
222  std::vector<edm::ObjectWithDict>& v) const
223 {
224  pair<edm::ObjectWithDict, bool> ret(o, false);
225  const SingleInvoker* i = 0;
226  do {
227  edm::TypeWithDict type = ret.first.typeOf();
228  if (type.isClass()) {
229  type = ret.first.dynamicType();
230  }
231  i = &invoker(type);
232  ret = i->invoke(edm::ObjectWithDict(type, ret.first.address()), v);
233  }
234  while (ret.second == false);
235  return i->retToDouble(ret.first);
236 }
237 
240  const std::vector<AnyMethodArgument>& args)
241 {
242  TypeStack typeStack(1, type);
243  LazyMethodStack dummy;
244  MethodArgumentStack dummy2;
245  MethodSetter setter(invokers_, dummy, typeStack, dummy2, false);
246  isRefGet_ = !setter.push(name, args, "LazyInvoker dynamic resolution", false);
247  //std::cerr << "SingleInvoker on type " << type.qualifiedName() <<
248  // ", name " << name << (isRefGet_ ? " is just a ref.get " : " is real") <<
249  // std::endl;
250  if (invokers_.front().isFunction()) {
251  edm::TypeWithDict retType = invokers_.front().method().finalReturnType();
253  }
254  else {
256  storageNeedsDestructor_ = false;
257  }
258  // typeStack[0] = type of self
259  // typeStack[1] = type of ret
260  retType_ = reco::typeCode(typeStack[1]);
261 }
262 
265 {
267 }
268 
269 pair<edm::ObjectWithDict, bool>
271 invoke(const edm::ObjectWithDict& o, std::vector<edm::ObjectWithDict>& v) const
272 {
273  // std::cerr << "[SingleInvoker::invoke] member " <<
274  // invokers_.front().method().qualifiedName() <<
275  // " of type " <<
276  // o.typeOf().qualifiedName() <<
277  // (!isRefGet_ ? " is one shot" : " needs another round") <<
278  // std::endl;
279  pair<edm::ObjectWithDict, bool>
280  ret(invokers_.front().invoke(o, storage_), !isRefGet_);
282  //std::cerr << "Storage type: " << storage_.typeOf().qualifiedName() <<
283  // ", I have to call the destructor." << std::endl;
284  v.push_back(storage_);
285  }
286  return ret;
287 }
288 
289 double
292 {
295  }
297 }
298 
299 void
302 {
304  << "member \"" << invokers_.back().methodName()
305  << "\" return type is \"" << invokers_.back().returnTypeName()
306  << "\" retured a \"" << o.typeOf().qualifiedName()
307  << "\" which is not convertible to double.";
308 }
309 
type
Definition: HCALResponse.h:21
edm::ObjectWithDict invoke(const edm::ObjectWithDict &obj, edm::ObjectWithDict &retstore) const
int i
Definition: DBlmapReader.cc:9
method::TypeCode retType_
Definition: MethodInvoker.h:60
static bool makeStorage(edm::ObjectWithDict &obj, const edm::TypeWithDict &retType)
bool isRefGet_
true if this invoker just pops out a ref and returns (ref.get(), false)
Definition: MethodInvoker.h:65
void * address() const
SingleInvoker(const edm::TypeWithDict &, const std::string &name, const std::vector< AnyMethodArgument > &args)
std::pair< edm::ObjectWithDict, bool > invoke(const edm::ObjectWithDict &o, std::vector< edm::ObjectWithDict > &v) const
MethodInvoker(const edm::FunctionWithDict &method, const std::vector< AnyMethodArgument > &ints=std::vector< AnyMethodArgument >())
std::string returnTypeName() const
std::vector< edm::TypeWithDict > TypeStack
Definition: TypeStack.h:17
static double objToDouble(const edm::ObjectWithDict &obj, method::TypeCode type)
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
edm::MemberWithDict member_
Definition: MethodInvoker.h:23
boost::shared_ptr< SingleInvoker > SingleInvokerPtr
Definition: MethodInvoker.h:97
TypeWithDict toType() const
TypeWithDict typeOf() const
std::vector< AnyMethodArgument > ints_
Definition: MethodInvoker.h:24
std::vector< AnyMethodArgument > MethodArgumentStack
static bool isValidReturnType(method::TypeCode)
std::string typeName() const
bool isClass() const
edm::FunctionWithDict method_
Definition: MethodInvoker.h:22
std::string name() const
edm::ObjectWithDict storage_
Definition: MethodInvoker.h:62
TypeCode typeCode(const edm::TypeWithDict &t)
Definition: returnType.cc:44
ObjectWithDict get() const
bool push(const std::string &, const std::vector< AnyMethodArgument > &, const char *, bool deep=true) const
Definition: MethodSetter.cc:65
TypeWithDict typeOf() const
std::type_info const & typeInfo() const
edm::TypeWithDict retTypeFinal_
Definition: MethodInvoker.h:28
void invoke(ObjectWithDict const &obj, ObjectWithDict *ret=nullptr, std::vector< void * > const &values=std::vector< void * >()) const
Call a member function.
edm::ObjectWithDict invoke(const edm::ObjectWithDict &o, std::vector< edm::ObjectWithDict > &v) const
TypeWithDict finalReturnType() const
std::vector< LazyInvoker > LazyMethodStack
Definition: MethodStack.h:18
MethodInvoker & operator=(const MethodInvoker &)
void throwFailedConversion(const edm::ObjectWithDict &) const
static void delStorage(edm::ObjectWithDict &)
bool isReference() const
const SingleInvoker & invoker(const edm::TypeWithDict &) const
TypeWithDict & stripConstRef()
std::string methodName() const
std::vector< void * > args_
Definition: MethodInvoker.h:25
std::vector< AnyMethodArgument > argsBeforeFixups_
Definition: MethodInvoker.h:93
double retToDouble(const edm::ObjectWithDict &) const
convert the output of invoke to a double, if possible
volatile std::atomic< bool > shutdown_flag false
std::vector< MethodInvoker > invokers_
Definition: MethodInvoker.h:61
bool isPointer() const
std::map< edm::TypeID, SingleInvokerPtr > invokers_
Definition: MethodInvoker.h:98
LazyInvoker(const std::string &name, const std::vector< AnyMethodArgument > &args)