1#ifndef RestTools_REST_Reflection
2#define RestTools_REST_Reflection
20#include "TBufferFile.h"
22#include "TClassEdit.h"
23#include "TDataMember.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);
231EXTERN_DEF std::map<void*, TClass*> RESTListOfClasses_typeid;
232EXTERN_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;
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;
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;
406TRestReflector
Assembly(std::string typeName);
411TRestReflector
WrapType(std::string typeName);
418void CloneAny(TRestReflector from, 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;
431EXTERN_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.
void SetValue(const T &val)
Set the value of the wrapped type.
TRestReflector(T *obj)
Constructor to wrap an object pointer.
void ParseString(std::string str)
Set the value of the wrapped object from std::string.
void Assembly()
Assembly a new object, and save its address. The old object will be destroied if not null.
std::string ToString()
Convert the wrapped object to std::string.
TRestReflector()
Default constructor.
std::string GetDataMemberValueString(std::string name)
Get the value of datamember as std::string.
std::string type
Type of the wrapped object.
int size
Size of the object.
std::vector< std::string > GetListOfDataMembers()
Get a list of the class's datamembers as a std::vector of std::string, including those from base clas...
char * address
Address of the wrapped object.
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.
void operator>>(TRestReflector to)
Deep copy the content of the wrapped object to to.
int GetNumberOfDataMembers()
Get the number of data members of a class.
TRestReflector GetDataMember(std::string name)
Find the class's datamember as TRestReflector object, including those from base class.
std::string name
Name field.
void PrintMemory(int bytepreline=16)
Print the Hex memory std::map of the wrappered object.
void Destroy()
Destroy the current object. It will make the class to be zombie.
const std::type_info * typeinfo
value of typeid(T).name() of the wrapped object
bool IsZombie()
If this object type wrapper is invalid.
bool onheap
If on heap, we can call Destroy() to TRestReflector. True only when initialized from Assembly()
friend std::ostream & operator<<(std::ostream &cin, TRestReflector ptr)
Output overload by calling ToString();.
int InitDictionary()
Prepare the ROOT dictionary for this type.
A base class for any REST event process.
This namespace serves for the reflection functionality.
TRestReflector WrapType(std::string typeName)
Wrap information an object of type: typeName, memory is not allocated.
std::string GetTypeName()
Get the type name of an object.
TClass * GetClassQuick(std::string type)
void CloneAny(TRestReflector from, TRestReflector to)
Deep copy the content of object from to to
TRestReflector Assembly(std::string typeName)
Assembly an object of type: typeName, returning the allocated memory address and size.