Jpp 19.3.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JRootComparator.hh
Go to the documentation of this file.
1#ifndef __JROOT_COMPARATOR__
2#define __JROOT_COMPARATOR__
3
4#include <string>
5#include <memory>
6#include <map>
7
8#include "TString.h"
9#include "TDictionary.h"
10#include "TVirtualCollectionProxy.h"
11#include "TBaseClass.h"
12#include "TDataMember.h"
13
14#include "JLang/JTypeList.hh"
16
17#include "JROOT/JRootClass.hh"
18
19#include "Jeep/JMessage.hh"
20
21
22namespace JROOT {}
23namespace JPP { using namespace JROOT; }
24
25namespace JROOT {
26
27 using JLANG::JType;
28
29
30 /**
31 * Interface for comparison of a template class.
32 */
34 public:
35 /**
36 * Virtual destructor.
37 */
39 {}
40
41
42 /**
43 * Compare objects.
44 *
45 * \param first pointer to first object
46 * \param second pointer to second object
47 * \return true if objects are equal; else false
48 */
49 virtual bool equals(const void* first, const void* second) const = 0;
50 };
51
52
53 /**
54 * Implementation for comparison of a template class.
55 *
56 * This class implements the JROOT::JAstractComparator interface for the given template class using the operator <tt>==</tt>.
57 */
58 template<class T>
61 {
62 public:
63 /**
64 * Compare objects.
65 *
66 * \param first pointer to first object
67 * \param second pointer to second object
68 * \return true if objects are equal; else false
69 */
70 virtual bool equals(const void* first, const void* second) const override
71 {
72 return (* ((const T*) first) == * ((const T*) second));
73 }
74 };
75
76
77 /**
78 * ROOT comparator.
79 */
81 public std::map<std::string, std::shared_ptr<JAbstractComparator> >
82 {
83 public:
84 /**
85 * Default constructor.
86 */
88 {
89 using namespace JPP;
90
91 for_each<JRemove<JPrimitiveTypes_t, long double>::typelist>(*this);
92
93 (*this)(JType<std::string>());
94 (*this)(JType<std::size_t>());
95
96#define VALUE_TYPE(__TYPE__) value_type(#__TYPE__, new JObjectComparator<__TYPE__>())
97
98 this->insert(VALUE_TYPE(Char_t));
99 this->insert(VALUE_TYPE(UChar_t));
100 this->insert(VALUE_TYPE(Short_t));
101 this->insert(VALUE_TYPE(UShort_t));
102 this->insert(VALUE_TYPE(Int_t));
103 this->insert(VALUE_TYPE(UInt_t));
104 this->insert(VALUE_TYPE(Long_t));
105 this->insert(VALUE_TYPE(ULong_t));
106 this->insert(VALUE_TYPE(Long64_t));
107 this->insert(VALUE_TYPE(ULong64_t));
108 this->insert(VALUE_TYPE(Float_t));
109 this->insert(VALUE_TYPE(Double_t));
110 this->insert(VALUE_TYPE(TString));
111
112#undef VALUE_TYPE
113 }
114
115
116 /**
117 * Compare objects.
118 *
119 * \param first first object
120 * \param second second object
121 * \return true if objects are equal; else false
122 */
123 template<class T>
124 bool operator()(const T& first, const T& second) const
125 {
126 using namespace std;
127
128 DEBUG("compare: " << JRootWritableClass(first).getTypename() << ' ' << JRootWritableClass(second).getTypename() << endl << endl);
129
130 return this->compare(JRootWritableClass(first), JRootWritableClass(second));
131 }
132
133
134 /**
135 * Addition of class.
136 *
137 * \param type data type
138 */
139 template<class T>
140 void operator()(const JType<T>& type)
141 {
142 this->insert(value_type(JRoot::getTypename<T>(), new JObjectComparator<T>()));
143 }
144
145
146 int debug = 0; //!< debug level
147
148 protected:
149 /**
150 * Compare objects.
151 *
152 * \param first first object
153 * \param second second object
154 * \return true if objects are equal; else false
155 */
156 bool compare(const JRootWritableClass& first, const JRootWritableClass& second) const
157 {
158 using namespace std;
159
160 if (first .is_valid() &&
161 second.is_valid()) {
162
163 const_iterator i1 = this->find(first .getTypename());
164 const_iterator i2 = this->find(second.getTypename());
165
166 if (i1 != this->end() &&
167 i2 != this->end() &&
168 i1 == i2) {
169
170 if (!i1->second->equals(first.getAddress(), second.getAddress())) {
171 return false;
172 }
173
174 } else if (first .getClass() != NULL &&
175 second.getClass() != NULL) {
176
177 if (first .getClass()->GetCollectionType() != ROOT::ESTLType::kNotSTL && first .getClass()->GetCollectionProxy() != NULL &&
178 second.getClass()->GetCollectionType() != ROOT::ESTLType::kNotSTL && second.getClass()->GetCollectionProxy() != NULL) {
179
180 std::unique_ptr<TVirtualCollectionProxy> p1(first .getClass()->GetCollectionProxy()->Generate());
181 std::unique_ptr<TVirtualCollectionProxy> p2(second.getClass()->GetCollectionProxy()->Generate());
182
183 p1->PushProxy(const_cast<char*>(first .getAddress()));
184 p2->PushProxy(const_cast<char*>(second.getAddress()));
185
186 TDictionary* d1 = TDictionary::GetDictionary(p1->GetType() == EDataType::kNoType_t ? p1->GetValueClass()->GetName() : TDataType::GetTypeName(p1->GetType()));
187 TDictionary* d2 = TDictionary::GetDictionary(p2->GetType() == EDataType::kNoType_t ? p2->GetValueClass()->GetName() : TDataType::GetTypeName(p2->GetType()));
188
189 DEBUG("proxy: " << p1->GetCollectionClass()->GetName() << " " << d1->GetName() << "(" << p1->Size() << ");" << endl);
190 DEBUG("proxy: " << p2->GetCollectionClass()->GetName() << " " << d2->GetName() << "(" << p2->Size() << ");" << endl);
191
192 if (p1->Size() != p2->Size()) {
193 return false;
194 }
195
196 for (UInt_t i = 0; (i != p1->Size() &&
197 i != p2->Size()); ++i) {
198
199 DEBUG("index: " << d1->GetName() << "[" << i << "] " << endl);
200 //DEBUG("index: " << d2->GetName() << "[" << i << "] " << endl);
201
202 const JRootWritableClass w1(d1, (char*) p1->At(i));
203 const JRootWritableClass w2(d2, (char*) p2->At(i));
204
205 if (!this->compare(w1, w2)) {
206 return false;
207 }
208 }
209
210 } else {
211
212 if (first .getClass()->GetListOfBases() != NULL &&
213 second.getClass()->GetListOfBases() != NULL) {
214
215 std::unique_ptr<TIterator> i1(first .getClass()->GetListOfBases()->MakeIterator());
216 std::unique_ptr<TIterator> i2(second.getClass()->GetListOfBases()->MakeIterator());
217
218 for (const TBaseClass *p1, *p2; ((p1 = (const TBaseClass*) i1->Next()) != NULL &&
219 (p2 = (const TBaseClass*) i2->Next()) != NULL); ) {
220
221 if (JRoot::is_class(p1->GetName()) &&
222 JRoot::is_class(p2->GetName())) {
223
224 DEBUG("base: " << p1->GetName() << endl);
225 //DEBUG("base: " << p2->GetName() << endl);
226
227 if (!this->compare(first.get(*p1), second.get(*p2))) {
228 return false;
229 }
230 }
231 }
232 }
233
234 if (first .getClass()->GetListOfDataMembers() != NULL &&
235 second.getClass()->GetListOfDataMembers() != NULL) {
236
237 std::unique_ptr<TIterator> i1(first .getClass()->GetListOfDataMembers()->MakeIterator());
238 std::unique_ptr<TIterator> i2(second.getClass()->GetListOfDataMembers()->MakeIterator());
239
240 for (const TDataMember *p1, *p2; ((p1 = (const TDataMember*) i1->Next()) != NULL &&
241 (p2 = (const TDataMember*) i2->Next()) != NULL); ) {
242
243
244 if (JRoot::is_class(p1->GetName()) &&
245 JRoot::is_class(p2->GetName())) {
246
247 DEBUG("member: " << p1->GetTrueTypeName() << " " << p1->GetName() << ";" << endl);
248 //DEBUG("member: " << p2->GetTrueTypeName() << " " << p2->GetName() << ";" << endl);
249
250 if (!this->compare(first.get(*p1), second.get(*p2))) {
251 return false;
252 }
253 }
254 }
255 }
256 }
257 }
258 }
259
260 return true;
261 }
262 };
263}
264
265#endif
TPaveText * p1
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
Type list of primitive data types.
#define VALUE_TYPE(__TYPE__)
Interface for comparison of a template class.
virtual bool equals(const void *first, const void *second) const =0
Compare objects.
virtual ~JAbstractComparator()
Virtual destructor.
Implementation for comparison of a template class.
virtual bool equals(const void *first, const void *second) const override
Compare objects.
bool operator()(const T &first, const T &second) const
Compare objects.
bool compare(const JRootWritableClass &first, const JRootWritableClass &second) const
Compare objects.
void operator()(const JType< T > &type)
Addition of class.
JRootComparator()
Default constructor.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
Auxiliary class for a type holder.
Definition JType.hh:19
bool is_valid() const
Check validity of this addressable class.
pointer_type getAddress() const
Get address.
JRootAddressableClass get(const TDataMember &object) const
Get addressable class of given data member.
const char * getTypename() const
Get type name.
TClass * getClass() const
Get class.
ROOT class for writing from object.
static bool is_class(const char *const name)
Check name of class against internal ROOT class names.
Definition JRoot.hh:30
static const char * getTypename()
Get ROOT typename for given template class.
Definition JRoot.hh:138