Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JRootClass.hh
Go to the documentation of this file.
1 #ifndef __JROOT__JROOTCLASS__
2 #define __JROOT__JROOTCLASS__
3 
4 #include <string>
5 #include <ostream>
6 #include <string.h>
7 #include <typeinfo>
8 
9 #include <TDictionary.h>
10 #include <TClass.h>
11 #include <TDataMember.h>
12 #include <TBaseClass.h>
13 #include <TIterator.h>
14 #include <TList.h>
15 
16 #include "JLang/JType.hh"
17 #include "JLang/JAddress.hh"
18 #include "JLang/JException.hh"
19 
20 
21 /**
22  * \author mdejong
23  */
24 
25 namespace JROOT {}
26 namespace JPP { using namespace JROOT; }
27 
28 namespace JROOT {
29 
30  using JLANG::JType;
31  using JLANG::JAddress;
33 
34 
35  /**
36  * Auxiliary class to manage access to base classes and data members of ROOT class.
37  */
38  struct JRootClass {
39  /**
40  * Check class name against ROOT class names.
41  *
42  * \param class_name class name
43  * \return true if valid class name; else false
44  */
45  static inline bool is_class(const char* const class_name)
46  {
47  return (class_name != NULL &&
48  strcmp(class_name, TClass ::Class()->GetName()) != 0 &&
49  strcmp(class_name, TObject::Class()->GetName()) != 0 &&
50  strcmp(class_name, "fgIsA") != 0 &&
51  strcmp(class_name, "atomic<TClass*>") != 0);
52  }
53 
54 
55  /**
56  * Check base class against ROOT class names.
57  *
58  * \param base_class base class
59  * \return true if valid class name; else false
60  */
61  static inline bool is_class(const TBaseClass& base_class)
62  {
63  return is_class(base_class.GetName());
64  }
65 
66 
67  /**
68  * Check data member against ROOT class names.
69  *
70  * \param data_member data member
71  * \return true if valid class name; else false
72  */
73  static inline bool is_class(const TDataMember& data_member)
74  {
75  return is_class(data_member.GetTypeName());
76  }
77 
78 
79  /**
80  * Check if base class is STL container.
81  *
82  * \param base_class base class
83  * \return true if STL congtainer; else false
84  */
85  static inline bool is_STLcontainer(const TBaseClass& base_class)
86  {
87  return (const_cast<TBaseClass&>(base_class).IsSTLContainer() != ROOT::kNotSTL);
88  }
89 
90 
91  /**
92  * Check if data member is STL container.
93  *
94  * \param data_member data member
95  * \return true if STL congtainer; else false
96  */
97  static inline bool is_STLcontainer(const TDataMember& data_member)
98  {
99  return (const_cast<TDataMember&>(data_member).IsSTLContainer() != ROOT::kNotSTL);
100  }
101 
102 
103  /**
104  * Check if data member is STL string.
105  *
106  * \param data_member data member
107  * \return true if STL string; else false
108  */
109  static inline bool is_STLstring(const TDataMember& data_member)
110  {
111  return (strcmp(data_member.GetFullTypeName(), "string") == 0 ||
112  strcmp(data_member.GetFullTypeName(), "const string") == 0);
113  }
114 
115 
116  /**
117  * Check if data member is static.
118  *
119  * \param data_member data member
120  * \return true if static; else false
121  */
122  static inline bool is_static(const TDataMember& data_member)
123  {
124  return (data_member.Property() & kIsStatic);
125  }
126 
127 
128  /**
129  * Constructor.
130  *
131  * \param type data type
132  */
133  template<class T>
134  JRootClass(const JType<T>& type) :
135  dictionary(TDictionary::GetDictionary(typeid(T))),
136  offset(0)
137  {}
138 
139 
140  /**
141  * Get dictionary.
142  *
143  * \return pointer to dictionary
144  */
145  TDictionary* getDictionary() const
146  {
147  return dictionary;
148  }
149 
150 
151  /**
152  * Get offset of this class with respect to parent class.
153  *
154  * \return offset
155  */
156  int getOffset() const
157  {
158  return offset;
159  }
160 
161 
162  /**
163  * Get class.
164  *
165  * \return pointer to class
166  */
167  TClass* getClass() const
168  {
169  return dynamic_cast<TClass*>(dictionary);
170  }
171 
172 
173  /**
174  * Get type name.
175  *
176  * \return type name
177  */
178  const char* getTypename() const
179  {
180  if (dictionary != NULL)
181  return dictionary->GetName();
182  else
183  return NULL;
184  }
185 
186 
187  /**
188  * Check validity of this class.
189  *
190  * \return true if valid class; else false
191  */
192  bool is_valid() const
193  {
194  return (this->getDictionary() != NULL && is_class(this->getTypename()));
195  }
196 
197 
198  /**
199  * Test equality of ROOT classes.
200  *
201  * \param first first ROOT class
202  * \param second second ROOT class
203  * \return true if both ROOT classes are same type; else false
204  */
205  friend inline bool operator==(const JRootClass& first,
206  const JRootClass& second)
207  {
208  return (first .getTypename() != NULL &&
209  second.getTypename() != NULL &&
210  strcmp(first.getTypename(), second.getTypename()) == 0);
211  }
212 
213 
214  /**
215  * Find base class or data member with given name within current class.
216  *
217  * \param name name of base class or data member
218  */
219  JRootClass find(const char* name) const
220  {
221  if (name != NULL && strlen(name) != 0) {
222 
223  if (strcmp(getTypename(), name) == 0) {
224  return *this;
225  }
226 
227  if (this->getClass() != NULL) {
228 
229  // check for data member
230 
231  const TDataMember* p = this->getClass()->GetDataMember(name);
232 
233  if (p != NULL) {
234  return this->get(*p);
235  }
236 
237  // check for base classes
238 
239  TIterator* i = this->getClass()->GetListOfBases()->MakeIterator();
240 
241  for (TBaseClass* p; (p = (TBaseClass*) i->Next()) != NULL; ) {
242 
243  if (is_class(*p) && !is_STLcontainer(*p)) {
244 
245  JRootClass cls = this->get(*p);
246 
247  cls = cls.find(name);
248 
249  if (cls.is_valid()) {
250  return cls;
251  }
252  }
253  }
254  }
255  }
256 
257  return JRootClass(); // invalid value
258  }
259 
260 
261  /**
262  * Get ROOT class of given data member.
263  *
264  * \param data_member data member
265  */
266  JRootClass get(const TDataMember& data_member) const
267  {
268  return JRootClass(TDictionary::GetDictionary(data_member.GetTypeName()),
269  this->getOffset() + data_member.GetOffset());
270  }
271 
272 
273  /**
274  * Get ROOT class of given base class
275  *
276  * \param base_class base class
277  */
278  JRootClass get(const TBaseClass& base_class) const
279  {
280  return JRootClass(TDictionary::GetDictionary(base_class.GetName()),
281  this->getOffset() + const_cast<TBaseClass&>(base_class).GetDelta());
282  }
283 
284 
285  /**
286  * Print ROOT class information.
287  *
288  * \param out output stream
289  */
290  inline void print(std::ostream& out) const
291  {
292  print(out, getTypename());
293  }
294 
295 
296  protected:
297 
298  TDictionary* dictionary; //!< pointer to ROOT dictionary
299  int offset; //!< offset with respect to data structure [B]
300 
301 
302  /**
303  * Default constructor.
304  */
306  dictionary(NULL),
307  offset(0)
308  {}
309 
310 
311  /**
312  * Constructor.
313  *
314  * \param dictionary pointer to dictionary
315  * \param offset offset
316  */
317  JRootClass(TDictionary* dictionary,
318  int offset) :
319  dictionary(dictionary),
320  offset (offset)
321  {}
322 
323 
324  /**
325  * Print ROOT class information.
326  *
327  * \param out output stream
328  * \param prefix prefix
329  */
330  inline void print(std::ostream& out, const std::string& prefix) const
331  {
332  if (this->is_valid()) {
333 
334  print(out, prefix, this->getTypename());
335 
336  if (this->getClass() != NULL) {
337 
338  if (this->getClass()->GetListOfBases() != NULL) {
339 
340  TIterator* i = this->getClass()->GetListOfBases()->MakeIterator();
341 
342  for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
343  if (!is_STLcontainer(*p))
344  this->get(*p).print(out, prefix + "::" + p->GetName());
345  else
346  print(out, prefix + "::" + p->GetName(), this->get(*p).getTypename());
347  }
348  }
349 
350  if (this->getClass()->GetListOfDataMembers() != NULL) {
351 
352  TIterator* i = this->getClass()->GetListOfDataMembers()->MakeIterator();
353 
354  for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
355  if (!is_STLstring(*p) && !is_STLcontainer(*p))
356  this->get(*p).print(out, prefix + (is_static(*p) ? "::" : ".") + p->GetName());
357  else
358  print(out, prefix + (is_static(*p) ? "::" : ".") + p->GetName(), this->get(*p).getTypename());
359  }
360  }
361  }
362  }
363  }
364 
365 
366  /**
367  * Print ROOT class information.
368  *
369  * \param out output stream
370  * \param name name
371  * \param type type
372  */
373  inline static void print(std::ostream& out, const std::string& name, const std::string& type)
374  {
375  using namespace std;
376 
377  out << name << " " << '(' << type << ')' << endl;
378  }
379  };
380 
381 
382  /**
383  * Auxiliary class to manage access to base classes and data members of ROOT class objects.
384  */
385  template<bool is_const>
387  public JRootClass,
388  public JAddress<is_const>
389  {
392 
393 
394  /**
395  * Constructor.
396  *
397  * \param object template object
398  */
399  template<class T>
401  JRootClass(JType<T>()),
402  JAddress_t((pointer_type) &object)
403  {}
404 
405 
406  /**
407  * Get address.
408  *
409  * \return pointer to object
410  */
412  {
413  return this->address + getOffset();
414  }
415 
416 
417  /**
418  * Check validity of this addressable class.
419  *
420  * \return true if valid addressable class; else false
421  */
422  bool is_valid() const
423  {
424  return (JRootClass::is_valid() && this->address != NULL);
425  }
426 
427 
428  /**
429  * Find addressable base class or data member with given name within current class.
430  *
431  * \param name name of base class or data member
432  */
433  JRootAddressableClass find(const char* name) const
434  {
435  return JRootAddressableClass(JRootClass::find(name), this->address);
436  }
437 
438 
439  /**
440  * Get addressable class of given data member.
441  *
442  * \param data_member data member
443  */
444  JRootAddressableClass get(const TDataMember& data_member) const
445  {
446  return JRootAddressableClass(JRootClass::get(data_member), this->address);
447  }
448 
449 
450  /**
451  * Get addressable class of given base class
452  *
453  * \param base_class base class
454  */
455  JRootAddressableClass get(const TBaseClass& base_class) const
456  {
457  return JRootAddressableClass(JRootClass::get(base_class), this->address);
458  }
459 
460 
461  protected:
462  /**
463  * Constructor.
464  *
465  * \param rcs ROOT class
466  * \param address address
467  */
469  JRootClass(rcs),
470  JAddress_t(address)
471  {}
472  };
473 
474 
475  /**
476  * ROOT class for reading object.
477  */
479  public JRootAddressableClass<false>
480  {
481  /**
482  * Constructor.
483  *
484  * \param object template object
485  */
486  template<class T>
487  JRootClassReader(T& object) :
488  JRootAddressableClass<false>(object)
489  {}
490 
491 
492  /**
493  * Copy constructor.
494  *
495  * \param rcs ROOT addressable class
496  */
498  JRootAddressableClass<false>(rcs)
499  {}
500 
501 
502  /**
503  * Type conversion operator.
504  *
505  * \return value
506  */
507  template<class T>
508  operator const T&() const
509  {
510  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
511  return * (const T*) this->getAddress();
512  } else {
513  THROW(JCastException, "JRootClassReader::operator const T&");
514  }
515  }
516 
517 
518  /**
519  * Type conversion operator.
520  *
521  * \return value
522  */
523  template<class T>
524  operator T&()
525  {
526  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
527  return * (T*) this->getAddress();
528  } else {
529  THROW(JCastException, "JRootClassReader::operator T&");
530  }
531  }
532 
533 
534  /**
535  * Assignment operator.
536  *
537  * \param value value
538  * \return this ROOT class reader
539  */
540  template<class T>
541  JRootClassReader& operator=(const T& value)
542  {
543  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
544  * (T*) this->getAddress() = value;
545  } else {
546  THROW(JCastException, "JRootClassReader::operator = " << value);
547  }
548 
549  return *this;
550  }
551 
552 
553  /**
554  * Get ROOT class reader with given name within current class.
555  *
556  * \param name name of base class or data member
557  */
558  JRootClassReader operator[](const char* name) const
559  {
560  return JRootClassReader(this->find(name));
561  }
562  };
563 
564 
565  /**
566  * ROOT class for writing object.
567  */
569  public JRootAddressableClass<true>
570  {
571  /**
572  * Constructor.
573  *
574  * \param object template object
575  */
576  template<class T>
577  JRootClassWriter(const T& object) :
578  JRootAddressableClass<true>(object)
579  {}
580 
581 
582  /**
583  * Copy constructor.
584  *
585  * \param rcs ROOT addressable class
586  */
588  JRootAddressableClass<true>(rcs)
589  {}
590 
591 
592  /**
593  * Type conversion operator.
594  *
595  * \return value
596  */
597  template<class T>
598  operator const T&() const
599  {
600  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
601  return * (const T*) this->getAddress();
602  } else {
603  THROW(JCastException, "JRootClassWriter::operator const T&");
604  }
605  }
606 
607 
608  /**
609  * Get ROOT class writer with given name within current class.
610  *
611  * \param name name of base class or data member
612  */
613  JRootClassWriter operator[](const char* name) const
614  {
615  return JRootClassWriter(this->find(name));
616  }
617  };
618 }
619 
620 #endif
void print(std::ostream &out, const std::string &prefix) const
Print ROOT class information.
Definition: JRootClass.hh:330
Exceptions.
int getOffset() const
Get offset of this class with respect to parent class.
Definition: JRootClass.hh:156
static bool is_STLcontainer(const TBaseClass &base_class)
Check if base class is STL container.
Definition: JRootClass.hh:85
void print(std::ostream &out) const
Print ROOT class information.
Definition: JRootClass.hh:290
static bool is_class(const char *const class_name)
Check class name against ROOT class names.
Definition: JRootClass.hh:45
JRootClassWriter(const T &object)
Constructor.
Definition: JRootClass.hh:577
const char * getTypename() const
Get type name.
Definition: JRootClass.hh:178
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:633
JRootClass()
Default constructor.
Definition: JRootClass.hh:305
pointer_type getAddress() const
Get address.
Definition: JRootClass.hh:411
JRootClassReader operator[](const char *name) const
Get ROOT class reader with given name within current class.
Definition: JRootClass.hh:558
JRootAddressableClass(T &object)
Constructor.
Definition: JRootClass.hh:400
JRootClass(const JType< T > &type)
Constructor.
Definition: JRootClass.hh:134
Auxiliary class for a type holder.
Definition: JType.hh:19
JAddress< is_const > JAddress_t
Definition: JRootClass.hh:390
JRootAddressableClass(const JRootClass &rcs, pointer_type address)
Constructor.
Definition: JRootClass.hh:468
static bool is_STLcontainer(const TDataMember &data_member)
Check if data member is STL container.
Definition: JRootClass.hh:97
Auxiliary class to manage access to base classes and data members of ROOT class objects.
Definition: JRootClass.hh:386
JRootClassReader & operator=(const T &value)
Assignment operator.
Definition: JRootClass.hh:541
bool is_valid() const
Check validity of this addressable class.
Definition: JRootClass.hh:422
JAddressTypedef< is_const >::pointer_type pointer_type
Type definition of address.
Definition: JAddress.hh:48
static bool is_STLstring(const TDataMember &data_member)
Check if data member is STL string.
Definition: JRootClass.hh:109
JRootClass get(const TDataMember &data_member) const
Get ROOT class of given data member.
Definition: JRootClass.hh:266
ROOT class for writing object.
Definition: JRootClass.hh:568
friend bool operator==(const JRootClass &first, const JRootClass &second)
Test equality of ROOT classes.
Definition: JRootClass.hh:205
TDictionary * getDictionary() const
Get dictionary.
Definition: JRootClass.hh:145
JRootClassReader(const JRootAddressableClass< false > &rcs)
Copy constructor.
Definition: JRootClass.hh:497
static bool is_class(const TBaseClass &base_class)
Check base class against ROOT class names.
Definition: JRootClass.hh:61
ROOT class for reading object.
Definition: JRootClass.hh:478
bool is_valid() const
Check validity of this class.
Definition: JRootClass.hh:192
Simple address wrapper for const and non-const pointers.
Definition: JAddress.hh:44
static void print(std::ostream &out, const std::string &name, const std::string &type)
Print ROOT class information.
Definition: JRootClass.hh:373
JRootClassWriter operator[](const char *name) const
Get ROOT class writer with given name within current class.
Definition: JRootClass.hh:613
Exception for cast operation.
Definition: JException.hh:216
JRootClassWriter(const JRootAddressableClass< true > &rcs)
Copy constructor.
Definition: JRootClass.hh:587
TDictionary * dictionary
pointer to ROOT dictionary
Definition: JRootClass.hh:298
static bool is_class(const TDataMember &data_member)
Check data member against ROOT class names.
Definition: JRootClass.hh:73
TClass * getClass() const
Get class.
Definition: JRootClass.hh:167
JRootClass(TDictionary *dictionary, int offset)
Constructor.
Definition: JRootClass.hh:317
JRootAddressableClass find(const char *name) const
Find addressable base class or data member with given name within current class.
Definition: JRootClass.hh:433
Auxiliary class to manage access to base classes and data members of ROOT class.
Definition: JRootClass.hh:38
JRootClass find(const char *name) const
Find base class or data member with given name within current class.
Definition: JRootClass.hh:219
int offset
offset with respect to data structure [B]
Definition: JRootClass.hh:299
JRootClassReader(T &object)
Constructor.
Definition: JRootClass.hh:487
static bool is_static(const TDataMember &data_member)
Check if data member is static.
Definition: JRootClass.hh:122
JAddress_t::pointer_type pointer_type
Definition: JRootClass.hh:391