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