CMS 3D CMS Logo

FriendlyName.cc
Go to the documentation of this file.
1 /*
2  * friendlyName.cpp
3  * CMSSW
4  *
5  * Created by Chris Jones on 2/24/06.
6  *
7  */
8 #include <string>
9 #include <regex>
10 #include <iostream>
11 #include <cassert>
12 #include "oneapi/tbb/concurrent_unordered_map.h"
13 
14 //NOTE: This should probably be rewritten so that we break the class name into a tree where the template arguments are the node. On the way down the tree
15 // we look for '<' or ',' and on the way up (caused by finding a '>') we can apply the transformation to the output string based on the class name for the
16 // templated class. Up front we'd register a class name to a transformation function (which would probably take a std::vector<std::string> which holds
17 // the results of the node transformations)
18 
19 namespace {
20  constexpr bool debug = false;
21  std::string prefix; // used only if debug == true
22 } // namespace
23 
24 namespace edm {
25  namespace friendlyname {
26  static std::regex const reBeginSpace("^ +");
27  static std::regex const reEndSpace(" +$");
28  static std::regex const reAllSpaces(" +");
29  static std::regex const reColons("::");
30  static std::regex const reComma(",");
31  static std::regex const reTemplateArgs("[^<]*<(.*)>$");
32  static std::regex const rePointer("\\*");
33  static std::regex const reArray("\\[\\]");
34  static std::regex const reUniquePtrDeleter("^std::unique_ptr< *(.*), *std::default_delete<\\1> *>");
35  static std::regex const reUniquePtr("^std::unique_ptr");
36  static std::string const emptyString("");
37 
38  std::string handleNamespaces(std::string const& iIn) { return std::regex_replace(iIn, reColons, emptyString); }
39 
41  return std::regex_replace(std::regex_replace(iIn, reBeginSpace, emptyString), reEndSpace, emptyString);
42  }
43 
44  std::string removeAllSpaces(std::string const& iIn) { return std::regex_replace(iIn, reAllSpaces, emptyString); }
45  static std::regex const reWrapper("edm::Wrapper<(.*)>");
46  static std::regex const reString("std::basic_string<char>");
47  static std::regex const reString2("std::string");
48  static std::regex const reString3("std::basic_string<char,std::char_traits<char> >");
49  //The c++11 abi for gcc internally uses a different namespace for standard classes
50  static std::regex const reCXX11("std::__cxx11::");
51  static std::regex const reSorted("edm::SortedCollection<(.*), *edm::StrictWeakOrdering<\\1 *> >");
52  static std::regex const reclangabi("std::__1::");
53  static std::regex const reULongLong("ULong64_t");
54  static std::regex const reLongLong("Long64_t");
55  static std::regex const reUnsigned("unsigned ");
56  static std::regex const reLong("long ");
57  static std::regex const reVector("std::vector");
58  static std::regex const reUnorderedSetHashKeyEqual(
59  "std::unordered_set< *(.*), *std::hash<\\1> *, *std::equal_to<\\1> *>");
60  static std::regex const reUnorderedSetCustomHashKeyEqual(
61  "std::unordered_set< *(.*), *(.*) *, *std::equal_to<\\1> *>");
62  static std::regex const reUnorderedSetHash("std::unordered_set< *(.*), *std::hash<\\1> *>");
63  static std::regex const reUnorderedSet("std::unordered_set");
64  static std::regex const reUnorderedMapHashKeyEqual(
65  "std::unordered_map< *(.*), *(.*), *std::hash<\\1> *, *std::equal_to<\\1> *>");
66  static std::regex const reUnorderedMapCustomHashKeyEqual(
67  "std::unordered_map< *(.*), *(.*), *(.*) *, *std::equal_to<\\1> *>");
68  static std::regex const reUnorderedMapHash("std::unordered_map< *(.*), *(.*), *std::hash<\\1> *>");
69  static std::regex const reUnorderedMap("std::unordered_map");
70  static std::regex const reSharedPtr("std::shared_ptr");
71  static std::regex const reAIKR(
72  ", *edm::helper::AssociationIdenticalKeyReference"); //this is a default so can replaced with empty
73  //force first argument to also be the argument to edm::ClonePolicy so that if OwnVector is within
74  // a template it will not eat all the remaining '>'s
75  static std::regex const reOwnVector("edm::OwnVector<(.*), *edm::ClonePolicy<\\1 *> >");
76 
77  //NOTE: the '?' means make the smallest match. This may lead to problems where the template arguments themselves have commas
78  // but we are using it in the cases where edm::AssociationMap appears multiple times in template arguments
79  static std::regex const reOneToOne("edm::AssociationMap< *edm::OneToOne<(.*?),(.*?), *u[a-z]*> >");
80  static std::regex const reOneToMany("edm::AssociationMap< *edm::OneToMany<(.*?),(.*?), *u[a-z]*> >");
81  static std::regex const reOneToValue("edm::AssociationMap< *edm::OneToValue<(.*?),(.*?), *u[a-z]*> >");
82  static std::regex const reOneToManyWithQuality(
83  "edm::AssociationMap<edm::OneToManyWithQuality<(.*?), *(.*?), *(.*?), *u[a-z]*> >");
84  static std::regex const reToVector("edm::AssociationVector<(.*), *(.*), *edm::Ref.*,.*>");
85  //NOTE: if the item within a clone policy is a template, this substitution will probably fail
86  static std::regex const reToRangeMap("edm::RangeMap< *(.*), *(.*), *edm::ClonePolicy<([^>]*)> >");
87  //NOTE: If container is a template with one argument which is its 'type' then can simplify name
88  static std::regex const reToRefs1(
89  "edm::RefVector< *(.*)< *(.*) *>, *\\2 *, *edm::refhelper::FindUsingAdvance< *\\1< *\\2 *> *, *\\2 *> *>");
90  static std::regex const reToRefs2(
91  "edm::RefVector< *(.*) *, *(.*) *, *edm::refhelper::FindUsingAdvance< *\\1, *\\2 *> *>");
92  static std::regex const reToRefsAssoc(
93  "edm::RefVector< *Association(.*) *, *edm::helper(.*), *Association(.*)::Find>");
94 
95  // type aliases for Alpaka internals
96  static std::regex const reAlpakaDevCpu("alpaka::DevCpu"); // alpakaDevCpu
97  static std::regex const reAlpakaDevCudaRt("alpaka::DevUniformCudaHipRt<alpaka::ApiCudaRt>"); // alpakaDevCudaRt
98  static std::regex const reAlpakaDevHipRt("alpaka::DevUniformCudaHipRt<alpaka::ApiHipRt>"); // alpakaDevHipRt
99  static std::regex const reAlpakaQueueCpuBlocking(
100  "alpaka::QueueGenericThreadsBlocking<alpaka::DevCpu>"); // alpakaQueueCpuBlocking
101  static std::regex const reAlpakaQueueCpuNonBlocking(
102  "alpaka::QueueGenericThreadsNonBlocking<alpaka::DevCpu>"); // alpakaQueueCpuNonBlocking
103  static std::regex const reAlpakaQueueCudaRtBlocking(
104  "alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiCudaRt,true>"); // alpakaQueueCudaRtBlocking
105  static std::regex const reAlpakaQueueCudaRtNonBlocking(
106  "alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiCudaRt,false>"); // alpakaQueueCudaRtNonBlocking
107  static std::regex const reAlpakaQueueHipRtBlocking(
108  "alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiHipRt,true>"); // alpakaQueueHipRtBlocking
109  static std::regex const reAlpakaQueueHipRtNonBlocking(
110  "alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiHipRt,false>"); // alpakaQueueHipRtNonBlocking
111 
113  using std::regex;
114  using std::regex_replace;
115  std::string name = regex_replace(iIn, reWrapper, "$1");
116  name = regex_replace(name, rePointer, "ptr");
117  name = regex_replace(name, reArray, "As");
118  name = regex_replace(name, reAIKR, "");
119  name = regex_replace(name, reclangabi, "std::");
120  name = regex_replace(name, reCXX11, "std::");
121  name = regex_replace(name, reString, "String");
122  name = regex_replace(name, reString2, "String");
123  name = regex_replace(name, reString3, "String");
124  name = regex_replace(name, reSorted, "sSorted<$1>");
125  name = regex_replace(name, reULongLong, "ull");
126  name = regex_replace(name, reLongLong, "ll");
127  name = regex_replace(name, reUnsigned, "u");
128  name = regex_replace(name, reLong, "l");
129  name = regex_replace(name, reVector, "s");
130  name = regex_replace(name, reSharedPtr, "SharedPtr");
131  name = regex_replace(name, reOwnVector, "sOwned<$1>");
132  name = regex_replace(name, reToVector, "AssociationVector<$1,To,$2>");
133  name = regex_replace(name, reOneToOne, "Association<$1,ToOne,$2>");
134  name = regex_replace(name, reOneToMany, "Association<$1,ToMany,$2>");
135  name = regex_replace(name, reOneToValue, "Association<$1,ToValue,$2>");
136  name = regex_replace(name, reOneToManyWithQuality, "Association<$1,ToMany,$2,WithQuantity,$3>");
137  name = regex_replace(name, reToRangeMap, "RangeMap<$1,$2>");
138  name = regex_replace(name, reToRefs1, "Refs<$1<$2>>");
139  name = regex_replace(name, reToRefs2, "Refs<$1,$2>");
140  name = regex_replace(name, reToRefsAssoc, "Refs<Association$1>");
141 
142  // Alpaka types
143  name = regex_replace(name, reAlpakaQueueCpuBlocking, "alpakaQueueCpuBlocking");
144  name = regex_replace(name, reAlpakaQueueCpuNonBlocking, "alpakaQueueCpuNonBlocking");
145  name = regex_replace(name, reAlpakaQueueCudaRtBlocking, "alpakaQueueCudaRtBlocking");
146  name = regex_replace(name, reAlpakaQueueCudaRtNonBlocking, "alpakaQueueCudaRtNonBlocking");
147  name = regex_replace(name, reAlpakaQueueHipRtBlocking, "alpakaQueueHipRtBlocking");
148  name = regex_replace(name, reAlpakaQueueHipRtNonBlocking, "alpakaQueueHipRtNonBlocking");
149  // devices should be last, as they can appear as template arguments in other types
150  name = regex_replace(name, reAlpakaDevCpu, "alpakaDevCpu");
151  name = regex_replace(name, reAlpakaDevCudaRt, "alpakaDevCudaRt");
152  name = regex_replace(name, reAlpakaDevHipRt, "alpakaDevHipRt");
153 
154  if constexpr (debug) {
155  std::cout << prefix << "standardRenames iIn " << iIn << " result " << name << std::endl;
156  }
157  return name;
158  }
159 
162  using namespace std;
163  std::string result = removeExtraSpaces(iFullName);
164 
165  // temporarily remove leading const
166  std::string leadingConst;
167  if (std::string_view{result}.substr(0, 5) == "const") {
168  leadingConst = "const";
169  result = removeExtraSpaces(result.substr(5));
170  }
171 
172  if constexpr (debug) {
173  std::cout << prefix << "subFriendlyName iFullName " << iFullName << " result " << result << std::endl;
174  }
175  // Handle unique_ptr, which may contain the deleter (but handle only std::default_delete)
176  {
177  auto result2 =
178  regex_replace(result, reUniquePtrDeleter, "UniquePtr<$1>", std::regex_constants::format_first_only);
179  if (result2 == result) {
180  result2 = regex_replace(result, reUniquePtr, "UniquePtr", std::regex_constants::format_first_only);
181  }
182  result = std::move(result2);
183  }
184  // insert the leading const back if it was there
185  result = leadingConst + result;
186  // Handle unordered_set, which may contain a hash and an an equal for the key
187  {
188  auto result2 =
189  regex_replace(result, reUnorderedSetHashKeyEqual, "stduset<$1>", std::regex_constants::format_first_only);
190  if (result2 == result) {
191  result2 = regex_replace(
192  result, reUnorderedSetCustomHashKeyEqual, "stduset<$1, $2>", std::regex_constants::format_first_only);
193  }
194  if (result2 == result) {
195  result2 = regex_replace(result, reUnorderedSetHash, "stduset<$1>", std::regex_constants::format_first_only);
196  }
197  if (result2 == result) {
198  result2 = regex_replace(result, reUnorderedSet, "stduset", std::regex_constants::format_first_only);
199  }
200  result = std::move(result2);
201  }
202  // Handle unordered_map, which may contain a hash and an an equal for the key
203  {
204  auto result2 = regex_replace(
205  result, reUnorderedMapHashKeyEqual, "stdumap<$1, $2>", std::regex_constants::format_first_only);
206  if (result2 == result) {
207  result2 = regex_replace(
208  result, reUnorderedMapCustomHashKeyEqual, "stdumap<$1, $2, $3>", std::regex_constants::format_first_only);
209  }
210  if (result2 == result) {
211  result2 =
212  regex_replace(result, reUnorderedMapHash, "stdumap<$1, $2>", std::regex_constants::format_first_only);
213  }
214  if (result2 == result) {
215  result2 = regex_replace(result, reUnorderedMap, "stdumap", std::regex_constants::format_first_only);
216  }
217  result = std::move(result2);
218  }
219  if (smatch theMatch; regex_match(result, theMatch, reTemplateArgs)) {
220  //std::cout <<"found match \""<<theMatch.str(1) <<"\"" <<std::endl;
221  //static regex const templateClosing(">$");
222  //std::string aMatch = regex_replace(theMatch.str(1),templateClosing,"");
223  std::string aMatch = theMatch.str(1);
224  if constexpr (debug) {
225  prefix += " ";
226  }
227  std::string theSub = handleTemplateArguments(aMatch);
228  if constexpr (debug) {
229  prefix.pop_back();
230  prefix.pop_back();
231  std::cout << prefix << " aMatch " << aMatch << " theSub " << theSub << std::endl;
232  }
233  regex const eMatch(std::string("(^[^<]*)<") + aMatch + ">");
234  result = regex_replace(result, eMatch, theSub + "$1");
235  }
236  return removeAllSpaces(result);
237  }
238 
240  using namespace std;
242  if constexpr (debug) {
243  std::cout << prefix << "handleTemplateArguments " << iIn << " removeExtraSpaces " << result << std::endl;
244  }
245 
246  // Trick to have every full class name to end with comma to
247  // avoid treating the end as a special case
248  result += ",";
249 
250  std::string result2;
251  result2.reserve(iIn.size());
252  unsigned int openTemplate = 0;
253  bool hadTemplate = false;
254  size_t begin = 0;
255  for (size_t i = 0, size = result.size(); i < size; ++i) {
256  if (result[i] == '<') {
257  ++openTemplate;
258  hadTemplate = true;
259  continue;
260  } else if (result[i] == '>') {
261  --openTemplate;
262  }
263  // If we are not within the template arguments of a class template
264  // - encountering comma means that we are within a template
265  // argument of some other class template, and we've reached
266  // a point when we should translate the argument class name
267  // - encountering colon, but only if the class name so far
268  // itself was a template, we've reached a point when we
269  // should translate the class name
270  if (const bool hasComma = result[i] == ',', hasColon = hadTemplate and result[i] == ':';
271  openTemplate == 0 and (hasComma or hasColon)) {
272  std::string templateClass = result.substr(begin, i - begin);
273  if constexpr (debug) {
274  std::cout << prefix << " templateClass " << templateClass << std::endl;
275  }
276  if (hadTemplate) {
277  if constexpr (debug) {
278  prefix += " ";
279  }
280  std::string friendlierName = subFriendlyName(templateClass);
281  if constexpr (debug) {
282  prefix.pop_back();
283  prefix.pop_back();
284  std::cout << prefix << " friendlierName " << friendlierName << std::endl;
285  }
286  result2 += friendlierName;
287  } else {
288  result2 += templateClass;
289  }
290  if constexpr (debug) {
291  std::cout << prefix << " result2 " << result2 << std::endl;
292  }
293  // reset counters
294  hadTemplate = false;
295  begin = i + 1;
296  // With colon we need to eat the second colon as well
297  if (hasColon) {
298  assert(result[begin] == ':');
299  ++begin;
300  }
301  }
302  }
303 
304  result = regex_replace(result2, reComma, "");
305  if constexpr (debug) {
306  std::cout << prefix << " reComma " << result << std::endl;
307  }
308  return result;
309  }
311  if constexpr (debug) {
312  std::cout << "\nfriendlyName for " << iFullName << std::endl;
313  prefix = " ";
314  }
315  typedef oneapi::tbb::concurrent_unordered_map<std::string, std::string> Map;
316  static Map s_fillToFriendlyName;
317  auto itFound = s_fillToFriendlyName.find(iFullName);
318  if (s_fillToFriendlyName.end() == itFound) {
319  itFound = s_fillToFriendlyName
320  .insert(Map::value_type(iFullName, handleNamespaces(subFriendlyName(standardRenames(iFullName)))))
321  .first;
322  }
323  if constexpr (debug) {
324  std::cout << "result " << itFound->second << std::endl;
325  }
326  return itFound->second;
327  }
328  } // namespace friendlyname
329 } // namespace edm
static std::regex const reAlpakaQueueCudaRtNonBlocking("alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiCudaRt,false>")
static std::regex const reEndSpace(" +$")
static std::regex const reToRangeMap("edm::RangeMap< *(.*), *(.*), *edm::ClonePolicy<([^>]*)> >")
static std::regex const reUnorderedMap("std::unordered_map")
static std::regex const reCXX11("std::__cxx11::")
static std::regex const reAlpakaQueueCpuNonBlocking("alpaka::QueueGenericThreadsNonBlocking<alpaka::DevCpu>")
static std::regex const reAIKR(", *edm::helper::AssociationIdenticalKeyReference")
static std::regex const rePointer("\")
static std::regex const reString3("std::basic_string<char,std::char_traits<char> >")
static std::regex const reUnsigned("unsigned ")
std::string removeAllSpaces(std::string const &iIn)
Definition: FriendlyName.cc:44
std::string subFriendlyName(std::string const &iFullName)
static std::regex const reSharedPtr("std::shared_ptr")
static std::regex const reUniquePtrDeleter("^std::unique_ptr< *(.*), *std::default_delete<> *>")
static std::regex const reOneToManyWithQuality("edm::AssociationMap<edm::OneToManyWithQuality<(.*?), *(.*?), *(.*?), *u[a-z]*> >")
static std::regex const reToVector("edm::AssociationVector<(.*), *(.*), *edm::Ref.*,.*>")
assert(be >=bs)
static std::regex const reLong("long ")
static std::regex const reAlpakaDevHipRt("alpaka::DevUniformCudaHipRt<alpaka::ApiHipRt>")
static std::regex const reOneToMany("edm::AssociationMap< *edm::OneToMany<(.*?),(.*?), *u[a-z]*> >")
static std::regex const reToRefs2("edm::RefVector< *(.*) *, *(.*) *, *edm::refhelper::FindUsingAdvance< *\, *\ *> *>")
static std::regex const reArray("\\")
static std::regex const reLongLong("Long64_t")
static std::regex const reComma(",")
static std::regex const reAlpakaQueueCpuBlocking("alpaka::QueueGenericThreadsBlocking<alpaka::DevCpu>")
std::string friendlyName(std::string const &iFullName)
static std::regex const reUnorderedSetHash("std::unordered_set< *(.*), *std::hash<> *>")
static std::regex const reToRefs1("edm::RefVector< *(.*)< *(.*) *>, *\ *, *edm::refhelper::FindUsingAdvance< *< *\ *> *, *\ *> *>")
static std::regex const reAlpakaDevCpu("alpaka::DevCpu")
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static std::regex const reUnorderedSetCustomHashKeyEqual("std::unordered_set< *(.*), *(.*) *, *std::equal_to<> *>")
static std::regex const reAlpakaQueueHipRtNonBlocking("alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiHipRt,false>")
static std::regex const reOneToOne("edm::AssociationMap< *edm::OneToOne<(.*?),(.*?), *u[a-z]*> >")
std::string handleNamespaces(std::string const &iIn)
Definition: FriendlyName.cc:38
static std::regex const reWrapper("edm::Wrapper<(.*)>")
static std::regex const reUnorderedMapHashKeyEqual("std::unordered_map< *(.*), *(.*), *std::hash<> *, *std::equal_to<> *>")
static std::regex const reAlpakaQueueCudaRtBlocking("alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiCudaRt,true>")
static std::regex const reUnorderedSet("std::unordered_set")
static std::regex const reSorted("edm::SortedCollection<(.*), *edm::StrictWeakOrdering<\ *> >")
static std::regex const reTemplateArgs("[^<]*<(.*)>$")
static std::regex const reAlpakaDevCudaRt("alpaka::DevUniformCudaHipRt<alpaka::ApiCudaRt>")
static std::regex const reToRefsAssoc("edm::RefVector< *Association(.*) *, *edm::helper(.*), *Association(.*)::Find>")
static std::regex const reULongLong("ULong64_t")
static std::regex const reVector("std::vector")
#define debug
Definition: HDRShower.cc:19
std::string standardRenames(std::string const &iIn)
static std::regex const reUnorderedSetHashKeyEqual("std::unordered_set< *(.*), *std::hash<> *, *std::equal_to<> *>")
static std::regex const reColons("::")
std::string handleTemplateArguments(std::string const &)
static std::regex const reAlpakaQueueHipRtBlocking("alpaka::uniform_cuda_hip::detail::QueueUniformCudaHipRt<alpaka::ApiHipRt,true>")
static std::string const emptyString("")
HLT enums.
static std::regex const reBeginSpace("^ +")
static std::regex const reOwnVector("edm::OwnVector<(.*), *edm::ClonePolicy<\ *> >")
static std::regex const reUnorderedMapHash("std::unordered_map< *(.*), *(.*), *std::hash<> *>")
static std::regex const reUniquePtr("^std::unique_ptr")
static std::regex const reclangabi("std::__1::")
static std::regex const reUnorderedMapCustomHashKeyEqual("std::unordered_map< *(.*), *(.*), *(.*) *, *std::equal_to<> *>")
static std::regex const reString2("std::string")
static std::regex const reString("std::basic_string<char>")
static std::regex const reAllSpaces(" +")
def move(src, dest)
Definition: eostools.py:511
static std::regex const reOneToValue("edm::AssociationMap< *edm::OneToValue<(.*?),(.*?), *u[a-z]*> >")
std::string removeExtraSpaces(std::string const &iIn)
Definition: FriendlyName.cc:40