CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ExpressionVar.cc
Go to the documentation of this file.
2 #include "Reflex/Object.h"
3 #include <Reflex/Builder/NewDelFunctions.h>
4 #include <map>
5 #include <assert.h>
6 using namespace reco::parser;
7 using namespace Reflex;
8 using namespace std;
9 
10 ExpressionVar::ExpressionVar(const vector<MethodInvoker>& methods, method::TypeCode retType) :
11  methods_(methods), retType_(retType) {
12  initObjects_();
13 }
14 
16  methods_(other.methods_), retType_(other.retType_) {
17  initObjects_();
18 }
19 
21  for(std::vector<Reflex::Object>::iterator it = objects_.begin(); it != objects_.end(); ++it) {
22  delStorage(*it);
23  }
24  objects_.clear();
25 }
26 
27 void
28 ExpressionVar::delStorage(Reflex::Object &obj) {
29  if (obj.Address() != 0) {
30  if (obj.TypeOf().IsPointer() || obj.TypeOf().IsReference()) {
31  // just delete a void *, as that's what it was
32  void **p = static_cast<void **>(obj.Address());
33  delete p;
34  } else {
35  //std::cout << "Calling Destruct on a " << obj.TypeOf().Name(QUALIFIED) << std::endl;
36  obj.TypeOf().Deallocate(obj.Address());
37  }
38  }
39 }
40 
42  objects_.resize(methods_.size());
43  std::vector<MethodInvoker>::const_iterator it = methods_.begin(), ed = methods_.end();
44  std::vector<Reflex::Object>::iterator itobj = objects_.begin();
45  for (; it != ed; ++it, ++itobj) {
46  needsDestructor_.push_back(makeStorage(*itobj, it->method()));
47  }
48 }
49 
50 bool
51 ExpressionVar::makeStorage(Reflex::Object &obj, const Reflex::Member &member) {
52  bool ret = false;
53  static Type tVoid = Type::ByName("void");
54  if (member.IsFunctionMember()) {
55  Reflex::Type retType = member.TypeOf().ReturnType();
56  //remove any typedefs if any. If we do not do this it appears that we get a memory leak
57  // because typedefs do not have 'destructors'
58  retType = retType.FinalType();
59  if (retType == tVoid) {
60  obj = Reflex::Object(tVoid);
61  } else if (retType.IsPointer() || retType.IsReference()) {
62  // in this case, I have to allocate a void *, not an object!
63  obj = Reflex::Object(retType, new void *);
64  } else {
65  obj = Reflex::Object(retType, retType.Allocate());
66  ret = retType.IsClass();
67  //std::cout << "ExpressionVar: reserved memory at " << obj.Address() << " for a " << retType.Name(QUALIFIED) << " returned by " << member.Name() << std::endl;
68  }
69  } else { // no alloc, we don't need it
70  obj = Reflex::Object();
71  }
72  return ret;
73 }
74 
76 {
77  using namespace method;
78  bool ret = false;
79  switch(retType) {
80  case(doubleType) : ret = true; break;
81  case(floatType ) : ret = true; break;
82  case(intType ) : ret = true; break;
83  case(uIntType ) : ret = true; break;
84  case(shortType ) : ret = true; break;
85  case(uShortType) : ret = true; break;
86  case(longType ) : ret = true; break;
87  case(uLongType ) : ret = true; break;
88  case(charType ) : ret = true; break;
89  case(uCharType ) : ret = true; break;
90  case(boolType ) : ret = true; break;
91  case(enumType ) : ret = true; break;
92  case(invalid):
93  default:
94  break;
95  }
96  return ret;
97 }
98 
99 double ExpressionVar::value(const Object & o) const {
100  Object ro = o;
101  std::vector<MethodInvoker>::const_iterator itm, end = methods_.end();
102  std::vector<Reflex::Object>::iterator ito;
103  for(itm = methods_.begin(), ito = objects_.begin(); itm != end; ++itm, ++ito) {
104  ro = itm->invoke(ro, *ito);
105  }
106  double ret = objToDouble(ro, retType_);
107  std::vector<Reflex::Object>::reverse_iterator rito, rend = objects_.rend();;
108  std::vector<bool>::const_reverse_iterator ritb;
109  for(rito = objects_.rbegin(), ritb = needsDestructor_.rbegin(); rito != rend; ++rito, ++ritb) {
110  if (*ritb) rito->TypeOf().Destruct(rito->Address(), false);
111  }
112  return ret;
113 }
114 
115 double
117  using namespace method;
118  void * addr = obj.Address();
119  double ret = 0;
120  switch(type) {
121  case(doubleType) : ret = * static_cast<double *>(addr); break;
122  case(floatType ) : ret = * static_cast<float *>(addr); break;
123  case(intType ) : ret = * static_cast<int *>(addr); break;
124  case(uIntType ) : ret = * static_cast<unsigned int *>(addr); break;
125  case(shortType ) : ret = * static_cast<short *>(addr); break;
126  case(uShortType) : ret = * static_cast<unsigned short *>(addr); break;
127  case(longType ) : ret = * static_cast<long *>(addr); break;
128  case(uLongType ) : ret = * static_cast<unsigned long *>(addr); break;
129  case(charType ) : ret = * static_cast<char *>(addr); break;
130  case(uCharType ) : ret = * static_cast<unsigned char *>(addr); break;
131  case(boolType ) : ret = * static_cast<bool *>(addr); break;
132  case(enumType ) : ret = * static_cast<int *>(addr); break;
133  default:
134  assert(false);
135  };
136  return ret;
137 }
138 
139 void ExpressionVar::trueDelete(Reflex::Object & obj) {
140  static std::map<void *, Reflex::NewDelFunctions *> deleters_;
141  void * reflexTypeId = obj.TypeOf().Id();
142  std::map<void *, Reflex::NewDelFunctions *>::iterator match = deleters_.find(reflexTypeId);
143  if (match == deleters_.end()) {
144  Reflex::NewDelFunctions *ptr;
145  Reflex::Object newDel(Reflex::Type::ByTypeInfo(typeid(ptr)), &ptr);
146  obj.Invoke("__getNewDelFunctions", &newDel);
147  match = deleters_.insert(std::make_pair(reflexTypeId, ptr)).first;
148  }
149  (*match->second->fDelete)(obj.Address());
150 }
151 
152 ExpressionLazyVar::ExpressionLazyVar(const std::vector<LazyInvoker> & methods) :
153  methods_(methods)
154 {
155 }
156 
158 {
159 }
160 
161 double
162 ExpressionLazyVar::value(const Reflex::Object & o) const {
163  std::vector<LazyInvoker>::const_iterator it, ed = methods_.end()-1;
164  Reflex::Object ro = o;
165  for (it = methods_.begin(); it < ed; ++it) {
166  ro = it->invoke(ro, objects_);
167  }
168  double ret = it->invokeLast(ro, objects_);
169  std::vector<Reflex::Object>::reverse_iterator rit, red = objects_.rend();
170  for (rit = objects_.rbegin(); rit != red; ++rit) {
171  rit->TypeOf().Destruct(rit->Address(), false);
172  }
173  objects_.clear();
174  return ret;
175 }
176 
type
Definition: HCALResponse.h:22
ExpressionLazyVar(const std::vector< LazyInvoker > &methods)
virtual double value(const Reflex::Object &o) const
std::vector< Reflex::Object > objects_
Definition: ExpressionVar.h:61
static void delStorage(Reflex::Object &obj)
std::vector< LazyInvoker > methods_
Definition: ExpressionVar.h:60
ExpressionVar(const std::vector< MethodInvoker > &methods, method::TypeCode retType)
std::vector< bool > needsDestructor_
Definition: ExpressionVar.h:45
static bool isValidReturnType(method::TypeCode)
std::vector< Reflex::Object > objects_
Definition: ExpressionVar.h:44
static void trueDelete(Reflex::Object &o)
#define end
Definition: vmac.h:38
virtual double value(const Reflex::Object &o) const
std::vector< MethodInvoker > methods_
Definition: ExpressionVar.h:43
static bool makeStorage(Reflex::Object &obj, const Reflex::Member &member)
static double objToDouble(const Reflex::Object &obj, method::TypeCode type)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:6
Evaluate an object&#39;s method or datamember (or chain of them) to get a number.
Definition: ExpressionVar.h:21
method::TypeCode retType_
Definition: ExpressionVar.h:46