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 if(it->isFunction()) {
00048 edm::TypeWithDict retType = it->method().finalReturnType();
00049 needsDestructor_.push_back(makeStorage(*itobj, retType));
00050 } else {
00051 *itobj = edm::ObjectWithDict();
00052 needsDestructor_.push_back(false);
00053 }
00054 }
00055 }
00056
00057 bool
00058 ExpressionVar::makeStorage(edm::ObjectWithDict &obj, const edm::TypeWithDict &retType) {
00059 bool ret = false;
00060 static edm::TypeWithDict tVoid(edm::TypeWithDict::byName("void"));
00061 if (retType == tVoid) {
00062 obj = edm::ObjectWithDict::byType(tVoid);
00063 } else if (retType.isPointer() || retType.isReference()) {
00064
00065 obj = edm::ObjectWithDict(retType, new void *);
00066 } else {
00067 obj = edm::ObjectWithDict(retType, retType.allocate());
00068 ret = retType.isClass();
00069
00070 }
00071 return ret;
00072 }
00073
00074 bool ExpressionVar::isValidReturnType(method::TypeCode retType)
00075 {
00076 using namespace method;
00077 bool ret = false;
00078 switch(retType) {
00079 case(doubleType) : ret = true; break;
00080 case(floatType ) : ret = true; break;
00081 case(intType ) : ret = true; break;
00082 case(uIntType ) : ret = true; break;
00083 case(shortType ) : ret = true; break;
00084 case(uShortType) : ret = true; break;
00085 case(longType ) : ret = true; break;
00086 case(uLongType ) : ret = true; break;
00087 case(charType ) : ret = true; break;
00088 case(uCharType ) : ret = true; break;
00089 case(boolType ) : ret = true; break;
00090 case(enumType ) : ret = true; break;
00091 case(invalid):
00092 default:
00093 break;
00094 }
00095 return ret;
00096 }
00097
00098 double ExpressionVar::value(const edm::ObjectWithDict & o) const {
00099 edm::ObjectWithDict ro = o;
00100 std::vector<MethodInvoker>::const_iterator itm, end = methods_.end();
00101 std::vector<edm::ObjectWithDict>::iterator ito;
00102 for(itm = methods_.begin(), ito = objects_.begin(); itm != end; ++itm, ++ito) {
00103 ro = itm->invoke(ro, *ito);
00104 }
00105 double ret = objToDouble(ro, retType_);
00106 std::vector<edm::ObjectWithDict>::reverse_iterator rito, rend = objects_.rend();;
00107 std::vector<bool>::const_reverse_iterator ritb;
00108 for(rito = objects_.rbegin(), ritb = needsDestructor_.rbegin(); rito != rend; ++rito, ++ritb) {
00109 if (*ritb) rito->typeOf().destruct(rito->address(), false);
00110 }
00111 return ret;
00112 }
00113
00114 double
00115 ExpressionVar::objToDouble(const edm::ObjectWithDict &obj, method::TypeCode type) {
00116 using namespace method;
00117 void * addr = obj.address();
00118 double ret = 0;
00119 switch(type) {
00120 case(doubleType) : ret = * static_cast<double *>(addr); break;
00121 case(floatType ) : ret = * static_cast<float *>(addr); break;
00122 case(intType ) : ret = * static_cast<int *>(addr); break;
00123 case(uIntType ) : ret = * static_cast<unsigned int *>(addr); break;
00124 case(shortType ) : ret = * static_cast<short *>(addr); break;
00125 case(uShortType) : ret = * static_cast<unsigned short *>(addr); break;
00126 case(longType ) : ret = * static_cast<long *>(addr); break;
00127 case(uLongType ) : ret = * static_cast<unsigned long *>(addr); break;
00128 case(charType ) : ret = * static_cast<char *>(addr); break;
00129 case(uCharType ) : ret = * static_cast<unsigned char *>(addr); break;
00130 case(boolType ) : ret = * static_cast<bool *>(addr); break;
00131 case(enumType ) : ret = * static_cast<int *>(addr); break;
00132 default:
00133 assert(false);
00134 };
00135 return ret;
00136 }
00137
00138 ExpressionLazyVar::ExpressionLazyVar(const std::vector<LazyInvoker> & methods) :
00139 methods_(methods)
00140 {
00141 }
00142
00143 ExpressionLazyVar::~ExpressionLazyVar()
00144 {
00145 }
00146
00147 double
00148 ExpressionLazyVar::value(const edm::ObjectWithDict & o) const {
00149 std::vector<LazyInvoker>::const_iterator it, ed = methods_.end()-1;
00150 edm::ObjectWithDict ro = o;
00151 for (it = methods_.begin(); it < ed; ++it) {
00152 ro = it->invoke(ro, objects_);
00153 }
00154 double ret = it->invokeLast(ro, objects_);
00155 std::vector<edm::ObjectWithDict>::reverse_iterator rit, red = objects_.rend();
00156 for (rit = objects_.rbegin(); rit != red; ++rit) {
00157 rit->typeOf().destruct(rit->address(), false);
00158 }
00159 objects_.clear();
00160 return ret;
00161 }
00162