LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
TypeID.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
7 
8 #include <cstddef>
9 #include <map>
10 #include <mutex>
11 #include <ostream>
12 #include <string>
13 #include <typeinfo>
14 #include <utility>
15 
16 using namespace std;
17 
18 namespace {
19  map<size_t, string> name_cache{};
20  mutex cache_mutex{};
21 }
22 
23 namespace art {
24 
25  TypeID::~TypeID() noexcept = default;
26  TypeID::TypeID() noexcept = default;
27  TypeID::TypeID(TypeID const&) noexcept = default;
28  TypeID::TypeID(TypeID&) noexcept = default;
29  TypeID& TypeID::operator=(TypeID const&) noexcept = default;
30  TypeID& TypeID::operator=(TypeID&) noexcept = default;
31 
32  TypeID::TypeID(type_info const& ti) noexcept : ti_{&ti} {}
33  TypeID::TypeID(type_info const* ti) noexcept : ti_{ti} {}
34 
35  type_info const&
36  TypeID::typeInfo() const
37  {
38  return *ti_;
39  }
40 
41  char const*
42  TypeID::name() const
43  {
44  return ti_->name();
45  }
46 
47  string
48  TypeID::className() const
49  {
50  auto hash_code = typeInfo().hash_code();
51  std::lock_guard sentry{cache_mutex};
52  auto entry = name_cache.find(hash_code);
53  if (entry == name_cache.end()) {
54  entry =
55  name_cache.emplace(hash_code, uniform_type_name(typeInfo())).first;
56  }
57  return entry->second;
58  }
59 
60  string
61  TypeID::friendlyClassName() const
62  {
63  return friendlyname::friendlyName(className());
64  }
65 
66  bool
67  TypeID::operator<(TypeID const& rhs) const
68  {
69  return ti_->before(*rhs.ti_);
70  }
71 
72  bool
73  TypeID::operator==(TypeID const& rhs) const
74  {
75  return *ti_ == *rhs.ti_;
76  }
77 
78  TypeID::operator bool() const
79  {
80  return ti_ != nullptr;
81  }
82 
83  void
85  {
86  std::swap(ti_, other.ti_);
87  }
88 
89  void
90  TypeID::print(ostream& os) const
91  {
92  os << className();
93  }
94 
95  bool
96  operator>(TypeID const& a, TypeID const& b)
97  {
98  return b < a;
99  }
100 
101  bool
102  operator!=(TypeID const& a, TypeID const& b)
103  {
104  return !(a == b);
105  }
106 
107  void
109  {
110  left.swap(right);
111  }
112 
113  ostream&
114  operator<<(ostream& os, TypeID const& tid)
115  {
116  tid.print(os);
117  return os;
118  }
119 
120  string
121  name_of_template_arg(string const& template_instance, size_t desired_arg)
122  {
123  string result;
124  auto comma_count = 0ul;
125  auto template_level = 0ul;
126  auto arg_start = string::npos;
127  auto pos = 0ul;
128  pos = template_instance.find_first_of("<>,", pos);
129  while (pos != string::npos) {
130  switch (template_instance[pos]) {
131  case '<':
132  ++template_level;
133  if ((desired_arg == 0ul) && (template_level == 1ul)) {
134  // Found the begin of the desired template arg.
135  arg_start = pos + 1;
136  }
137  break;
138  case '>':
139  --template_level;
140  if ((desired_arg == comma_count) && (template_level == 0ul)) {
141  // Found the end of the desired template arg -- trim trailing
142  // whitespace
143  auto const arg_end =
144  template_instance.find_last_not_of(" \t", pos - 1) + 1;
145  result = template_instance.substr(arg_start, arg_end - arg_start);
146  return result;
147  }
148  break;
149  case ',':
150  if (template_level != 1ul) {
151  // Ignore arguments not at the first level.
152  break;
153  }
154  if (comma_count == desired_arg) {
155  // Found the end of the desired template arg.
156  result = template_instance.substr(arg_start, pos - arg_start);
157  return result;
158  }
159  ++comma_count;
160  if (comma_count == desired_arg) {
161  // Found the begin of the desired template arg.
162  arg_start = pos + 1;
163  }
164  break;
165  }
166  ++pos;
167  pos = template_instance.find_first_of("<>,", pos);
168  }
169  return result;
170  }
171 
172  string
173  name_of_assns_partner(string assns_type_name)
174  {
175  string result;
176  if (!is_assns(assns_type_name)) {
177  return result;
178  }
179  static string const assns_start = "art::Assns<"s;
180  auto const arg0 = name_of_template_arg(assns_type_name, 0);
181  auto const arg1 = name_of_template_arg(assns_type_name, 1);
182  auto const arg2 = name_of_template_arg(assns_type_name, 2);
183  result = assns_start + arg1 + ',' + arg0 + ',' + arg2 + '>';
184  return result;
185  }
186 
187  string
188  name_of_assns_base(string assns_type_name)
189  {
190  string result;
191  if (!is_assns(assns_type_name)) {
192  return result;
193  }
194  using namespace std::string_literals;
195  static string const assns_start = "art::Assns<"s;
196  if (name_of_template_arg(assns_type_name, 2) == "void"s) {
197  // Doesn't have the base we're looking for.
198  return result;
199  }
200  result = assns_start + name_of_template_arg(assns_type_name, 0) + ',' +
201  name_of_template_arg(assns_type_name, 1) + ",void>";
202  return result;
203  }
204 
205  string
206  name_of_unwrapped_product(string const& wrapped_name)
207  {
208  using namespace std::string_literals;
209  if (!is_instantiation_of(wrapped_name, "art::Wrapper"s)) {
210  throw Exception(errors::LogicError, "Can't unwrap"s)
211  << "-- attempted to get unwrapped product from non-instance of art::Wrapper."s;
212  }
213  return name_of_template_arg(wrapped_name, 0);
214  }
215 
216 } // namespace art
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
constexpr bool operator<(CryostatID const &a, CryostatID const &b)
Order cryostats with increasing ID.
Definition: geo_types.h:692
STL namespace.
string name_of_assns_partner(string assns_type_name)
Definition: TypeID.cc:173
ostream & operator<<(ostream &os, TypeID const &tid)
Definition: TypeID.cc:114
string name_of_unwrapped_product(string const &wrapped_name)
Definition: TypeID.cc:206
void print(std::ostream &) const
Definition: TypeID.cc:90
std::string uniform_type_name(std::type_info const &tid)
string name_of_assns_base(string assns_type_name)
Definition: TypeID.cc:188
bool is_instantiation_of(std::string const &type_name, std::string const &template_name)
Definition: TypeID.h:53
string name_of_template_arg(string const &template_instance, size_t desired_arg)
Definition: TypeID.cc:121
std::string friendlyName(std::string const &iFullName)
void swap(TypeID &)
Definition: TypeID.cc:84
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
bool operator!=(TypeID const &a, TypeID const &b)
Definition: TypeID.cc:102
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
bool operator>(TypeID const &a, TypeID const &b)
Definition: TypeID.cc:96
void swap(TypeID &left, TypeID &right)
Definition: TypeID.cc:108
Definition: MVAAlg.h:12
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
Definition: counter.h:278
bool is_assns(std::string const &type_name)
Definition: TypeID.h:66
std::type_info const * ti_
Definition: TypeID.h:45