CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/FWCore/Utilities/src/TypeID.cc

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------
00002 
00003 ----------------------------------------------------------------------*/
00004 #include <ostream>
00005 #include "FWCore/Utilities/interface/TypeID.h"
00006 #include "FWCore/Utilities/interface/FriendlyName.h"
00007 #include "FWCore/Utilities/interface/GCCPrerequisite.h"
00008 #include "FWCore/Utilities/interface/EDMException.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include "FWCore/Utilities/interface/TypeDemangler.h"
00011 #include "Reflex/Type.h"
00012 #include "boost/thread/tss.hpp"
00013 
00014 namespace edm {
00015   void
00016   TypeID::print(std::ostream& os) const {
00017     try {
00018       os << className();
00019     } catch (cms::Exception const& e) {
00020       os << typeInfo().name();
00021     }
00022   }
00023 
00024 namespace {
00025 
00026   std::string typeToClassName(std::type_info const& iType) {
00027     Reflex::Type t = Reflex::Type::ByTypeInfo(iType);
00028     if (!bool(t)) {
00029 #if GCC_PREREQUISITE(3,0,0)
00030       // demangling supported for currently supported gcc compilers.
00031       try {
00032         std::string result;
00033         typeDemangle(iType.name(), result);
00034         return result;
00035       } catch (cms::Exception const& e) {
00036         edm::Exception theError(errors::DictionaryNotFound,"NoMatch");
00037         theError << "TypeID::className: No dictionary for class " << iType.name() << '\n';
00038         theError.append(e);
00039         throw theError;
00040       }
00041 #else
00042       throw edm::Exception(errors::DictionaryNotFound,"NoMatch")
00043        << "TypeID::className: No dictionary for class " << iType.name() << '\n';
00044 #endif
00045     }
00046     return t.Name(Reflex::SCOPED);
00047   }
00048 }
00049 
00050   std::string
00051   TypeID::className() const {
00052     typedef std::map<edm::TypeID, std::string> Map;
00053     static boost::thread_specific_ptr<Map> s_typeToName;
00054     if(0 == s_typeToName.get()){
00055       s_typeToName.reset(new Map);
00056     }
00057     Map::const_iterator itFound = s_typeToName->find(*this);
00058     if(s_typeToName->end() == itFound) {
00059       itFound = s_typeToName->insert(Map::value_type(*this, typeToClassName(typeInfo()))).first;
00060     }
00061     return itFound->second;
00062   }
00063 
00064   std::string
00065   TypeID::userClassName() const {
00066     std::string theName = className();
00067     if (theName.find("edm::Wrapper") == 0) {
00068       stripTemplate(theName);
00069     }
00070     return theName;
00071   }
00072 
00073   std::string
00074   TypeID::friendlyClassName() const {
00075     return friendlyname::friendlyName(className());
00076   }
00077 
00078   bool
00079   TypeID::stripTemplate(std::string& theName) {
00080     std::string const spec("<,>");
00081     char const space = ' ';
00082     std::string::size_type idx = theName.find_first_of(spec);
00083     if (idx == std::string::npos) {
00084       return false;
00085     }
00086     std::string::size_type first = 0;
00087     std::string::size_type after = idx;
00088     if (theName[idx] == '<') {
00089       after = theName.rfind('>');
00090       assert (after != std::string::npos);
00091       first = ++idx;
00092     } else {
00093       theName = theName.substr(0, idx);
00094     }
00095     std::string::size_type idxa = after;
00096     while (space == theName[--idxa]) --after;
00097     std::string::size_type idxf = first;
00098     while (space == theName[idxf++]) ++first;
00099     theName = theName.substr(first, after - first);
00100     return true;
00101   }
00102 
00103   bool
00104   TypeID::stripNamespace(std::string& theName) {
00105     std::string::size_type idx = theName.rfind(':');
00106     bool ret = (idx != std::string::npos);
00107     if (ret) {
00108       ++idx;
00109       theName = theName.substr(idx);
00110     }
00111     return ret;
00112   }
00113 
00114   bool
00115   TypeID::hasDictionary() const {
00116     return bool(Reflex::Type::ByTypeInfo(typeInfo()));
00117   }
00118 
00119   std::ostream&
00120   operator<<(std::ostream& os, TypeID const& id) {
00121     id.print(os);
00122     return os;
00123   }
00124 }
00125