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