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