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
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  {
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 { return ti_ != nullptr; }
79 
80  void
82  {
83  std::swap(ti_, other.ti_);
84  }
85 
86  void
87  TypeID::print(ostream& os) const
88  {
89  os << className();
90  }
91 
92  bool
93  operator>(TypeID const& a, TypeID const& b)
94  {
95  return b < a;
96  }
97 
98  bool
99  operator!=(TypeID const& a, TypeID const& b)
100  {
101  return !(a == b);
102  }
103 
104  void
106  {
107  left.swap(right);
108  }
109 
110  ostream&
111  operator<<(ostream& os, TypeID const& tid)
112  {
113  tid.print(os);
114  return os;
115  }
116 
117  string
118  name_of_template_arg(string const& template_instance, size_t desired_arg)
119  {
120  string result;
121  auto comma_count = 0ul;
122  auto template_level = 0ul;
123  auto arg_start = string::npos;
124  auto pos = 0ul;
125  pos = template_instance.find_first_of("<>,", pos);
126  while (pos != string::npos) {
127  switch (template_instance[pos]) {
128  case '<':
129  ++template_level;
130  if ((desired_arg == 0ul) && (template_level == 1ul)) {
131  // Found the begin of the desired template arg.
132  arg_start = pos + 1;
133  }
134  break;
135  case '>':
136  --template_level;
137  if ((desired_arg == comma_count) && (template_level == 0ul)) {
138  // Found the end of the desired template arg -- trim trailing
139  // whitespace
140  auto const arg_end =
141  template_instance.find_last_not_of(" \t", pos - 1) + 1;
142  result = template_instance.substr(arg_start, arg_end - arg_start);
143  return result;
144  }
145  break;
146  case ',':
147  if (template_level != 1ul) {
148  // Ignore arguments not at the first level.
149  break;
150  }
151  if (comma_count == desired_arg) {
152  // Found the end of the desired template arg.
153  result = template_instance.substr(arg_start, pos - arg_start);
154  return result;
155  }
156  ++comma_count;
157  if (comma_count == desired_arg) {
158  // Found the begin of the desired template arg.
159  arg_start = pos + 1;
160  }
161  break;
162  }
163  ++pos;
164  pos = template_instance.find_first_of("<>,", pos);
165  }
166  return result;
167  }
168 
169  string
170  name_of_assns_partner(string assns_type_name)
171  {
172  string result;
173  if (!is_assns(assns_type_name)) {
174  return result;
175  }
176  static string const assns_start = "art::Assns<"s;
177  auto const arg0 = name_of_template_arg(assns_type_name, 0);
178  auto const arg1 = name_of_template_arg(assns_type_name, 1);
179  auto const arg2 = name_of_template_arg(assns_type_name, 2);
180  result = assns_start + arg1 + ',' + arg0 + ',' + arg2 + '>';
181  return result;
182  }
183 
184  string
185  name_of_assns_base(string assns_type_name)
186  {
187  string result;
188  if (!is_assns(assns_type_name)) {
189  return result;
190  }
191  using namespace std::string_literals;
192  static string const assns_start = "art::Assns<"s;
193  if (name_of_template_arg(assns_type_name, 2) == "void"s) {
194  // Doesn't have the base we're looking for.
195  return result;
196  }
197  result = assns_start + name_of_template_arg(assns_type_name, 0) + ',' +
198  name_of_template_arg(assns_type_name, 1) + ",void>";
199  return result;
200  }
201 
202  string
203  name_of_unwrapped_product(string const& wrapped_name)
204  {
205  using namespace std::string_literals;
206  if (!is_instantiation_of(wrapped_name, "art::Wrapper"s)) {
207  throw Exception(errors::LogicError, "Can't unwrap"s)
208  << "-- attempted to get unwrapped product from non-instance of art::Wrapper."s;
209  }
210  return name_of_template_arg(wrapped_name, 0);
211  }
212 
213 } // namespace art
static QCString name
Definition: declinfo.cpp:673
QList< Entry > entry
static QCString result
STL namespace.
static QCString className
Definition: declinfo.cpp:669
string name_of_assns_partner(string assns_type_name)
Definition: TypeID.cc:170
int find(const type *d) const
Definition: qlist.h:88
ostream & operator<<(ostream &os, TypeID const &tid)
Definition: TypeID.cc:111
string name_of_unwrapped_product(string const &wrapped_name)
Definition: TypeID.cc:203
QCollection::Item first()
Definition: qglist.cpp:807
void print(std::ostream &) const
Definition: TypeID.cc:87
bool operator<(ProductInfo const &a, ProductInfo const &b)
Definition: ProductInfo.cc:51
std::string uniform_type_name(std::type_info const &tid)
const double a
string name_of_assns_base(string assns_type_name)
Definition: TypeID.cc:185
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:118
std::string friendlyName(std::string const &iFullName)
void swap(TypeID &)
Definition: TypeID.cc:81
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
bool operator!=(TypeID const &a, TypeID const &b)
Definition: TypeID.cc:99
bool operator>(TypeID const &a, TypeID const &b)
Definition: TypeID.cc:93
void swap(TypeID &left, TypeID &right)
Definition: TypeID.cc:105
static bool * b
Definition: config.cpp:1043
int bool
Definition: qglobal.h:345
static QCString * s
Definition: config.cpp:1042
bool is_assns(std::string const &type_name)
Definition: TypeID.h:66
std::type_info const * ti_
Definition: TypeID.h:45
bool operator==(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept