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