CMS 3D CMS Logo

MethodInvoker.cc
Go to the documentation of this file.
2 
8 
9 #include <algorithm>
10 //#include <iostream>
11 using namespace reco::parser;
12 using namespace std;
13 
14 MethodInvoker::MethodInvoker(const edm::FunctionWithDict& method, const vector<AnyMethodArgument>& ints)
15  : method_(method), member_(), ints_(ints), isFunction_(true) {
16  setArgs();
17  if (isFunction_) {
19  }
20  //std::cout <<
21  // "Booking " <<
22  // methodName() <<
23  // " from " <<
24  // method_.declaringType().name() <<
25  // " with " <<
26  // args_.size() <<
27  // " arguments" <<
28  // " (were " <<
29  // ints.size() <<
30  // ")" <<
31  // std::endl;
32 }
33 
35  : method_(), member_(member), ints_(), isFunction_(false) {
36  setArgs();
37  //std::cout <<
38  // "Booking " <<
39  // methodName() <<
40  // " from " <<
41  // member_.declaringType().name() <<
42  // " with " <<
43  // args_.size() <<
44  // " arguments" <<
45  // " (were " <<
46  // ints.size() <<
47  // ")" <<
48  // std::endl;
49 }
50 
52  : method_(rhs.method_),
53  member_(rhs.member_),
54  ints_(rhs.ints_),
55  isFunction_(rhs.isFunction_),
56  retTypeFinal_(rhs.retTypeFinal_) {
57  setArgs();
58 }
59 
61  if (this != &rhs) {
62  method_ = rhs.method_;
63  member_ = rhs.member_;
64  ints_ = rhs.ints_;
67 
68  setArgs();
69  }
70  return *this;
71 }
72 
74  for (size_t i = 0; i < ints_.size(); ++i) {
75  args_.push_back(std::visit(AnyMethodArgument2VoidPtr(), ints_[i]));
76  }
77 }
78 
80  if (isFunction_) {
81  return method_.name();
82  }
83  return member_.name();
84 }
85 
87  if (isFunction_) {
88  return method_.typeName();
89  }
90  return member_.typeOf().qualifiedName();
91 }
92 
94  edm::ObjectWithDict ret = retstore;
95  edm::TypeWithDict retType;
96  if (isFunction_) {
97  //std::cout << "Invoking " << methodName()
98  // << " from " << method_.declaringType().qualifiedName()
99  // << " on an instance of " << o.dynamicType().qualifiedName()
100  // << " at " << o.address()
101  // << " with " << args_.size() << " arguments"
102  // << std::endl;
103  method_.invoke(o, &ret, args_);
104  // this is correct, it takes pointers and refs into account
105  retType = retTypeFinal_;
106  } else {
107  //std::cout << "Invoking " << methodName()
108  // << " from " << member_.declaringType().qualifiedName()
109  // << " on an instance of " << o.dynamicType().qualifiedName()
110  // << " at " << o.address()
111  // << " with " << args_.size() << " arguments"
112  // << std::endl;
113  ret = member_.get(o);
114  retType = member_.typeOf();
115  }
116  void* addr = ret.address();
117  //std::cout << "Stored result of " << methodName() << " (type " <<
118  // returnTypeName() << ") at " << addr << std::endl;
119  if (addr == nullptr) {
121  << "method \"" << methodName() << "\" called with " << args_.size() << " arguments returned a null pointer ";
122  }
123  //std::cout << "Return type is " << retType.qualifiedName() << std::endl;
124  if (retType.isPointer() || retType.isReference()) {
125  // both need void** -> void* conversion
126  if (retType.isPointer()) {
127  retType = retType.toType();
128  } else {
129  // strip cv & ref flags
130  // FIXME: This is only true if the propery passed to the constructor
131  // overrides the const and reference flags.
132  retType = retType.stripConstRef();
133  }
134  ret = edm::ObjectWithDict(retType, *static_cast<void**>(addr));
135  //std::cout << "Now type is " << retType.qualifiedName() << std::endl;
136  }
137  if (!bool(ret)) {
139  << "method \"" << methodName() << "\" returned void invoked on object of type \"" << o.typeOf().qualifiedName()
140  << "\"\n";
141  }
142  return ret;
143 }
144 
145 LazyInvoker::LazyInvoker(const std::string& name, const std::vector<AnyMethodArgument>& args)
146  : name_(name), argsBeforeFixups_(args) {}
147 
149 
151  //std::cout << "LazyInvoker for " << name_ << " called on type " <<
152  // type.qualifiedName() << std::endl;
153  const edm::TypeID thetype(type.typeInfo());
154  auto found = invokers_.find(thetype);
155  if (found != invokers_.cend()) {
156  return *(found->second);
157  }
158  auto to_add = std::make_shared<SingleInvoker>(type, name_, argsBeforeFixups_);
159  auto emplace_result = invokers_.insert(std::make_pair(thetype, to_add));
160  return *(emplace_result.first->second);
161 }
162 
163 edm::ObjectWithDict LazyInvoker::invoke(const edm::ObjectWithDict& o, std::vector<StorageManager>& v) const {
164  pair<edm::ObjectWithDict, bool> ret(o, false);
165  do {
166  edm::TypeWithDict type = ret.first.typeOf();
167  if (type.isClass()) {
168  type = ret.first.dynamicType();
169  }
170  ret = invoker(type).invoke(edm::ObjectWithDict(type, ret.first.address()), v);
171  } while (ret.second == false);
172  return ret.first;
173 }
174 
175 double LazyInvoker::invokeLast(const edm::ObjectWithDict& o, std::vector<StorageManager>& v) const {
176  pair<edm::ObjectWithDict, bool> ret(o, false);
177  const SingleInvoker* i = nullptr;
178  do {
179  edm::TypeWithDict type = ret.first.typeOf();
180  if (type.isClass()) {
181  type = ret.first.dynamicType();
182  }
183  i = &invoker(type);
184  ret = i->invoke(edm::ObjectWithDict(type, ret.first.address()), v);
185  } while (ret.second == false);
186  return i->retToDouble(ret.first);
187 }
188 
190  const std::string& name,
191  const std::vector<AnyMethodArgument>& args) {
192  TypeStack typeStack(1, type);
194  MethodArgumentStack dummy2;
195  MethodSetter setter(invokers_, dummy, typeStack, dummy2, false);
196  isRefGet_ = !setter.push(name, args, "LazyInvoker dynamic resolution", false);
197  //std::cerr << "SingleInvoker on type " << type.qualifiedName() <<
198  // ", name " << name << (isRefGet_ ? " is just a ref.get " : " is real") <<
199  // std::endl;
201  // typeStack[0] = type of self
202  // typeStack[1] = type of ret
203  retType_ = reco::typeCode(typeStack[1]);
204 }
205 
207  edm::ObjectWithDict stored;
208  while (storage_.try_pop(stored)) {
209  //std::cout <<"deleting "<<stored.address()<<" from "<<this<<std::endl;
211  }
212 }
213 
214 edm::ObjectWithDict SingleInvoker::createStorage(bool& needsDestructor) const {
215  if (invokers_.front().isFunction()) {
216  edm::TypeWithDict retType = invokers_.front().method().finalReturnType();
217  edm::ObjectWithDict stored;
218  needsDestructor = ExpressionVar::makeStorage(stored, retType);
219  return stored;
220  }
221  needsDestructor = false;
222  return edm::ObjectWithDict();
223 }
224 
227  if (storage_.try_pop(o)) {
228  //std::cout <<"borrowed "<<o.address()<<" from "<<this<<std::endl;
229  return o;
230  }
231  bool dummy;
232  o = createStorage(dummy);
233  //std::cout <<"borrowed new "<<o.address()<<std::endl;
234  return o;
235 }
236 
238  //std::cout <<"returned "<<o.address()<<" to "<<this<<std::endl;
239  storage_.push(std::move(o));
240 }
241 
242 pair<edm::ObjectWithDict, bool> SingleInvoker::invoke(const edm::ObjectWithDict& o,
243  std::vector<StorageManager>& v) const {
244  // std::cerr << "[SingleInvoker::invoke] member " <<
245  // invokers_.front().method().qualifiedName() <<
246  // " of type " <<
247  // o.typeOf().qualifiedName() <<
248  // (!isRefGet_ ? " is one shot" : " needs another round") <<
249  // std::endl;
250  auto storage = borrowStorage();
251  pair<edm::ObjectWithDict, bool> ret(invokers_.front().invoke(o, storage), !isRefGet_);
252  v.emplace_back(storage, this, storageNeedsDestructor_);
253  return ret;
254 }
255 
259  }
261 }
262 
265  << "member \"" << invokers_.back().methodName() << "\" return type is \"" << invokers_.back().returnTypeName()
266  << "\" retured a \"" << o.typeOf().qualifiedName() << "\" which is not convertible to double.";
267 }
268 
270  if (needsDestructor_) {
271  object_.destruct(false);
272  }
273  if (invoker_) {
275  }
276 }
const SingleInvoker & invoker(const edm::TypeWithDict &) const
SingleInvoker(const SingleInvoker &)=delete
method::TypeCode retType_
Definition: MethodInvoker.h:90
static bool makeStorage(edm::ObjectWithDict &obj, const edm::TypeWithDict &retType)
TypeWithDict typeOf() const
edm::ObjectWithDict invoke(const edm::ObjectWithDict &obj, edm::ObjectWithDict &retstore) const
TypeWithDict finalReturnType() const
void destruct(bool dealloc) const
bool isRefGet_
true if this invoker just pops out a ref and returns (ref.get(), false)
Definition: MethodInvoker.h:95
ret
prodAgent to be discontinued
double retToDouble(const edm::ObjectWithDict &) const
convert the output of invoke to a double, if possible
std::string methodName() const
MethodInvoker(const edm::FunctionWithDict &method, const std::vector< AnyMethodArgument > &ints=std::vector< AnyMethodArgument >())
std::string qualifiedName() const
std::vector< edm::TypeWithDict > TypeStack
Definition: TypeStack.h:17
static double objToDouble(const edm::ObjectWithDict &obj, method::TypeCode type)
edm::MemberWithDict member_
Definition: MethodInvoker.h:29
std::string name() const
edm::ObjectWithDict createStorage(bool &needsDestructor) const
void returnStorage(edm::ObjectWithDict &&) const
edm::ObjectWithDict object_
Definition: MethodInvoker.h:65
std::vector< AnyMethodArgument > ints_
Definition: MethodInvoker.h:30
ObjectWithDict get() const
std::vector< AnyMethodArgument > MethodArgumentStack
static bool isValidReturnType(method::TypeCode)
method::TypeCode typeCode(const edm::TypeWithDict &)
Definition: returnType.cc:39
edm::FunctionWithDict method_
Definition: MethodInvoker.h:28
oneapi::tbb::concurrent_queue< edm::ObjectWithDict > storage_
Definition: MethodInvoker.h:92
edm::TypeWithDict retTypeFinal_
Definition: MethodInvoker.h:34
edm::ObjectWithDict invoke(const edm::ObjectWithDict &o, std::vector< StorageManager > &v) const
std::vector< LazyInvoker > LazyMethodStack
Definition: MethodStack.h:18
MethodInvoker & operator=(const MethodInvoker &)
std::string typeName() const
void invoke(ObjectWithDict const &obj, ObjectWithDict *ret=nullptr, std::vector< void *> const &values=std::vector< void *>()) const
Call a member function.
static void delStorage(edm::ObjectWithDict &)
std::string name() const
std::pair< edm::ObjectWithDict, bool > invoke(const edm::ObjectWithDict &o, std::vector< StorageManager > &v) const
SingleInvoker const * invoker_
Definition: MethodInvoker.h:66
TypeWithDict & stripConstRef()
double invokeLast(const edm::ObjectWithDict &o, std::vector< StorageManager > &v) const
invoke and coerce result to double
edm::ObjectWithDict borrowStorage() const
std::vector< void * > args_
Definition: MethodInvoker.h:31
std::string returnTypeName() const
std::vector< AnyMethodArgument > argsBeforeFixups_
TypeWithDict toType() const
std::vector< MethodInvoker > invokers_
Definition: MethodInvoker.h:91
bool isPointer() const
bool push(const std::string &, const std::vector< AnyMethodArgument > &, const char *, bool deep=true) const
Definition: MethodSetter.cc:57
bool isReference() const
void throwFailedConversion(const edm::ObjectWithDict &) const
def move(src, dest)
Definition: eostools.py:511
ROOT::VecOps::RVec< int > ints
Definition: Resolutions.cc:4
LazyInvoker(const std::string &name, const std::vector< AnyMethodArgument > &args)