Go to the documentation of this file.00001 #include "CommonTools/Utils/src/ExpressionVar.h"
00002 #include "Reflex/Object.h"
00003 #include <Reflex/Builder/NewDelFunctions.h>
00004 #include <map>
00005 #include <assert.h>
00006 using namespace reco::parser;
00007 using namespace Reflex;
00008 using namespace std;
00009
00010 ExpressionVar::ExpressionVar(const vector<MethodInvoker>& methods, method::TypeCode retType) :
00011 methods_(methods), retType_(retType) {
00012 initObjects_();
00013 }
00014
00015 ExpressionVar::ExpressionVar(const ExpressionVar &other) :
00016 methods_(other.methods_), retType_(other.retType_) {
00017 initObjects_();
00018 }
00019
00020 ExpressionVar::~ExpressionVar() {
00021 for(std::vector<Reflex::Object>::iterator it = objects_.begin(); it != objects_.end(); ++it) {
00022 delStorage(*it);
00023 }
00024 objects_.clear();
00025 }
00026
00027 void
00028 ExpressionVar::delStorage(Reflex::Object &obj) {
00029 if (obj.Address() != 0) {
00030 if (obj.TypeOf().IsPointer() || obj.TypeOf().IsReference()) {
00031
00032 void **p = static_cast<void **>(obj.Address());
00033 delete p;
00034 } else {
00035
00036 obj.TypeOf().Deallocate(obj.Address());
00037 }
00038 }
00039 }
00040
00041 void ExpressionVar::initObjects_() {
00042 objects_.resize(methods_.size());
00043 std::vector<MethodInvoker>::const_iterator it = methods_.begin(), ed = methods_.end();
00044 std::vector<Reflex::Object>::iterator itobj = objects_.begin();
00045 for (; it != ed; ++it, ++itobj) {
00046 needsDestructor_.push_back(makeStorage(*itobj, it->method()));
00047 }
00048 }
00049
00050 bool
00051 ExpressionVar::makeStorage(Reflex::Object &obj, const Reflex::Member &member) {
00052 bool ret = false;
00053 static Type tVoid = Type::ByName("void");
00054 if (member.IsFunctionMember()) {
00055 Reflex::Type retType = member.TypeOf().ReturnType();
00056
00057
00058 retType = retType.FinalType();
00059 if (retType == tVoid) {
00060 obj = Reflex::Object(tVoid);
00061 } else if (retType.IsPointer() || retType.IsReference()) {
00062
00063 obj = Reflex::Object(retType, new void *);
00064 } else {
00065 obj = Reflex::Object(retType, retType.Allocate());
00066 ret = retType.IsClass();
00067
00068 }
00069 } else {
00070 obj = Reflex::Object();
00071 }
00072 return ret;
00073 }
00074
00075 bool ExpressionVar::isValidReturnType(method::TypeCode retType)
00076 {
00077 using namespace method;
00078 bool ret = false;
00079 switch(retType) {
00080 case(doubleType) : ret = true; break;
00081 case(floatType ) : ret = true; break;
00082 case(intType ) : ret = true; break;
00083 case(uIntType ) : ret = true; break;
00084 case(shortType ) : ret = true; break;
00085 case(uShortType) : ret = true; break;
00086 case(longType ) : ret = true; break;
00087 case(uLongType ) : ret = true; break;
00088 case(charType ) : ret = true; break;
00089 case(uCharType ) : ret = true; break;
00090 case(boolType ) : ret = true; break;
00091 case(enumType ) : ret = true; break;
00092 case(invalid):
00093 default:
00094 break;
00095 }
00096 return ret;
00097 }
00098
00099 double ExpressionVar::value(const Object & o) const {
00100 Object ro = o;
00101 std::vector<MethodInvoker>::const_iterator itm, end = methods_.end();
00102 std::vector<Reflex::Object>::iterator ito;
00103 for(itm = methods_.begin(), ito = objects_.begin(); itm != end; ++itm, ++ito) {
00104 ro = itm->invoke(ro, *ito);
00105 }
00106 double ret = objToDouble(ro, retType_);
00107 std::vector<Reflex::Object>::reverse_iterator rito, rend = objects_.rend();;
00108 std::vector<bool>::const_reverse_iterator ritb;
00109 for(rito = objects_.rbegin(), ritb = needsDestructor_.rbegin(); rito != rend; ++rito, ++ritb) {
00110 if (*ritb) rito->TypeOf().Destruct(rito->Address(), false);
00111 }
00112 return ret;
00113 }
00114
00115 double
00116 ExpressionVar::objToDouble(const Reflex::Object &obj, method::TypeCode type) {
00117 using namespace method;
00118 void * addr = obj.Address();
00119 double ret = 0;
00120 switch(type) {
00121 case(doubleType) : ret = * static_cast<double *>(addr); break;
00122 case(floatType ) : ret = * static_cast<float *>(addr); break;
00123 case(intType ) : ret = * static_cast<int *>(addr); break;
00124 case(uIntType ) : ret = * static_cast<unsigned int *>(addr); break;
00125 case(shortType ) : ret = * static_cast<short *>(addr); break;
00126 case(uShortType) : ret = * static_cast<unsigned short *>(addr); break;
00127 case(longType ) : ret = * static_cast<long *>(addr); break;
00128 case(uLongType ) : ret = * static_cast<unsigned long *>(addr); break;
00129 case(charType ) : ret = * static_cast<char *>(addr); break;
00130 case(uCharType ) : ret = * static_cast<unsigned char *>(addr); break;
00131 case(boolType ) : ret = * static_cast<bool *>(addr); break;
00132 case(enumType ) : ret = * static_cast<int *>(addr); break;
00133 default:
00134 assert(false);
00135 };
00136 return ret;
00137 }
00138
00139 void ExpressionVar::trueDelete(Reflex::Object & obj) {
00140 static std::map<void *, Reflex::NewDelFunctions *> deleters_;
00141 void * reflexTypeId = obj.TypeOf().Id();
00142 std::map<void *, Reflex::NewDelFunctions *>::iterator match = deleters_.find(reflexTypeId);
00143 if (match == deleters_.end()) {
00144 Reflex::NewDelFunctions *ptr;
00145 Reflex::Object newDel(Reflex::Type::ByTypeInfo(typeid(ptr)), &ptr);
00146 obj.Invoke("__getNewDelFunctions", &newDel);
00147 match = deleters_.insert(std::make_pair(reflexTypeId, ptr)).first;
00148 }
00149 (*match->second->fDelete)(obj.Address());
00150 }
00151
00152 ExpressionLazyVar::ExpressionLazyVar(const std::vector<LazyInvoker> & methods) :
00153 methods_(methods)
00154 {
00155 }
00156
00157 ExpressionLazyVar::~ExpressionLazyVar()
00158 {
00159 }
00160
00161 double
00162 ExpressionLazyVar::value(const Reflex::Object & o) const {
00163 std::vector<LazyInvoker>::const_iterator it, ed = methods_.end()-1;
00164 Reflex::Object ro = o;
00165 for (it = methods_.begin(); it < ed; ++it) {
00166 ro = it->invoke(ro, objects_);
00167 }
00168 double ret = it->invokeLast(ro, objects_);
00169 std::vector<Reflex::Object>::reverse_iterator rit, red = objects_.rend();
00170 for (rit = objects_.rbegin(); rit != red; ++rit) {
00171 rit->TypeOf().Destruct(rit->Address(), false);
00172 }
00173 objects_.clear();
00174 return ret;
00175 }
00176