Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
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 <cstring>
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
27namespace JROOT {}
28namespace JPP { using namespace JROOT; }
29
30namespace 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 * Check if name is one of TObject own data members
136 * (fBits or fUniqueID, for Root <= 6.30.04 at least)
137 */
138 static inline bool is_tobject_member(const char* name)
139 {
140 TClass* o_class = TClass::GetClass<TObject>();
141 return o_class->GetListOfRealData()->FindObject(name) != nullptr;
142 }
143 /**
144 * Constructor.
145 *
146 * \param type data type
147 */
148 template<class JType_t>
150 dictionary(TDictionary::GetDictionary(typeid(JType_t))),
151 offset(0)
152 {}
153
154
155 /**
156 * Constructor.
157 *
158 * \param pd pointer to C++ data member
159 */
160 template<class JType_t, class JClass_t>
161 JRootClass(JType_t JClass_t::*pd) :
162 dictionary(TDictionary::GetDictionary(typeid(JType_t))),
163 offset((char*) &(((JClass_t*) NULL)->*pd) - (char*) NULL)
164 {}
165
166
167 /**
168 * Get dictionary.
169 *
170 * \return pointer to dictionary
171 */
172 TDictionary* getDictionary() const
173 {
174 return dictionary;
175 }
176
177
178 /**
179 * Get offset of this class with respect to parent class.
180 *
181 * \return offset
182 */
183 int getOffset() const
184 {
185 return offset;
186 }
187
188
189 /**
190 * Get class.
191 *
192 * \return pointer to class
193 */
194 TClass* getClass() const
195 {
196 return dynamic_cast<TClass*>(dictionary);
197 }
198
199
200 /**
201 * Get type name.
202 *
203 * \return type name
204 */
205 const char* getTypename() const
206 {
207 if (dictionary != NULL)
208 return dictionary->GetName();
209 else
210 return NULL;
211 }
212
213
214 /**
215 * Check validity of this class.
216 *
217 * \return true if valid class; else false
218 */
219 bool is_valid() const
220 {
221 return (this->getDictionary() != NULL && is_class(this->getTypename()));
222 }
223
224
225 /**
226 * Test equality of ROOT classes.
227 *
228 * \param object ROOT class
229 * \return true if both ROOT classes are same type; else false
230 */
231 bool equals(const JRootClass& object) const
232 {
233 return (this-> getTypename() != NULL &&
234 object.getTypename() != NULL &&
235 strcmp(this->getTypename(), object.getTypename()) == 0);
236 }
237
238
239 /**
240 * Find base class or data member with given name within current class.
241 *
242 * \param name name of base class or data member
243 * \param option case sensitivity
244 * \return ROOT class
245 */
246 JRootClass find(const char* const name, const bool option = true) const
247 {
248 if (name != NULL && strlen(name) != 0) {
249
250 if (strcmp(getTypename(), name) == 0) {
251 return *this;
252 }
253
254 if (this->getClass() != NULL) {
255
256 // check for data member
257
258 for (std::unique_ptr<TIterator> i(this->getClass()->GetListOfDataMembers(kFALSE)->MakeIterator()); const TDataMember* p = (const TDataMember*) i->Next(); ) {
259 if (( option && strcmp (p->GetName(), name) == 0) ||
260 (!option && strcasecmp(p->GetName(), name) == 0)) {
261 return this->get(*p);
262 }
263 }
264
265 // check for base classes
266
267 for (std::unique_ptr<TIterator> i(this->getClass()->GetListOfBases()->MakeIterator()); TBaseClass* p = (TBaseClass*) i->Next(); ) {
268
269 if (is_class(*p) && !is_STLcontainer(*p)) {
270
271 JRootClass rcs = this->get(*p);
272
273 rcs = rcs.find(name);
274
275 if (rcs.is_valid()) {
276 return rcs;
277 }
278 }
279 }
280 }
281 }
282
283 return JRootClass(); // invalid value
284 }
285
286
287 /**
288 * Get ROOT class of given data member.
289 *
290 * \param data_member data member
291 * \return ROOT class
292 */
293 JRootClass get(const TDataMember& data_member) const
294 {
295 return JRootClass(TDictionary::GetDictionary(data_member.GetTypeName()),
296 this->getOffset() + data_member.GetOffset());
297 }
298
299
300 /**
301 * Get ROOT class of given base class
302 *
303 * \param base_class base class
304 * \return ROOT class
305 */
306 JRootClass get(const TBaseClass& base_class) const
307 {
308 return JRootClass(TDictionary::GetDictionary(base_class.GetName()),
309 this->getOffset() + const_cast<TBaseClass&>(base_class).GetDelta());
310 }
311
312
313 /**
314 * Print ROOT class information.
315 *
316 * \param out output stream
317 */
318 inline void print(std::ostream& out) const
319 {
320 print(out, getTypename());
321 }
322
323
324 protected:
325
326 TDictionary* dictionary; //!< pointer to ROOT dictionary
327 int offset; //!< offset with respect to data structure [B]
328
329
330 /**
331 * Default constructor.
332 */
334 dictionary(NULL),
335 offset(0)
336 {}
337
338
339 /**
340 * Constructor.
341 *
342 * \param dictionary pointer to dictionary
343 * \param offset offset
344 */
345 JRootClass(TDictionary* dictionary,
346 int offset) :
348 offset (offset)
349 {}
350
351
352 /**
353 * Print ROOT class information.
354 *
355 * \param out output stream
356 * \param prefix prefix
357 */
358 inline void print(std::ostream& out, const std::string& prefix) const
359 {
360 if (this->is_valid()) {
361
362 print(out, prefix, this->getTypename());
363
364 if (this->getClass() != NULL) {
365
366 if (this->getClass()->GetListOfBases() != NULL) {
367
368 for (std::unique_ptr<TIterator> i(this->getClass()->GetListOfBases()->MakeIterator()); const TBaseClass* p = (const TBaseClass*) i->Next(); ) {
369 if (!is_STLcontainer(*p))
370 this->get(*p).print(out, prefix + "::" + p->GetName());
371 else
372 print(out, prefix + "::" + p->GetName(), this->get(*p).getTypename());
373 }
374 }
375
376 if (this->getClass()->GetListOfDataMembers(kFALSE) != NULL) {
377
378 for (std::unique_ptr<TIterator> i(this->getClass()->GetListOfDataMembers(kFALSE)->MakeIterator()); const TDataMember* p = (const TDataMember*) i->Next(); ) {
379 if (!is_STLstring(*p) && !is_STLcontainer(*p))
380 this->get(*p).print(out, prefix + (is_static(*p) ? "::" : ".") + p->GetName());
381 else
382 print(out, prefix + (is_static(*p) ? "::" : ".") + p->GetName(), this->get(*p).getTypename());
383 }
384 }
385 }
386 }
387 }
388
389
390 /**
391 * Print ROOT class information.
392 *
393 * \param out output stream
394 * \param name name
395 * \param type type
396 */
397 inline static void print(std::ostream& out, const std::string& name, const std::string& type)
398 {
399 using namespace std;
400
401 out << name << " " << '(' << type << ')' << endl;
402 }
403 };
404
405
406 /**
407 * Simple address wrapper.
408 */
409 template<class JPointer_t>
410 struct JAddress
411 {
412 /**
413 * Type definition of address.
414 */
415 typedef JPointer_t pointer_type;
416
417 /**
418 * Constructor.
419 *
420 * \param p pointer to object
421 */
423 address(p)
424 {}
425
427 };
428
429
430 /**
431 * Auxiliary class to manage access to base classes and data members of ROOT class objects.
432 *
433 * This class augments the class JRootClass with addressing capabilities.
434 */
435 template<class JPointer_t>
437 public JRootClass,
438 public JAddress<JPointer_t>
439 {
442
443 /**
444 * Constructor.
445 *
446 * \param object template object
447 */
448 template<class T>
450 JRootClass(JType<T>()),
451 JAddress_t((pointer_type) &object)
452 {}
453
454
455 /**
456 * Get address.
457 *
458 * \return pointer to object
459 */
461 {
462 return this->address + getOffset();
463 }
464
465
466 /**
467 * Check validity of this addressable class.
468 *
469 * \return true if valid addressable class; else false
470 */
471 bool is_valid() const
472 {
473 return (JRootClass::is_valid() && this->address != NULL);
474 }
475
476
477 /**
478 * Find addressable base class or data member with given name within current class.
479 *
480 * \param name name of base class or data member
481 * \return ROOT addressable class
482 */
483 JRootAddressableClass find(const char* const name) const
484 {
486 }
487
488
489 /**
490 * Get addressable class of given data member.
491 *
492 * \param data_member data member
493 * \return ROOT addressable class
494 */
495 JRootAddressableClass get(const TDataMember& data_member) const
496 {
497 return JRootAddressableClass(JRootClass::get(data_member), this->address);
498 }
499
500
501 /**
502 * Get addressable class of given base class
503 *
504 * \param base_class base class
505 * \return ROOT addressable class
506 */
507 JRootAddressableClass get(const TBaseClass& base_class) const
508 {
509 return JRootAddressableClass(JRootClass::get(base_class), this->address);
510 }
511
512
513 /**
514 * Find addressable base class or data member with given name within current class.
515 *
516 * \param name name of base class or data member
517 * \return ROOT addressable class
518 */
519 JRootAddressableClass operator[](const char* const name) const
520 {
521 return this->find(name);
522 }
523
524
525 protected:
526 /**
527 * Constructor.
528 *
529 * \param rc ROOT class
530 * \param address address
531 */
536 };
537
538
539 /**
540 * ROOT class for reading object.
541 */
543 public JRootAddressableClass<char *>
544 {
545 /**
546 * Constructor.
547 *
548 * \param object template object
549 */
550 template<class T>
552 JRootAddressableClass<char *>(object)
553 {}
554
555
556 /**
557 * Copy constructor.
558 *
559 * \param rc ROOT addressable class
560 */
564
565
566 /**
567 * Type conversion operator.
568 *
569 * \return value
570 */
571 template<class T>
572 operator const T&() const
573 {
574 if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
575 return * (const T*) this->getAddress();
576 } else {
577 THROW(JCastException, "JRootReadableClass::operator const T&");
578 }
579 }
580
581
582 /**
583 * Type conversion operator.
584 *
585 * \return value
586 */
587 template<class T>
588 operator T&()
589 {
590 if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
591 return * (T*) this->getAddress();
592 } else {
593 THROW(JCastException, "JRootReadableClass::operator T&");
594 }
595 }
596 };
597
598
599 /**
600 * ROOT class for writing object.
601 */
603 public JRootAddressableClass<const char*>
604 {
605 /**
606 * Constructor.
607 *
608 * \param object template object
609 */
610 template<class T>
611 JRootWritableClass(const T& object) :
612 JRootAddressableClass<const char *>(object)
613 {}
614
615
616 /**
617 * Copy constructor.
618 *
619 * \param rc ROOT addressable class
620 */
624
625
626 /**
627 * Type conversion operator.
628 *
629 * \return value
630 */
631 template<class T>
632 operator const T&() const
633 {
634 if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
635 return * (const T*) this->getAddress();
636 } else {
637 THROW(JCastException, "JRootWritableClass::operator const T&");
638 }
639 }
640 };
641
642
643 /**
644 * Get ROOT data member for given parent and member class.
645 *
646 * \param parent ROOT class
647 * \param member ROOT class
648 * \return pointer to ROOT data member
649 */
650 inline const TDataMember* getDataMember(const JRootClass& parent,
651 const JRootClass& member)
652 {
653 if (parent.getClass() != NULL) {
654
655 for (std::unique_ptr<TIterator> i(parent.getClass()->GetListOfDataMembers(kFALSE)->MakeIterator()); const TDataMember* p = (const TDataMember*) i->Next(); ) {
656
657 const JRootClass abc = parent.get(*p);
658
659 if (abc == member && abc.getOffset() == member.getOffset()) {
660 return p;
661 }
662 }
663
664 for (std::unique_ptr<TIterator> i(parent.getClass()->GetListOfBases()->MakeIterator()); const TBaseClass* p = (const TBaseClass*) i->Next(); ) {
665
667
668 const TDataMember* q = getDataMember(parent.get(*p), member);
669
670 if (q != NULL) {
671 return q;
672 }
673 }
674 }
675 }
676
677 return NULL;
678 }
679
680
681 /**
682 * Get ROOT data member for given C++ data member.
683 *
684 * \param pd pointer to C++ data member
685 * \return pointer to ROOT data member
686 */
687 template<class JType_t, class JClass_t>
688 inline const TDataMember* getDataMember(JType_t JClass_t::*pd)
689 {
690 return getDataMember(JRootClass(getType<JClass_t>()), JRootClass(pd));
691 }
692
693
694 /**
695 * Get list of ROOT data members for given class.
696 */
697 template<class T>
699 {
701
702 TClass* rc = (TClass*) TDictionary::GetDictionary(typeid(T));
703
704 for (std::unique_ptr<TIterator> i(rc->GetListOfDataMembers(kFALSE)->MakeIterator()); TDataMember* p = (TDataMember*) i->Next(); ) {
705 if (JRootClass::is_class(p->GetName())) {
706 buffer.push_back(p);
707 }
708 }
709
710 return buffer;
711 }
712}
713
714#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Exception for cast operation.
JType< T > getType()
Get type.
Definition JType.hh:31
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
std::vector< TDataMember * > getListOfDataMembers()
Get list of ROOT data members for given class.
const TDataMember * getDataMember(const JRootClass &parent, const JRootClass &member)
Get ROOT data member for given parent and member class.
Template definition of auxiliary base class for comparison of data structures.
Definition JEquals.hh:84
Auxiliary class for a type holder.
Definition JType.hh:19
Simple address wrapper.
pointer_type address
JPointer_t pointer_type
Type definition of address.
JAddress(pointer_type p)
Constructor.
Auxiliary class to manage access to base classes and data members of ROOT class objects.
bool is_valid() const
Check validity of this addressable class.
JRootAddressableClass get(const TBaseClass &base_class) const
Get addressable class of given base class.
pointer_type getAddress() const
Get address.
JAddress_t::pointer_type pointer_type
JRootAddressableClass get(const TDataMember &data_member) const
Get addressable class of given data member.
JRootAddressableClass find(const char *const name) const
Find addressable base class or data member with given name within current class.
JRootAddressableClass operator[](const char *const name) const
Find addressable base class or data member with given name within current class.
JRootAddressableClass(const JRootClass &rc, pointer_type address)
Constructor.
JAddress< JPointer_t > JAddress_t
JRootAddressableClass(T &object)
Constructor.
Auxiliary class to manage access to base classes and data members of ROOT class.
Definition JRootClass.hh:43
static bool is_tobject_member(const char *name)
Check if name is one of TObject own data members (fBits or fUniqueID, for Root <= 6....
TDictionary * getDictionary() const
Get dictionary.
JRootClass(const JType< JType_t > &type)
Constructor.
void print(std::ostream &out) const
Print ROOT class information.
TDictionary * dictionary
pointer to ROOT dictionary
const char * getTypename() const
Get type name.
JRootClass get(const TBaseClass &base_class) const
Get ROOT class of given base class.
bool is_valid() const
Check validity of this class.
static bool is_STLcontainer(const TDataMember &data_member)
Check if data member is STL container.
JRootClass get(const TDataMember &data_member) const
Get ROOT class of given data member.
static bool is_STLcontainer(const TBaseClass &base_class)
Check if base class is STL container.
Definition JRootClass.hh:91
JRootClass(JType_t JClass_t::*pd)
Constructor.
JRootClass()
Default constructor.
static bool is_static(const TDataMember &data_member)
Check if data member is static.
TClass * getClass() const
Get class.
void print(std::ostream &out, const std::string &prefix) const
Print ROOT class information.
int getOffset() const
Get offset of this class with respect to parent class.
int offset
offset with respect to data structure [B]
JRootClass find(const char *const name, const bool option=true) const
Find base class or data member with given name within current class.
static bool is_STLstring(const TDataMember &data_member)
Check if data member is STL string.
static bool is_class(const TDataMember &data_member)
Check data member against ROOT class names.
Definition JRootClass.hh:79
static void print(std::ostream &out, const std::string &name, const std::string &type)
Print ROOT class information.
static bool is_class(const TBaseClass &base_class)
Check base class against ROOT class names.
Definition JRootClass.hh:67
JRootClass(TDictionary *dictionary, int offset)
Constructor.
static bool is_class(const char *const name)
Check name of class against ROOT classes.
Definition JRootClass.hh:50
bool equals(const JRootClass &object) const
Test equality of ROOT classes.
ROOT class for reading object.
JRootReadableClass(const JRootAddressableClass< char * > &rc)
Copy constructor.
JRootReadableClass(T &object)
Constructor.
ROOT class for writing object.
JRootWritableClass(const JRootAddressableClass< const char * > &rc)
Copy constructor.
JRootWritableClass(const T &object)
Constructor.