File indexing completed on 2024-04-06 12:13:14
0001
0002
0003
0004 #include <cassert>
0005 #include <ostream>
0006 #include "oneapi/tbb/concurrent_unordered_map.h"
0007 #include "FWCore/Utilities/interface/TypeID.h"
0008 #include "FWCore/Utilities/interface/FriendlyName.h"
0009 #include "FWCore/Utilities/interface/Exception.h"
0010 #include "FWCore/Utilities/interface/TypeDemangler.h"
0011
0012 namespace edm {
0013 void TypeID::print(std::ostream& os) const {
0014 try {
0015 os << className();
0016 } catch (cms::Exception const&) {
0017 os << typeInfo().name();
0018 }
0019 }
0020
0021 namespace {
0022
0023 TypeID const nullTypeID;
0024
0025 std::string typeToClassName(std::type_info const& iType) {
0026 try {
0027 return typeDemangle(iType.name());
0028 } catch (cms::Exception const& e) {
0029 cms::Exception theError("Name Demangling Error");
0030 theError << "TypeID::typeToClassName: can't demangle " << iType.name() << '\n';
0031 theError.append(e);
0032 throw theError;
0033 }
0034 }
0035 }
0036 struct TypeIDHasher {
0037 size_t operator()(TypeID const& tid) const { return std::hash<std::string>{}(std::string(tid.name())); }
0038 };
0039
0040 std::string const& TypeID::className() const {
0041 typedef oneapi::tbb::concurrent_unordered_map<edm::TypeID, std::string, TypeIDHasher> Map;
0042 static Map s_typeToName;
0043
0044 auto itFound = s_typeToName.find(*this);
0045 if (s_typeToName.end() == itFound) {
0046 itFound = s_typeToName.insert(Map::value_type(*this, typeToClassName(typeInfo()))).first;
0047 }
0048 return itFound->second;
0049 }
0050
0051 std::string TypeID::userClassName() const {
0052 std::string theName = className();
0053 if (theName.find("edm::Wrapper") == 0) {
0054 stripTemplate(theName);
0055 }
0056 return theName;
0057 }
0058
0059 std::string TypeID::friendlyClassName() const { return friendlyname::friendlyName(className()); }
0060
0061 bool stripTemplate(std::string& theName) {
0062 std::string const spec("<,>");
0063 char const space = ' ';
0064 std::string::size_type idx = theName.find_first_of(spec);
0065 if (idx == std::string::npos) {
0066 return false;
0067 }
0068 std::string::size_type first = 0;
0069 std::string::size_type after = idx;
0070 if (theName[idx] == '<') {
0071 after = theName.rfind('>');
0072 assert(after != std::string::npos);
0073 first = ++idx;
0074 } else {
0075 theName = theName.substr(0, idx);
0076 }
0077 std::string::size_type idxa = after;
0078 while (space == theName[--idxa])
0079 --after;
0080 std::string::size_type idxf = first;
0081 while (space == theName[idxf++])
0082 ++first;
0083 theName = theName.substr(first, after - first);
0084 return true;
0085 }
0086
0087 std::string stripNamespace(std::string const& theName) {
0088
0089 std::string::size_type colonIndex = theName.rfind(':');
0090 if (colonIndex == std::string::npos) {
0091
0092 return theName;
0093 }
0094 std::string::size_type bracketIndex = theName.rfind('>');
0095 if (bracketIndex == std::string::npos || bracketIndex < colonIndex) {
0096
0097 return theName.substr(colonIndex + 1);
0098 }
0099
0100 int depth = 1;
0101 for (size_t index = bracketIndex; index != 0; --index) {
0102 char c = theName[index - 1];
0103 if (c == '>') {
0104 ++depth;
0105 } else if (c == '<') {
0106 --depth;
0107 assert(depth >= 0);
0108 } else if (depth == 0 && c == ':') {
0109 return theName.substr(index);
0110 }
0111 }
0112 return theName;
0113 }
0114
0115 TypeID::operator bool() const { return !(*this == nullTypeID); }
0116
0117 std::ostream& operator<<(std::ostream& os, TypeID const& id) {
0118 id.print(os);
0119 return os;
0120 }
0121 }