Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TViewPubDataMembers.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Philippe Canal October 2013
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TViewPubDataMembers
13 View implementing the TList interface and giving access all the
14 TDictionary describing public data members in a class and all its
15 base classes without caching any of the TDictionary pointers.
16 
17 Adding to this collection directly is prohibited.
18 Iteration can only be done via the TIterator interfaces.
19 */
20 
21 #include "TViewPubDataMembers.h"
22 
23 #include "TClass.h"
24 #include "TBaseClass.h"
25 #include "TError.h"
26 #include "TDictionary.h"
27 #include "THashList.h"
28 
29 // ClassImp(TViewPubDataMembers);
30 
31 ////////////////////////////////////////////////////////////////////////////////
32 /// loop over all base classes and add them to the container.
33 
34 static void AddBasesClasses(TList &bases, TClass *cl)
35 {
36  TIter nextBaseClass(cl->GetListOfBases());
37  TBaseClass *base;
38  while ((base = (TBaseClass*) nextBaseClass())) {
39  if (!base->GetClassPointer()) continue;
40  if (!(base->Property() & kIsPublic)) continue;
41 
42  bases.Add(base->GetClassPointer());
43  AddBasesClasses(bases,base->GetClassPointer());
44  }
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Usual constructor
49 
50 TViewPubDataMembers::TViewPubDataMembers(TClass *cl /* = 0 */)
51 {
52  if (cl) {
53  fClasses.Add(cl);
54  AddBasesClasses(fClasses,cl);
55  }
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Default destructor.
60 
61 TViewPubDataMembers::~TViewPubDataMembers()
62 {
63 }
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// Clear is not allowed in this class.
67 /// See TList::Clear for the intended behavior.
68 
69 void TViewPubDataMembers::Clear(Option_t * /* option="" */)
70 {
71  ::Error("TViewPubDataMembers::Clear","Operation not allowed on a view.");
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// Delete is not allowed in this class.
76 /// See TList::Delete for the intended behavior.
77 
78 void TViewPubDataMembers::Delete(Option_t * /*option="" */)
79 {
80  ::Error("TViewPubDataMembers::Delete","Operation not allowed on a view.");
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Find an object in this list using its name. Requires a sequential
85 /// scan till the object has been found. Returns 0 if object with specified
86 /// name is not found.
87 
88 TObject *TViewPubDataMembers::FindObject(const char * name) const
89 {
90  TIter next(&fClasses);
91  while (TClass *cl = (TClass*)next()) {
92  THashList *hl = dynamic_cast<THashList*>(cl->GetListOfDataMembers(kFALSE));
93  TIter content_next(hl->GetListForObject(name));
94  while (TDictionary *p = (TDictionary*) content_next()) {
95  // The 'ListForObject' is actually a hash table bucket that can also
96  // contain other element/name.
97  if (strcmp(name,p->GetName())==0 && (p->Property() & kIsPublic))
98  return p;
99  }
100  }
101  return 0;
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Find an object in this list using the object's IsEqual()
106 /// member function. Requires a sequential scan till the object has
107 /// been found. Returns 0 if object is not found.
108 
109 TObject *TViewPubDataMembers::FindObject(const TObject * obj) const
110 {
111  TIter next(&fClasses);
112  while (TClass *cl = (TClass*)next()) {
113  TObject *result = cl->GetListOfDataMembers(kFALSE)->FindObject(obj);
114  if (result) return result;
115  }
116  return 0;
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Return a list iterator.
121 
122 TIterator *TViewPubDataMembers::MakeIterator(Bool_t dir /* = kIterForward*/) const
123 {
124  return new TViewPubDataMembersIter(this, dir);
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// AddFirst is not allowed in this class.
129 /// See TList::AddFirst for the intended behavior.
130 
131 void TViewPubDataMembers::AddFirst(TObject * /* obj */)
132 {
133  ::Error("TViewPubDataMembers::AddFirst","Operation not allowed on a view.");
134 }
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// AddFirst is not allowed in this class.
138 /// See TList::AddFirst for the intended behavior.
139 
140 void TViewPubDataMembers::AddFirst(TObject * /* obj */, Option_t * /* opt */)
141 {
142  ::Error("TViewPubDataMembers::AddFirst","Operation not allowed on a view.");
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// AddLast is not allowed in this class.
147 /// See TList::AddLast for the intended behavior.
148 
149 void TViewPubDataMembers::AddLast(TObject * /* obj */)
150 {
151  ::Error("TViewPubDataMembers::AddLast","Operation not allowed on a view.");
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// AddLast is not allowed in this class.
156 /// See TList::AddLast for the intended behavior.
157 
158 void TViewPubDataMembers::AddLast(TObject * /* obj */, Option_t * /* opt */)
159 {
160  ::Error("TViewPubDataMembers::AddLast","Operation not allowed on a view.");
161 }
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// AddAt is not allowed in this class.
165 /// See TList::AddAt for the intended behavior.
166 
167 void TViewPubDataMembers::AddAt(TObject * /* obj */, Int_t /* idx */)
168 {
169  ::Error("TViewPubDataMembers::AddAt","Operation not allowed on a view.");
170 }
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// AddAfter is not allowed in this class.
174 /// See TList::AddAfter for the intended behavior.
175 
176 void TViewPubDataMembers::AddAfter(const TObject * /* after */, TObject * /* obj */)
177 {
178  ::Error("TViewPubDataMembers::RemAddLastove","Operation not allowed on a view.");
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// AddAfter is not allowed in this class.
183 /// See TList::AddAfter for the intended behavior.
184 
185 void TViewPubDataMembers::AddAfter(TObjLink * /* after */, TObject * /* obj */)
186 {
187  ::Error("TViewPubDataMembers::AddAfter","Operation not allowed on a view.");
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 /// AddBefore is not allowed in this class.
192 /// See TList::AddBefore for the intended behavior.
193 
194 void TViewPubDataMembers::AddBefore(const TObject * /* before */, TObject * /* obj */)
195 {
196  ::Error("TViewPubDataMembers::AddBefore","Operation not allowed on a view.");
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// AddBefore is not allowed in this class.
201 /// See TList::AddBefore for the intended behavior.
202 
203 void TViewPubDataMembers::AddBefore(TObjLink * /* before */, TObject * /* obj */)
204 {
205  ::Error("TViewPubDataMembers::AddBefore","Operation not allowed on a view.");
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// Returns the object at position idx. Returns 0 if idx is out of range.
210 
211 TObject *TViewPubDataMembers::At(Int_t idx) const
212 {
213  Int_t i = 0;
214  TIter next(&fClasses);
215  while (TClass *cl = (TClass*)next()) {
216  TIter content_next(cl->GetListOfDataMembers(kFALSE));
217  while (TDictionary *p = (TDictionary*) content_next()) {
218  if (p->Property() & kIsPublic) {
219  if (i == idx) return p;
220  ++i;
221  }
222  }
223  }
224  return 0;
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// After is not allowed in this class.
229 /// See TList::After for the intended behavior.
230 
231 TObject *TViewPubDataMembers::After(const TObject * /* obj */) const
232 {
233  ::Error("TViewPubDataMembers::After","Operation not allowed on a view.");
234  return 0;
235 }
236 
237 ////////////////////////////////////////////////////////////////////////////////
238 /// Before is not allowed in this class.
239 /// See TList::Before for the intended behavior.
240 
241 TObject *TViewPubDataMembers::Before(const TObject * /* obj */) const
242 {
243  ::Error("TViewPubDataMembers::Before","Operation not allowed on a view.");
244  return 0;
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// First is not allowed in this class.
249 /// See TList::First for the intended behavior.
250 
251 TObject *TViewPubDataMembers::First() const
252 {
253  ::Error("TViewPubDataMembers::First","Operation not allowed on a view.");
254  return 0;
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// FirstLink is not allowed in this class.
259 /// See TList::FirstLink for the intended behavior.
260 
261 TObjLink *TViewPubDataMembers::FirstLink() const
262 {
263  ::Error("TViewPubDataMembers::FirstLink","Operation not allowed on a view.");
264  return 0;
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// GetObjectRef is not allowed in this class.
269 /// See TList::GetObjectRef for the intended behavior.
270 
271 TObject **TViewPubDataMembers::GetObjectRef(const TObject * /* obj */) const
272 {
273  ::Error("TViewPubDataMembers::GetObjectRef","Operation not yet allowed on a view.");
274  return 0;
275 }
276 
277 ////////////////////////////////////////////////////////////////////////////////
278 /// Return the total number of public data members(currently loaded in the list
279 /// of DataMembers) in this class and all its base classes.
280 
281 Int_t TViewPubDataMembers::GetSize() const
282 {
283  Int_t size = 0;
284  TIter next(&fClasses);
285  while (TClass *cl = (TClass*)next()) {
286  TIter content_next(cl->GetListOfDataMembers(kFALSE));
287  while (TDictionary *p = (TDictionary*) content_next())
288  if (p->Property() & kIsPublic) ++size;
289  }
290  return size;
291 
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// Load all the DataMembers known to the interpreter for the scope 'fClass'
296 /// and all its bases classes.
297 
298 void TViewPubDataMembers::Load()
299 {
300  TIter next(&fClasses);
301  while (TClass *cl = (TClass*)next()) {
302  cl->GetListOfDataMembers(kTRUE);
303  }
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Last is not allowed in this class.
308 /// See TList::Last for the intended behavior.
309 
310 TObject *TViewPubDataMembers::Last() const
311 {
312  ::Error("TViewPubDataMembers::Last","Operation not allowed on a view.");
313  return 0;
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// LastLink is not allowed in this class.
318 /// See TList::LastLink for the intended behavior.
319 
320 TObjLink *TViewPubDataMembers::LastLink() const
321 {
322  ::Error("TViewPubDataMembers::LastLink","Operation not allowed on a view.");
323  return 0;
324 }
325 
326 ////////////////////////////////////////////////////////////////////////////////
327 /// RecursiveRemove is not allowed in this class.
328 /// See TList::RecursiveRemove for the intended behavior.
329 
330 void TViewPubDataMembers::RecursiveRemove(TObject * /* obj */)
331 {
332  ::Error("TViewPubDataMembers::RecursiveRemove","Operation not allowed on a view.");
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// Remove is not allowed in this class.
337 /// See TList::Remove for the intended behavior.
338 
339 TObject *TViewPubDataMembers::Remove(TObject * /* obj */)
340 {
341  ::Error("TViewPubDataMembers::Remove","Operation not allowed on a view.");
342  return 0;
343 }
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// Remove is not allowed in this class.
347 /// See TList::Remove for the intended behavior.
348 
349 TObject *TViewPubDataMembers::Remove(TObjLink * /* lnk */)
350 {
351  ::Error("TViewPubDataMembers::Remove","Operation not allowed on a view.");
352  return 0;
353 }
354 
355 /** \class TViewPubDataMembersIter
356 Iterator of over the view's content.
357 */
358 
359 // ClassImp(TViewPubDataMembersIter);
360 
361 ////////////////////////////////////////////////////////////////////////////////
362 /// Create a new list iterator. By default the iteration direction
363 /// is kIterForward. To go backward use kIterBackward.
364 
365 TViewPubDataMembersIter::TViewPubDataMembersIter(const TViewPubDataMembers *l, Bool_t dir)
366 : fView(l),fClassIter(l->GetListOfClasses(),dir), fIter((TCollection *)0),
367 fStarted(kFALSE), fDirection(dir)
368 {
369 }
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Copy ctor.
373 
374 TViewPubDataMembersIter::TViewPubDataMembersIter(const TViewPubDataMembersIter &iter) :
375 TIterator(iter), fView(iter.fView),
376 fClassIter(iter.fClassIter), fIter(iter.fIter),
377 fStarted(iter.fStarted), fDirection(iter.fDirection)
378 {
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////////
382 /// Overridden assignment operator.
383 
384 TIterator &TViewPubDataMembersIter::operator=(const TIterator &rhs)
385 {
386  const TViewPubDataMembersIter *iter = dynamic_cast<const TViewPubDataMembersIter*>(&rhs);
387  if (this != &rhs && iter) {
388  fView = iter->fView;
389  fClassIter = iter->fClassIter;
390  fIter = iter->fIter;
391  fStarted = iter->fStarted;
392  fDirection = iter->fDirection;
393  }
394  return *this;
395 }
396 
397 ////////////////////////////////////////////////////////////////////////////////
398 /// Overloaded assignment operator.
399 
400 TViewPubDataMembersIter &TViewPubDataMembersIter::operator=(const TViewPubDataMembersIter &rhs)
401 {
402  if (this != &rhs) {
403  fView = rhs.fView;
404  fClassIter = rhs.fClassIter;
405  fIter = rhs.fIter;
406  fStarted = rhs.fStarted;
407  fDirection = rhs.fDirection;
408  }
409  return *this;
410 }
411 
412 ////////////////////////////////////////////////////////////////////////////////
413 /// Return next object in the list. Returns 0 when no more objects in list.
414 
415 TObject *TViewPubDataMembersIter::Next()
416 {
417  if (!fView) return 0;
418 
419  if (!fStarted) {
420  TClass *current = (TClass*)fClassIter();
421  fStarted = kTRUE;
422  if (current) {
423  fIter.~TIter();
424  new (&(fIter)) TIter(current->GetListOfDataMembers(kFALSE),fDirection);
425  } else {
426  return 0;
427  }
428  }
429 
430  while (1) {
431 
432  TDictionary *obj = (TDictionary *)fIter();
433  if (!obj) {
434  // End of list of DataMembers, move to the next;
435  TClass *current = (TClass*)fClassIter();
436  if (current) {
437  fIter.~TIter();
438  new (&(fIter)) TIter(current->GetListOfDataMembers(kFALSE),fDirection);
439  continue;
440  } else {
441  return 0;
442  }
443  } else if (obj->Property() & kIsPublic) {
444  // If it is public we found the next one.
445  return obj;
446  }
447 
448  }
449  // Not reachable.
450  return 0;
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Reset list iterator.
455 
456 void TViewPubDataMembersIter::Reset()
457 {
458  fStarted = kFALSE;
459  fClassIter.Reset();
460 }
461 
462 ////////////////////////////////////////////////////////////////////////////////
463 /// This operator compares two TIterator objects.
464 
465 Bool_t TViewPubDataMembersIter::operator!=(const TIterator &aIter) const
466 {
467  const TViewPubDataMembersIter *iter = dynamic_cast<const TViewPubDataMembersIter*>(&aIter);
468  if (iter) {
469  return (fClassIter != iter->fClassIter || fIter != iter->fIter);
470  }
471  return false; // for base class we don't implement a comparison
472 }
473 
474 ////////////////////////////////////////////////////////////////////////////////
475 /// This operator compares two TViewPubDataMembersIter objects.
476 
477 Bool_t TViewPubDataMembersIter::operator!=(const TViewPubDataMembersIter &aIter) const
478 {
479  return (fClassIter != aIter.fClassIter || fIter != aIter.fIter);
480 }
481