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
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