1 #ifndef RestTools_REST_Reflection
2 #define RestTools_REST_Reflection
20 #include "TBufferFile.h"
22 #include "TClassEdit.h"
23 #include "TDataMember.h"
24 #include "TDataType.h"
25 #include "TRestStringHelper.h"
26 #include "TStreamerElement.h"
27 #include "TVirtualStreamerInfo.h"
35 char name[20]{
'u',
'n',
'k',
'n',
'o',
'w',
'n', 0};
37 const std::type_info* typeinfo = 0;
42 switch (ToHash(name)) {
44 typeinfo = &
typeid(char);
48 typeinfo = &
typeid(short);
52 typeinfo = &
typeid(int);
56 typeinfo = &
typeid(long);
59 case ToHash(
"long int"):
60 typeinfo = &
typeid(
long int);
61 size =
sizeof(
long int);
63 case ToHash(
"long long"):
64 typeinfo = &
typeid(
long long);
65 size =
sizeof(
long long);
68 typeinfo = &
typeid(bool);
72 typeinfo = &
typeid(float);
75 case ToHash(
"double"):
76 typeinfo = &
typeid(double);
77 size =
sizeof(double);
79 case ToHash(
"long double"):
80 typeinfo = &
typeid(
long double);
81 size =
sizeof(
long double);
83 case ToHash(
"unsigned char"):
84 typeinfo = &
typeid(
unsigned char);
85 size =
sizeof(
unsigned char);
87 case ToHash(
"unsigned short"):
88 typeinfo = &
typeid(
unsigned short);
89 size =
sizeof(
unsigned short);
91 case ToHash(
"unsigned int"):
92 typeinfo = &
typeid(
unsigned int);
93 size =
sizeof(
unsigned int);
95 case ToHash(
"unsigned long"):
96 typeinfo = &
typeid(
unsigned long);
97 size =
sizeof(
unsigned long);
99 case ToHash(
"unsigned long long"):
100 typeinfo = &
typeid(
unsigned long long);
101 size =
sizeof(
unsigned long long);
103 case ToHash(
"unsigned long int"):
104 typeinfo = &
typeid(
unsigned long int);
105 size =
sizeof(
unsigned long int);
107 case ToHash(
"char*"):
108 typeinfo = &
typeid(
char*);
109 size =
sizeof(
char*);
111 case ToHash(
"size_t"):
112 typeinfo = &
typeid(size_t);
113 size =
sizeof(
char*);
116 case ToHash(
"Char_t"):
117 typeinfo = &
typeid(Char_t);
118 size =
sizeof(Char_t);
120 case ToHash(
"UChar_t"):
121 typeinfo = &
typeid(UChar_t);
122 size =
sizeof(UChar_t);
124 case ToHash(
"Short_t"):
125 typeinfo = &
typeid(Short_t);
126 size =
sizeof(Short_t);
128 case ToHash(
"Int_t"):
129 typeinfo = &
typeid(Int_t);
130 size =
sizeof(Int_t);
132 case ToHash(
"UInt_t"):
133 typeinfo = &
typeid(UInt_t);
134 size =
sizeof(UInt_t);
136 case ToHash(
"Long_t"):
137 typeinfo = &
typeid(Long_t);
138 size =
sizeof(Long_t);
140 case ToHash(
"ULong_t"):
141 typeinfo = &
typeid(ULong_t);
142 size =
sizeof(ULong_t);
144 case ToHash(
"Long64_t"):
145 typeinfo = &
typeid(Long64_t);
146 size =
sizeof(Long64_t);
148 case ToHash(
"ULong64_t"):
149 typeinfo = &
typeid(ULong64_t);
150 size =
sizeof(ULong64_t);
152 case ToHash(
"Float_t"):
153 typeinfo = &
typeid(Float_t);
154 size =
sizeof(Float_t);
156 case ToHash(
"Float16_t"):
157 typeinfo = &
typeid(Float16_t);
158 size =
sizeof(Float16_t);
160 case ToHash(
"Double_t"):
161 typeinfo = &
typeid(Double_t);
162 size =
sizeof(Double_t);
164 case ToHash(
"Double32_t"):
165 typeinfo = &
typeid(Double32_t);
166 size =
sizeof(Double32_t);
168 case ToHash(
"LongDouble_t"):
169 typeinfo = &
typeid(LongDouble_t);
170 size =
sizeof(LongDouble_t);
172 case ToHash(
"Bool_t"):
173 typeinfo = &
typeid(Bool_t);
174 size =
sizeof(Bool_t);
180 strcpy(this->name, name.c_str());
184 template <
typename T>
186 std::string name =
"";
187 if (
typeid(T) ==
typeid(
char)) {
189 }
else if (
typeid(T) ==
typeid(
short)) {
191 }
else if (
typeid(T) ==
typeid(
int)) {
193 }
else if (
typeid(T) ==
typeid(
long)) {
195 }
else if (
typeid(T) ==
typeid(
long int)) {
197 }
else if (
typeid(T) ==
typeid(
long long)) {
199 }
else if (
typeid(T) ==
typeid(
bool)) {
201 }
else if (
typeid(T) ==
typeid(
float)) {
203 }
else if (
typeid(T) ==
typeid(
double)) {
205 }
else if (
typeid(T) ==
typeid(
long double)) {
206 name =
"long double";
207 }
else if (
typeid(T) ==
typeid(
unsigned char)) {
208 name =
"unsigned char";
209 }
else if (
typeid(T) ==
typeid(
unsigned short)) {
210 name =
"unsigned short";
211 }
else if (
typeid(T) ==
typeid(
unsigned int)) {
212 name =
"unsigned int";
213 }
else if (
typeid(T) ==
typeid(
unsigned long)) {
214 name =
"unsigned long";
215 }
else if (
typeid(T) ==
typeid(
unsigned long long)) {
216 name =
"unsigned long long";
217 }
else if (
typeid(T) ==
typeid(
unsigned long int)) {
218 name =
"unsigned long int";
219 }
else if (
typeid(T) ==
typeid(
char*)) {
224 strcpy(this->name, name.c_str());
226 typeinfo = &
typeid(T);
231 EXTERN_DEF std::map<void*, TClass*> RESTListOfClasses_typeid;
232 EXTERN_DEF std::map<std::string, TClass*> RESTListOfClasses_typename;
240 auto iter = RESTListOfClasses_typename.find(type);
241 if (iter != RESTListOfClasses_typename.end()) {
244 TClass* cl = TClass::GetClass(type.c_str());
245 RESTListOfClasses_typename[type] = cl;
257 template <
typename T>
259 void* typeidaddr = (
void*)&
typeid(T);
260 auto iter = RESTListOfClasses_typeid.find(typeidaddr);
261 if (iter != RESTListOfClasses_typeid.end()) {
264 TClass* cl = TClass::GetClass(
typeid(T));
265 RESTListOfClasses_typeid[typeidaddr] = cl;
272 template <
typename T>
274 TClass* cl = TClass::GetClass(
typeid(T));
276 return cl->GetName();
283 return GetTypeName<T>();
315 template <
typename T>
317 if (
typeid(T) != *this->typeinfo) {
318 std::cout <<
"In TRestReflector::GetValue() : type unmatch! " << std::endl;
319 std::cout <<
"Input: " << GetTypeName<T>() <<
", this: " << this->type << std::endl;
328 if (
typeid(T) != *this->typeinfo) {
329 std::cout <<
"In TRestReflector::SetValue() : type unmatch! " << std::endl;
330 std::cout <<
"Input: " << GetTypeName<T>() <<
", this: " << std::string(this->type) << std::endl;
371 InitFromTemplate<T>();
377 InitFromTemplate<T>();
381 void InitFromTemplate() {
383 cl = REST_Reflection::GetClassQuick<T>();
385 if (
cl ==
nullptr && dt.size == 0) {
386 std::cout <<
"In TRestReflector::TRestReflector() : unrecognized type! " << std::endl;
406 TRestReflector
Assembly(
const std::string& typeName);
411 TRestReflector
WrapType(
const std::string& typeName);
418 void CloneAny(
const TRestReflector& from,
const TRestReflector& to);
425 virtual std::string ToString(
void* obj) = 0;
426 virtual void ParseString(
void* obj, std::string str) = 0;
427 virtual void CloneObj(
void* from,
void* to) = 0;
431 EXTERN_DEF std::map<size_t, RESTVirtualConverter*> RESTConverterMethodBase;
436 std::string (*ToStringFunc)(T);
437 T (*ParseStringFunc)(std::string);
438 static Converter<T>* thisptr;
440 std::string ToString(
void* obj)
override {
return ToStringFunc(*(T*)obj); }
441 void ParseString(
void* obj, std::string str)
override {
442 T newobj = ParseStringFunc(str);
443 *((T*)(obj)) = newobj;
445 void CloneObj(
void* from,
void* to)
override { *((T*)(to)) = *((T*)(from)); }
447 Converter(std::string (*_ToStringFunc)(T), T (*_ParseStringFunc)(std::string)) {
448 ToStringFunc = _ToStringFunc;
449 ParseStringFunc = _ParseStringFunc;
450 if (RESTConverterMethodBase.count(
typeid(T).hash_code()) > 0) {
451 std::cout <<
"Warning! converter for type: " <<
typeid(T).name() <<
" already added!"
454 RESTConverterMethodBase[
typeid(T).hash_code()] =
this;
464 #define AddConverter(ToStringFunc, ParseStringFunc, type) \
466 Converter<type>* Converter<type>::thisptr = new Converter<type>(&ToStringFunc, &ParseStringFunc);
TRestReflector(const T &obj)
Constructor to wrap an object. Any typed object can be revieved as argument.
friend std::ostream & operator<<(std::ostream &cin, TRestReflector ptr)
Output overload by calling ToString();.
void SetValue(const T &val)
Set the value of the wrapped type.
std::string GetDataMemberValueString(const std::string &name)
Get the value of datamember as std::string.
TRestReflector(T *obj)
Constructor to wrap an object pointer.
void Assembly()
Assembly a new object, and save its address. The old object will be destroied if not null.
TRestReflector()
Default constructor.
std::string type
Type of the wrapped object.
int size
Size of the object.
void Destroy() const
Destroy the current object. It will make the class to be zombie.
char * address
Address of the wrapped object.
int GetNumberOfDataMembers() const
Get the number of data members of a class.
void operator>>(const TRestReflector &to)
Deep copy the content of the wrapped object to to.
TClass * cl
Pointer to the corresponding TClass helper, if the wrapped object is in class type.
bool is_data_type
Pointer to the corresponding TDataType helper, if the wrapped object is in data type.
T GetValue()
Get the value of the wrapped type, not recommended to use.
std::vector< std::string > GetListOfDataMembers() const
Get a list of the class's datamembers as a std::vector of std::string, including those from base clas...
bool IsZombie() const
If this object type wrapper is invalid.
std::string ToString() const
Convert the wrapped object to std::string.
std::string name
Name field.
void PrintMemory(int bytepreline=16)
Print the Hex memory std::map of the wrappered object.
const std::type_info * typeinfo
value of typeid(T).name() of the wrapped object
bool onheap
If on heap, we can call Destroy() to TRestReflector. True only when initialized from Assembly()
TRestReflector GetDataMember(const std::string &name)
Find the class's datamember as TRestReflector object, including those from base class.
void ParseString(const std::string &str) const
Set the value of the wrapped object from std::string.
int InitDictionary()
Prepare the ROOT dictionary for this type.
A base class for any REST event process.
This namespace serves for the reflection functionality.
std::string GetTypeName()
Get the type name of an object.
TClass * GetClassQuick(std::string type)
TRestReflector WrapType(const std::string &typeName)
Wrap information an object of type: typeName, memory is not allocated.
void CloneAny(const TRestReflector &from, const TRestReflector &to)
Deep copy the content of object from to to
TRestReflector Assembly(const std::string &typeName)
Assembly an object of type: typeName, returning the allocated memory address and size.