CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ReflexTools.cc
Go to the documentation of this file.
4 
5 #include "Api.h" // for G__ClassInfo
6 #include "Reflex/Base.h"
7 #include "Reflex/Member.h"
8 #include "Reflex/TypeTemplate.h"
9 
10 #include "TROOT.h"
11 
12 #include "boost/algorithm/string.hpp"
13 #include "boost/thread/tss.hpp"
14 
15 #include <algorithm>
16 #include <sstream>
17 
18 using Reflex::Base;
19 using Reflex::FINAL;
20 using Reflex::Member;
21 using Reflex::Object;
22 using Reflex::SCOPED;
23 using Reflex::Type;
24 using Reflex::TypeTemplate;
25 using Reflex::Type_Iterator;
26 
27 namespace edm {
28 
31 
33  while(t.IsTypedef()) t = t.ToType();
34  return t;
35  }
36 
37  bool
38  find_nested_type_named(std::string const& nested_type,
39  Type const& type_to_search,
40  Type& found_type) {
41  // Look for a sub-type named 'nested_type'
42  for(Type_Iterator
43  i = type_to_search.SubType_Begin(),
44  e = type_to_search.SubType_End();
45  i != e;
46  ++i) {
47  if(i->Name() == nested_type) {
48  found_type = get_final_type(*i);
49  return true;
50  }
51  }
52  return false;
53  }
54 
55  bool
56  is_RefVector(Reflex::Type const& possible_ref_vector,
58 
59  static TypeTemplate ref_vector_template_id(TypeTemplate::ByName("edm::RefVector", 3));
60  static std::string member_type("member_type");
61  TypeTemplate primary_template_id(possible_ref_vector.TemplateFamily());
62  if(primary_template_id == ref_vector_template_id) {
63  return find_nested_type_named(member_type, possible_ref_vector, value_type);
64  }
65  return false;
66  }
67 
68  bool
69  is_PtrVector(Reflex::Type const& possible_ref_vector,
71 
72  static TypeTemplate ref_vector_template_id(TypeTemplate::ByName("edm::PtrVector", 1));
73  static std::string member_type("member_type");
74  static std::string val_type("value_type");
75  TypeTemplate primary_template_id(possible_ref_vector.TemplateFamily());
76  if(primary_template_id == ref_vector_template_id) {
77  Reflex::Type ptrType;
78  if(find_nested_type_named(val_type, possible_ref_vector, ptrType)) {
79  return find_nested_type_named(val_type, ptrType, value_type);
80  }
81  }
82  return false;
83  }
84 
85  bool
86  is_RefToBaseVector(Reflex::Type const& possible_ref_vector,
88 
89  static TypeTemplate ref_vector_template_id(TypeTemplate::ByName("edm::RefToBaseVector", 1));
90  static std::string member_type("member_type");
91  TypeTemplate primary_template_id(possible_ref_vector.TemplateFamily());
92  if(primary_template_id == ref_vector_template_id) {
93  return find_nested_type_named(member_type, possible_ref_vector, value_type);
94  }
95  return false;
96  }
97 
98  namespace {
99 
100  int const oneParamArraySize = 6;
101  std::string const oneParam[oneParamArraySize] = {
102  "vector",
103  "basic_string",
104  "set",
105  "list",
106  "deque",
107  "multiset"
108  };
109  int const twoParamArraySize = 3;
110  std::string const twoParam[twoParamArraySize] = {
111  "map",
112  "pair",
113  "multimap"
114  };
115 
116 
117  bool
118  hasCintDictionary(std::string const& name) {
119  std::auto_ptr<G__ClassInfo> ci(new G__ClassInfo(name.c_str()));
120  return(ci.get() && ci->IsLoaded());
121  }
122 
123  // Checks if there is a Reflex dictionary for the Type t.
124  // If noComponents is false, checks members and base classes recursively.
125  // If noComponents is true, checks Type t only.
126  void
127  checkType(Type t, bool noComponents = false) {
128 
129  // ToType strips const, volatile, array, pointer, reference, etc.,
130  // and also translates typedefs.
131  // To be safe, we do this recursively until we either get a null type
132  // or the same type.
133  Type null;
134  for(Type x = t.ToType(); x != null && x != t; t = x, x = t.ToType()) {}
135 
136  std::string name = t.Name(SCOPED);
137  boost::trim(name);
138 
139  if(foundTypes().end() != foundTypes().find(name) || missingTypes().end() != missingTypes().find(name)) {
140  // Already been processed. Prevents infinite loop.
141  return;
142  }
143 
144  if(name.empty() || t.IsFundamental() || t.IsEnum()) {
145  foundTypes().insert(name);
146  return;
147  }
148 
149  if(!bool(t)) {
150  if(hasCintDictionary(name)) {
151  foundTypes().insert(name);
152  } else {
153  missingTypes().insert(name);
154  }
155  return;
156  }
157 
158  foundTypes().insert(name);
159  if(noComponents) return;
160 
161  if(name.find("std::") == 0) {
162  if(t.IsTemplateInstance()) {
163  std::string::size_type n = name.find('<');
164  int cnt = 0;
165  if(std::find(oneParam, oneParam + oneParamArraySize, name.substr(5, n - 5)) != oneParam + oneParamArraySize) {
166  cnt = 1;
167  } else if(std::find(twoParam, twoParam + twoParamArraySize, name.substr(5, n - 5)) != twoParam + twoParamArraySize) {
168  cnt = 2;
169  }
170  for(int i = 0; i < cnt; ++i) {
171  checkType(t.TemplateArgumentAt(i));
172  }
173  }
174  } else {
175  int mcnt = t.DataMemberSize();
176  for(int i = 0; i < mcnt; ++i) {
177  Member m = t.DataMemberAt(i);
178  if(m.IsTransient() || m.IsStatic()) continue;
179  checkType(m.TypeOf());
180  }
181  int cnt = t.BaseSize();
182  for(int i = 0; i < cnt; ++i) {
183  checkType(t.BaseAt(i).ToType());
184  }
185  }
186  }
187  } // end unnamed namespace
188 
190  return missingTypes_;
191  }
192 
194  // The only purpose of this cache is to stop infinite recursion.
195  // Reflex maintains its own internal cache.
196  return foundTypes_;
197  }
198 
199  void checkDictionaries(std::string const& name, bool noComponents) {
200  Type null;
201  Type t = Type::ByName(name);
202  if(t == null) {
203  missingTypes().insert(name);
204  return;
205  }
206  checkType(Type::ByName(name), noComponents);
207  }
208 
210  if(!missingTypes().empty()) {
211  std::ostringstream ostr;
212  for (StringSet::const_iterator it = missingTypes().begin(), itEnd = missingTypes().end();
213  it != itEnd; ++it) {
214  ostr << *it << "\n\n";
215  }
217  << "No REFLEX data dictionary found for the following classes:\n\n"
218  << ostr.str()
219  << "Most likely each dictionary was never generated,\n"
220  << "but it may be that it was generated in the wrong package.\n"
221  << "Please add (or move) the specification\n"
222  << "<class name=\"whatever\"/>\n"
223  << "to the appropriate classes_def.xml file.\n"
224  << "If the class is a template instance, you may need\n"
225  << "to define a dummy variable of this type in classes.h.\n"
226  << "Also, if this class has any transient members,\n"
227  << "you need to specify them in classes_def.xml.";
228  }
229  }
230 
232  while (!missingTypes().empty()) {
234  for (StringSet::const_iterator it = missing.begin(), itEnd = missing.end();
235  it != itEnd; ++it) {
236  try {
237  gROOT->GetClass(it->c_str(), kTRUE);
238  }
239  // We don't want to fail if we can't load a plug-in.
240  catch(...) {}
241  }
242  missingTypes().clear();
243  for (StringSet::const_iterator it = missing.begin(), itEnd = missing.end();
244  it != itEnd; ++it) {
245  checkDictionaries(*it);
246  }
247  if (missingTypes() == missing) {
248  break;
249  }
250  }
251  if (missingTypes().empty()) {
252  return;
253  }
255  }
256 
258  std::vector<Type>& baseTypes) {
259 
260  if(type.IsClass() || type.IsStruct()) {
261 
262  int nBase = type.BaseSize();
263  for(int i = 0; i < nBase; ++i) {
264 
265  Base base = type.BaseAt(i);
266  if(base.IsPublic()) {
267 
268  Type baseType = type.BaseAt(i).ToType();
269  if(bool(baseType)) {
270 
271  while(baseType.IsTypedef() == true) {
272  baseType = baseType.ToType();
273  }
274 
275  // Check to make sure this base appears only once in the
276  // inheritance heirarchy.
277  if(!search_all(baseTypes, baseType)) {
278  // Save the type and recursive look for its base types
279  baseTypes.push_back(baseType);
280  public_base_classes(baseType, baseTypes);
281  }
282  // For now just ignore it if the class appears twice,
283  // After some more testing we may decide to uncomment the following
284  // exception.
285  /*
286  else {
287  throw Exception(errors::UnimplementedFeature)
288  << "DataFormats/Common/src/ReflexTools.cc in function public_base_classes.\n"
289  << "Encountered class that has a public base class that appears\n"
290  << "multiple times in its inheritance heirarchy.\n"
291  << "Please contact the EDM Framework group with details about\n"
292  << "this exception. It was our hope that this complicated situation\n"
293  << "would not occur. There are three possible solutions. 1. Change\n"
294  << "the class design so the public base class does not appear multiple\n"
295  << "times in the inheritance heirarchy. In many cases, this is a\n"
296  << "sign of bad design. 2. Modify the code that supports Views to\n"
297  << "ignore these base classes, but not supply support for creating a\n"
298  << "View of this base class. 3. Improve the View infrastructure to\n"
299  << "deal with this case. Class name of base class: " << baseType.Name() << "\n\n";
300  }
301  */
302  }
303  }
304  }
305  }
306  }
307 
308  void const*
310  Type const& dynamicType,
311  std::type_info const& toType) {
312  Object obj(dynamicType, raw);
313  return obj.CastObject(Type::ByTypeInfo(toType)).Address();
314  }
315 }
tuple base
Main Program
Definition: newFWLiteAna.py:92
type
Definition: HCALResponse.h:22
dictionary missing
Definition: combine.py:4
int i
Definition: DBlmapReader.cc:9
bool is_RefToBaseVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:86
bool is_PtrVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:69
void const * reflex_pointer_adjust(void *raw, Reflex::Type const &dynamicType, std::type_info const &toType)
void public_base_classes(Reflex::Type const &type, std::vector< Reflex::Type > &baseTypes)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
uint16_t size_type
StringSet & missingTypes()
Definition: ReflexTools.cc:189
std::set< std::string > StringSet
Definition: ReflexTools.h:22
void checkDictionaries(std::string const &name, bool noComponents=false)
Definition: ReflexTools.cc:199
#define end
Definition: vmac.h:38
StringSet & foundTypes()
Definition: ReflexTools.cc:193
Container::value_type value_type
void throwMissingDictionariesException()
Definition: ReflexTools.cc:209
bool find_nested_type_named(std::string const &nested_type, Reflex::Type const &type_to_search, Reflex::Type &found_type)
static StringSet foundTypes_
Definition: ReflexTools.cc:29
bool search_all(ForwardSequence const &s, Datum const &d)
Definition: Algorithms.h:46
void loadMissingDictionaries()
Definition: ReflexTools.cc:231
bool is_RefVector(Reflex::Type const &possible_ref_vector, Reflex::Type &value_type)
Definition: ReflexTools.cc:56
#define begin
Definition: vmac.h:31
Definition: DDAxes.h:10
Type get_final_type(Type t)
Definition: ReflexTools.cc:32
static StringSet missingTypes_
Definition: ReflexTools.cc:30