CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 
13 MethodInvoker::MethodInvoker(const edm::FunctionWithDict& method, const vector<AnyMethodArgument>& ints)
14  : method_(method), member_(), ints_(ints), isFunction_(true) {
15  setArgs();
16  if (isFunction_) {
18  }
19  //std::cout <<
20  // "Booking " <<
21  // methodName() <<
22  // " from " <<
23  // method_.declaringType().name() <<
24  // " with " <<
25  // args_.size() <<
26  // " arguments" <<
27  // " (were " <<
28  // ints.size() <<
29  // ")" <<
30  // std::endl;
31 }
32 
34  : method_(), member_(member), ints_(), isFunction_(false) {
35  setArgs();
36  //std::cout <<
37  // "Booking " <<
38  // methodName() <<
39  // " from " <<
40  // member_.declaringType().name() <<
41  // " with " <<
42  // args_.size() <<
43  // " arguments" <<
44  // " (were " <<
45  // ints.size() <<
46  // ")" <<
47  // std::endl;
48 }
49 
51  : method_(rhs.method_),
52  member_(rhs.member_),
53  ints_(rhs.ints_),
54  isFunction_(rhs.isFunction_),
55  retTypeFinal_(rhs.retTypeFinal_) {
56  setArgs();
57 }
58 
60  if (this != &rhs) {
61  method_ = rhs.method_;
62  member_ = rhs.member_;
63  ints_ = rhs.ints_;
66 
67  setArgs();
68  }
69  return *this;
70 }
71 
73  for (size_t i = 0; i < ints_.size(); ++i) {
74  args_.push_back(std::visit(AnyMethodArgument2VoidPtr(), ints_[i]));
75  }
76 }
77 
79  if (isFunction_) {
80  return method_.name();
81  }
82  return member_.name();
83 }
84 
86  if (isFunction_) {
87  return method_.typeName();
88  }
89  return member_.typeOf().qualifiedName();
90 }
91 
93  edm::ObjectWithDict ret = retstore;
94  edm::TypeWithDict retType;
95  if (isFunction_) {
96  //std::cout << "Invoking " << methodName()
97  // << " from " << method_.declaringType().qualifiedName()
98  // << " on an instance of " << o.dynamicType().qualifiedName()
99  // << " at " << o.address()
100  // << " with " << args_.size() << " arguments"
101  // << std::endl;
102  method_.invoke(o, &ret, args_);
103  // this is correct, it takes pointers and refs into account
104  retType = retTypeFinal_;
105  } else {
106  //std::cout << "Invoking " << methodName()
107  // << " from " << member_.declaringType().qualifiedName()
108  // << " on an instance of " << o.dynamicType().qualifiedName()
109  // << " at " << o.address()
110  // << " with " << args_.size() << " arguments"
111  // << std::endl;
112  ret = member_.get(o);
113  retType = member_.typeOf();
114  }
115  void* addr = ret.address();
116  //std::cout << "Stored result of " << methodName() << " (type " <<
117  // returnTypeName() << ") at " << addr << std::endl;
118  if (addr == nullptr) {
120  << "method \"" << methodName() << "\" called with " << args_.size() << " arguments returned a null pointer ";
121  }
122  //std::cout << "Return type is " << retType.qualifiedName() << std::endl;
123  if (retType.isPointer() || retType.isReference()) {
124  // both need void** -> void* conversion
125  if (retType.isPointer()) {
126  retType = retType.toType();
127  } else {
128  // strip cv & ref flags
129  // FIXME: This is only true if the propery passed to the constructor
130  // overrides the const and reference flags.
131  retType = retType.stripConstRef();
132  }
133  ret = edm::ObjectWithDict(retType, *static_cast<void**>(addr));
134  //std::cout << "Now type is " << retType.qualifiedName() << std::endl;
135  }
136  if (!bool(ret)) {
138  << "method \"" << methodName() << "\" returned void invoked on object of type \"" << o.typeOf().qualifiedName()
139  << "\"\n";
140  }
141  return ret;
142 }
143 
144 LazyInvoker::LazyInvoker(const std::string& name, const std::vector<AnyMethodArgument>& args)
145  : name_(name), argsBeforeFixups_(args) {}
146 
148 
150  //std::cout << "LazyInvoker for " << name_ << " called on type " <<
151  // type.qualifiedName() << std::endl;
152  const edm::TypeID thetype(type.typeInfo());
153  auto found = invokers_.find(thetype);
154  if (found != invokers_.cend()) {
155  return *(found->second);
156  }
157  auto to_add = std::make_shared<SingleInvoker>(type, name_, argsBeforeFixups_);
158  auto emplace_result = invokers_.insert(std::make_pair(thetype, to_add));
159  return *(emplace_result.first->second);
160 }
161 
162 edm::ObjectWithDict LazyInvoker::invoke(const edm::ObjectWithDict& o, std::vector<edm::ObjectWithDict>& v) const {
163  pair<edm::ObjectWithDict, bool> ret(o, false);
164  do {
165  edm::TypeWithDict type = ret.first.typeOf();
166  if (type.isClass()) {
167  type = ret.first.dynamicType();
168  }
169  ret = invoker(type).invoke(edm::ObjectWithDict(type, ret.first.address()), v);
170  } while (ret.second == false);
171  return ret.first;
172 }
173 
174 double LazyInvoker::invokeLast(const edm::ObjectWithDict& o, std::vector<edm::ObjectWithDict>& v) const {
175  pair<edm::ObjectWithDict, bool> ret(o, false);
176  const SingleInvoker* i = nullptr;
177  do {
178  edm::TypeWithDict type = ret.first.typeOf();
179  if (type.isClass()) {
180  type = ret.first.dynamicType();
181  }
182  i = &invoker(type);
183  ret = i->invoke(edm::ObjectWithDict(type, ret.first.address()), v);
184  } while (ret.second == false);
185  return i->retToDouble(ret.first);
186 }
187 
189  const std::string& name,
190  const std::vector<AnyMethodArgument>& args) {
191  TypeStack typeStack(1, type);
192  LazyMethodStack dummy;
193  MethodArgumentStack dummy2;
194  MethodSetter setter(invokers_, dummy, typeStack, dummy2, false);
195  isRefGet_ = !setter.push(name, args, "LazyInvoker dynamic resolution", false);
196  //std::cerr << "SingleInvoker on type " << type.qualifiedName() <<
197  // ", name " << name << (isRefGet_ ? " is just a ref.get " : " is real") <<
198  // std::endl;
199  if (invokers_.front().isFunction()) {
200  edm::TypeWithDict retType = invokers_.front().method().finalReturnType();
202  } else {
204  storageNeedsDestructor_ = false;
205  }
206  // typeStack[0] = type of self
207  // typeStack[1] = type of ret
208  retType_ = reco::typeCode(typeStack[1]);
209 }
210 
212 
213 pair<edm::ObjectWithDict, bool> SingleInvoker::invoke(const edm::ObjectWithDict& o,
214  std::vector<edm::ObjectWithDict>& v) const {
215  // std::cerr << "[SingleInvoker::invoke] member " <<
216  // invokers_.front().method().qualifiedName() <<
217  // " of type " <<
218  // o.typeOf().qualifiedName() <<
219  // (!isRefGet_ ? " is one shot" : " needs another round") <<
220  // std::endl;
221  pair<edm::ObjectWithDict, bool> ret(invokers_.front().invoke(o, storage_), !isRefGet_);
223  //std::cerr << "Storage type: " << storage_.typeOf().qualifiedName() <<
224  // ", I have to call the destructor." << std::endl;
225  v.push_back(storage_);
226  }
227  return ret;
228 }
229 
233  }
235 }
236 
239  << "member \"" << invokers_.back().methodName() << "\" return type is \"" << invokers_.back().returnTypeName()
240  << "\" retured a \"" << o.typeOf().qualifiedName() << "\" which is not convertible to double.";
241 }
edm::ObjectWithDict invoke(const edm::ObjectWithDict &obj, edm::ObjectWithDict &retstore) const
SingleInvoker(const SingleInvoker &)=delete
tuple ret
prodAgent to be discontinued
method::TypeCode retType_
Definition: MethodInvoker.h:65
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:70
void * address() const
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:28
TypeWithDict toType() const
TypeWithDict typeOf() const
std::vector< AnyMethodArgument > ints_
Definition: MethodInvoker.h:29
std::vector< AnyMethodArgument > MethodArgumentStack
static bool isValidReturnType(method::TypeCode)
std::string typeName() const
method::TypeCode typeCode(const edm::TypeWithDict &)
Definition: returnType.cc:39
bool isClass() const
edm::FunctionWithDict method_
Definition: MethodInvoker.h:27
std::string name() const
edm::ObjectWithDict storage_
Definition: MethodInvoker.h:67
ObjectWithDict get() const
bool push(const std::string &, const std::vector< AnyMethodArgument > &, const char *, bool deep=true) const
Definition: MethodSetter.cc:57
TypeWithDict typeOf() const
std::type_info const & typeInfo() const
edm::TypeWithDict retTypeFinal_
Definition: MethodInvoker.h:33
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:30
std::vector< AnyMethodArgument > argsBeforeFixups_
double retToDouble(const edm::ObjectWithDict &) const
convert the output of invoke to a double, if possible
std::vector< MethodInvoker > invokers_
Definition: MethodInvoker.h:66
bool isPointer() const
LazyInvoker(const std::string &name, const std::vector< AnyMethodArgument > &args)