CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Fireworks/Core/src/FWItemValueGetter.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWItemValueGetter
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Sun Nov 30 16:15:43 EST 2008
00011 // $Id: FWItemValueGetter.cc,v 1.6 2010/09/06 12:35:59 elmer Exp $
00012 //
00013 
00014 // system include files
00015 #include <sstream>
00016 #include "Reflex/Object.h"
00017 #include "Reflex/Base.h"
00018 #include <cstdio>
00019 
00020 // user include files
00021 #include "Fireworks/Core/interface/FWItemValueGetter.h"
00022 
00023 //
00024 // constants, enums and typedefs
00025 //
00026 
00027 //
00028 // static data member definitions
00029 //
00030 static
00031 ROOT::Reflex::Member
00032 recursiveFindMember(const std::string& iName,
00033                     const ROOT::Reflex::Type& iType)
00034 {
00035    using namespace ROOT::Reflex;
00036 
00037    Member temp = iType.MemberByName(iName);
00038    if(temp) {return temp;}
00039 
00040    //try all base classes
00041    for(Base_Iterator it = iType.Base_Begin(), itEnd = iType.Base_End();
00042        it != itEnd;
00043        ++it) {
00044       temp = recursiveFindMember(iName,it->ToType());
00045       if(temp) {break;}
00046    }
00047    return temp;
00048 }
00049 
00050 namespace {
00051    template <class T>
00052    const std::string& valueToString(const std::string& iName,
00053                                     const std::string& iUnit,
00054                                     const Reflex::Object& iObject,
00055                                     const Reflex::Member& iMember)
00056    {
00057       static std::string bala(128, 0);
00058       T temp;
00059       iMember.Invoke(iObject,temp);
00060       snprintf(&bala[0], 127, "%s: %.1f %s", iName.c_str(), temp, iUnit.c_str());
00061       return bala;
00062    }
00063 
00064    typedef const std::string& (*FunctionType)(const std::string&, const std::string&,const Reflex::Object&, const Reflex::Member&);
00065    typedef std::map<std::string, FunctionType> TypeToStringMap;
00066 
00067    template<typename T>
00068    static void addToStringMap(TypeToStringMap& iMap) {
00069       iMap[typeid(T).name()]=valueToString<T>;
00070    }
00071 
00072    template <class T>
00073    double valueToDouble(const Reflex::Object& iObj, const Reflex::Member& iMember) {
00074       T temp;
00075       iMember.Invoke(iObj,temp);
00076       return temp;
00077    }
00078 
00079    typedef double (*DoubleFunctionType)(const Reflex::Object&, const Reflex::Member&);
00080    typedef std::map<std::string, DoubleFunctionType> TypeToDoubleMap;
00081 
00082    template<typename T>
00083    static void addToDoubleMap(TypeToDoubleMap& iMap) {
00084       iMap[typeid(T).name()]=valueToDouble<T>;
00085    }
00086 
00087 }
00088 
00089 static
00090 const std::string&
00091 stringValueFor(const ROOT::Reflex::Object& iObj, 
00092                const ROOT::Reflex::Member& iMember,
00093                const std::string& iUnit)
00094 {
00095    static std::string     s_empty_string;
00096    static TypeToStringMap s_map;
00097    if (s_map.empty())
00098    {
00099       addToStringMap<float>(s_map);
00100       addToStringMap<double>(s_map);
00101    }
00102    Reflex::Type returnType = iMember.TypeOf().ReturnType().FinalType();
00103 
00104    TypeToStringMap::iterator itFound =s_map.find(returnType.TypeInfo().name());
00105    if (itFound == s_map.end())
00106    {
00107       //std::cout <<" could not print because type is "<<iObj.TypeOf().TypeInfo().name()<<std::endl;
00108       return s_empty_string;
00109    }
00110 
00111    return itFound->second(iMember.Name(),iUnit,iObj,iMember);
00112 }
00113 
00114 static
00115 double
00116 doubleValueFor(const ROOT::Reflex::Object& iObj, const ROOT::Reflex::Member& iMember) {
00117    static TypeToDoubleMap s_map;
00118    if(s_map.empty() ) {
00119       addToDoubleMap<float>(s_map);
00120       addToDoubleMap<double>(s_map);
00121    }
00122 
00123    const Reflex::Type returnType = iMember.TypeOf().ReturnType().FinalType();
00124 
00125    //std::cout << val.TypeOf().TypeInfo().name()<<std::endl;
00126    TypeToDoubleMap::iterator itFound =s_map.find(returnType.TypeInfo().name());
00127    if(itFound == s_map.end()) {
00128       //std::cout <<" could not print because type is "<<iObj.TypeOf().TypeInfo().name()<<std::endl;
00129       return -999.0;
00130    }
00131 
00132    return itFound->second(iObj,iMember);
00133 }
00134 
00135 
00136 //
00137 // constructors and destructor
00138 //
00139 FWItemValueGetter::FWItemValueGetter(const ROOT::Reflex::Type& iType,
00140                                      const std::vector<std::pair<std::string, std::string> >& iFindValueFrom) :
00141    m_type(iType)
00142 {
00143    using namespace ROOT::Reflex;
00144    for(std::vector<std::pair<std::string,std::string> >::const_iterator it = iFindValueFrom.begin(), itEnd=iFindValueFrom.end();
00145        it != itEnd;
00146        ++it) {
00147       //std::cout <<" trying function "<<*it<<std::endl;
00148       Member temp = recursiveFindMember(it->first,iType);
00149       if(temp) {
00150          if(0==temp.FunctionParameterSize(true)) {
00151             //std::cout <<"    FOUND "<<temp.Name()<<std::endl;
00152             //std::cout <<"     in type "<<temp.DeclaringType().Name(SCOPED)<<std::endl;
00153             m_memberFunction = temp;
00154             m_unit = it->second;
00155             break;
00156          }
00157       }
00158    }
00159 }
00160 
00161 // FWItemValueGetter::FWItemValueGetter(const FWItemValueGetter& rhs)
00162 // {
00163 //    // do actual copying here;
00164 // }
00165 
00166 //FWItemValueGetter::~FWItemValueGetter()
00167 //{
00168 //}
00169 
00170 //
00171 // assignment operators
00172 //
00173 // const FWItemValueGetter& FWItemValueGetter::operator=(const FWItemValueGetter& rhs)
00174 // {
00175 //   //An exception safe implementation is
00176 //   FWItemValueGetter temp(rhs);
00177 //   swap(rhs);
00178 //
00179 //   return *this;
00180 // }
00181 
00182 //
00183 // member functions
00184 //
00185 
00186 //
00187 // const member functions
00188 //
00189 double
00190 FWItemValueGetter::valueFor(const void* iObject) const
00191 {
00192    ROOT::Reflex::Object temp(m_type,
00193                              const_cast<void*>(iObject));
00194    ROOT::Reflex::Object obj= temp.CastObject(m_memberFunction.DeclaringType());
00195    return ::doubleValueFor(obj,m_memberFunction);
00196 }
00197 
00198 const std::string&
00199 FWItemValueGetter::stringValueFor(const void* iObject) const
00200 {
00201    ROOT::Reflex::Object temp(m_type,
00202                              const_cast<void*>(iObject));
00203    ROOT::Reflex::Object obj= temp.CastObject(m_memberFunction.DeclaringType());
00204 
00205    return ::stringValueFor(obj,m_memberFunction,m_unit);
00206 }
00207 
00208 bool
00209 FWItemValueGetter::isValid() const
00210 {
00211    return bool(m_memberFunction);
00212 }
00213 
00214 std::string
00215 FWItemValueGetter::valueName() const
00216 {
00217    return m_memberFunction.Name();
00218 }
00219 
00220 const std::string&
00221 FWItemValueGetter::unit() const
00222 {
00223    return m_unit;
00224 }
00225 
00226 //
00227 // static member functions
00228 //