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 Reflex;
11 using namespace std;
12 
13 MethodInvoker::MethodInvoker(const Member & method, const vector<AnyMethodArgument> & ints) :
14  method_(method), ints_(ints), isFunction_(method.IsFunctionMember())
15 {
16  setArgs();
17  /*std::cout << "Booking " << method_.Name()
18  << " from " << method_.DeclaringType().Name()
19  << " with " << args_.size() << " arguments"
20  << " (were " << ints.size() << ")"
21  << std::endl;*/
22 }
23 
24 MethodInvoker::MethodInvoker(const MethodInvoker & other) :
25  method_(other.method_), ints_(other.ints_), isFunction_(other.isFunction_) {
26  setArgs();
27 }
28 
30  method_ = other.method_;
31  ints_ = other.ints_;
32  isFunction_ = other.isFunction_;
33  setArgs();
34  return *this;
35 }
36 
38  for(size_t i = 0; i < ints_.size(); ++i) {
39  args_.push_back( boost::apply_visitor( AnyMethodArgument2VoidPtr(), ints_[i] ) );
40  }
41 }
42 
43 Reflex::Object
44 MethodInvoker::invoke(const Object & o, Reflex::Object &retstore) const {
45  Reflex::Object ret = retstore;
46  /*std::cout << "Invoking " << method_.Name()
47  << " from " << method_.DeclaringType().Name(QUALIFIED)
48  << " on an instance of " << o.DynamicType().Name(QUALIFIED)
49  << " at " << o.Address()
50  << " with " << args_.size() << " arguments"
51  << std::endl; */
52  Type retType;
53  if(isFunction_) {
54  method_.Invoke(o, &ret, args_);
55  retType = method_.TypeOf().ReturnType(); // this is correct, it takes pointers and refs into account
56  } else {
57  ret = method_.Get(o);
58  retType = method_.TypeOf();
59  }
60  void * addr = ret.Address();
61  //std::cout << "Stored result of " << method_.Name() << " (type " << method_.TypeOf().ReturnType().Name(QUALIFIED) << ") at " << addr << std::endl;
62  if(addr==0)
64  << "method \"" << method_.Name() << "\" called with " << args_.size()
65  << " arguments returned a null pointer ";
66  //std::cout << "Return type is " << retType.Name(QUALIFIED) << std::endl;
67 
68  if(retType.IsPointer() || retType.IsReference()) { // both need (void **)->(void *) conversion
69  if (retType.IsPointer()) {
70  retType = retType.ToType(); // for Pointers, I get the real type this way
71  } else {
72  retType = Type(retType, 0); // strip cv & ref flags
73  }
74  while (retType.IsTypedef()) retType = retType.ToType();
75  ret = Object(retType, *static_cast<void **>(addr));
76  //std::cout << "Now type is " << retType.Name(QUALIFIED) << std::endl;
77  }
78  if(!ret)
80  << "method \"" << method_.Name()
81  << "\" returned void invoked on object of type \""
82  << o.TypeOf().Name(QUALIFIED) << "\"\n";
83  return ret;
84 }
85 
86 LazyInvoker::LazyInvoker(const std::string &name, const std::vector<AnyMethodArgument> & args) :
87  name_(name),
88  argsBeforeFixups_(args)
89 {
90 }
91 
93 {
94 }
95 
96 const SingleInvoker &
98 {
99  //std::cout << "LazyInvoker for " << name_ << " called on type " << type.Name(QUALIFIED|SCOPED) << std::endl;
100  SingleInvokerPtr & invoker = invokers_[type.Id()];
101  if (!invoker) {
102  //std::cout << " Making new invoker for " << name_ << " on type " << type.Name(QUALIFIED|SCOPED) << std::endl;
103  invoker.reset(new SingleInvoker(type, name_, argsBeforeFixups_));
104  }
105  return * invoker;
106 }
107 
108 Object
109 LazyInvoker::invoke(const Reflex::Object & o, std::vector<Reflex::Object> &v) const
110 {
111  pair<Object, bool> ret(o,false);
112  do {
113  Type type = ret.first.TypeOf();
114  if (type.IsClass()) type = ret.first.DynamicType();
115  ret = invoker(type).invoke(Object(type, ret.first.Address()), v);
116  } while (ret.second == false);
117  return ret.first;
118 }
119 
120 double
121 LazyInvoker::invokeLast(const Reflex::Object & o, std::vector<Reflex::Object> &v) const
122 {
123  pair<Object, bool> ret(o,false);
124  const SingleInvoker *i = 0;
125  do {
126  Type type = ret.first.TypeOf();
127  if (type.IsClass()) type = ret.first.DynamicType();
128  i = & invoker(type);
129  ret = i->invoke(Object(type, ret.first.Address()), v);
130  } while (ret.second == false);
131  return i->retToDouble(ret.first);
132 }
133 
135  const std::string &name,
136  const std::vector<AnyMethodArgument> &args)
137 {
138  TypeStack typeStack(1, type);
139  LazyMethodStack dummy;
140  MethodArgumentStack dummy2;
141  MethodSetter setter(invokers_, dummy, typeStack, dummy2, false);
142  isRefGet_ = !setter.push(name, args, "LazyInvoker dynamic resolution", false);
143  //std::cerr << "SingleInvoker on type " << type.Name(QUALIFIED|SCOPED) << ", name " << name << (isRefGet_ ? " is just a ref.get " : " is real") << std::endl;
145  retType_ = reco::typeCode(typeStack[1]); // typeStack[0] = type of self, typeStack[1] = type of ret
146 }
147 
149 {
151 }
152 
153 pair<Object,bool>
154 SingleInvoker::invoke(const Reflex::Object & o, std::vector<Reflex::Object> &v) const
155 {
156  /* std::cerr << "[SingleInvoker::invoke] member " << invokers_.front().method().Name(QUALIFIED|SCOPED) <<
157  " of type " << o.TypeOf().Name(QUALIFIED|SCOPED) <<
158  (!isRefGet_ ? " is one shot" : " needs another round") << std::endl; */
159  pair<Object,bool> ret(invokers_.front().invoke(o, storage_), !isRefGet_);
161  //std::cout << "Storage type: " << storage_.TypeOf().Name(QUALIFIED|SCOPED) << ", I have to call the destructor." << std::endl;
162  v.push_back(storage_);
163  }
164  return ret;
165 }
166 
167 double
168 SingleInvoker::retToDouble(const Reflex::Object & o) const {
171  }
173 }
174 
175 void
176 SingleInvoker::throwFailedConversion(const Reflex::Object & o) const {
178  << "member \"" << invokers_.back().method().Name(QUALIFIED)
179  << "\" return type is \"" << invokers_.back().method().TypeOf().Name(QUALIFIED)
180  << "\" retured a \"" << o.TypeOf().Name(QUALIFIED)
181  << "\" which is not convertible to double.";
182 }
type
Definition: HCALResponse.h:22
int i
Definition: DBlmapReader.cc:9
std::map< void *, SingleInvokerPtr > invokers_
Definition: MethodInvoker.h:80
method::TypeCode retType_
Definition: MethodInvoker.h:55
std::vector< void * > args_
Definition: MethodInvoker.h:30
MethodInvoker & operator=(const MethodInvoker &)
bool isRefGet_
true if this invoker just pops out a ref and returns (ref.get(), false)
Definition: MethodInvoker.h:60
MethodInvoker(const Reflex::Member &method, const std::vector< AnyMethodArgument > &ints=std::vector< AnyMethodArgument >())
bool push(const std::string &, const std::vector< AnyMethodArgument > &, const char *, bool deep=true) const
Definition: MethodSetter.cc:44
double retToDouble(const Reflex::Object &o) const
Reflex::Object invoke(const Reflex::Object &o, Reflex::Object &retstore) const
boost::shared_ptr< SingleInvoker > SingleInvokerPtr
Definition: MethodInvoker.h:79
static void delStorage(Reflex::Object &obj)
static bool isValidReturnType(method::TypeCode)
std::vector< AnyMethodArgument > MethodArgumentStack
TypeCode typeCode(const Type &t)
Definition: returnType.cc:21
std::vector< LazyInvoker > LazyMethodStack
Definition: MethodStack.h:18
double invokeLast(const Reflex::Object &o, std::vector< Reflex::Object > &v) const
invoke and coerce result to double
Reflex::Object invoke(const Reflex::Object &o, std::vector< Reflex::Object > &v) const
std::pair< Reflex::Object, bool > invoke(const Reflex::Object &o, std::vector< Reflex::Object > &v) const
SingleInvoker(const Reflex::Type &t, const std::string &name, const std::vector< AnyMethodArgument > &args)
const SingleInvoker & invoker(const Reflex::Type &t) const
std::vector< AnyMethodArgument > ints_
Definition: MethodInvoker.h:29
dictionary args
void throwFailedConversion(const Reflex::Object &o) const
static bool makeStorage(Reflex::Object &obj, const Reflex::Member &member)
std::vector< AnyMethodArgument > argsBeforeFixups_
Definition: MethodInvoker.h:78
static double objToDouble(const Reflex::Object &obj, method::TypeCode type)
std::vector< MethodInvoker > invokers_
Definition: MethodInvoker.h:56
mathSSE::Vec4< T > v
LazyInvoker(const std::string &name, const std::vector< AnyMethodArgument > &args)
std::vector< Reflex::Type > TypeStack
Definition: TypeStack.h:17