Logo ROOT   6.10/09
Reference Guide
TListOfEnums.cxx
Go to the documentation of this file.
1 // @(#)root/cont
2 // Author: Bianca-Cristina Cristescu February 2014
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, 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 TListOfEnums
13 A collection of TEnum objects designed for fast access given a
14 DeclId_t and for keep track of TEnum that were described
15 unloaded enum.
16 */
17 
18 #include <forward_list>
19 
20 #include "TListOfEnums.h"
21 #include "TClass.h"
22 #include "TExMap.h"
23 #include "TEnum.h"
24 #include "TGlobal.h"
25 #include "TInterpreter.h"
26 #include "TVirtualMutex.h"
27 
28 const unsigned int listSize=3;
29 
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 /// Constructor.
34 
36  THashList(listSize), fClass(cl), fIds(0), fUnloaded(0), fIsLoaded(kFALSE), fLastLoadMarker(0)
37 {
38  fIds = new TExMap(listSize);
39  fUnloaded = new THashList(listSize);
40 }
41 
42 ////////////////////////////////////////////////////////////////////////////////
43 /// Destructor.
44 
46 {
48  delete fIds;
49  fUnloaded->Delete();
50  delete fUnloaded;
51 }
52 
53 ////////////////////////////////////////////////////////////////////////////////
54 /// Add pair<id, object> to the map of functions and their ids.
55 
57 {
58  TEnum *e = dynamic_cast<TEnum *>(obj);
59  if (e && e->GetDeclId()) {
60  fIds->Add((Long64_t)e->GetDeclId(), (Long64_t)e);
61  }
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Add object at the beginning of the list.
66 
68 {
70  MapObject(obj);
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// Add object at the beginning of the list and also store option.
75 /// Storing an option is useful when one wants to change the behaviour
76 /// of an object a little without having to create a complete new
77 /// copy of the object. This feature is used, for example, by the Draw()
78 /// method. It allows the same object to be drawn in different ways.
79 
81 {
82  THashList::AddFirst(obj, opt);
83  MapObject(obj);
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Add object at the end of the list.
88 
90 {
91  THashList::AddLast(obj);
92  MapObject(obj);
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Add object at the end of the list and also store option.
97 /// Storing an option is useful when one wants to change the behaviour
98 /// of an object a little without having to create a complete new
99 /// copy of the object. This feature is used, for example, by the Draw()
100 /// method. It allows the same object to be drawn in different ways.
101 
103 {
104  THashList::AddLast(obj, opt);
105  MapObject(obj);
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Insert object at location idx in the list.
110 
112 {
113  THashList::AddAt(obj, idx);
114  MapObject(obj);
115 }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Insert object after object after in the list.
119 
120 void TListOfEnums::AddAfter(const TObject *after, TObject *obj)
121 {
122  THashList::AddAfter(after, obj);
123  MapObject(obj);
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Insert object after object after in the list.
128 
130 {
131  THashList::AddAfter(after, obj);
132  MapObject(obj);
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// Insert object before object before in the list.
137 
138 void TListOfEnums::AddBefore(const TObject *before, TObject *obj)
139 {
140  THashList::AddBefore(before, obj);
141  MapObject(obj);
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 /// Insert object before object before in the list.
146 
148 {
149  THashList::AddBefore(before, obj);
150  MapObject(obj);
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Remove all objects from the list. Does not delete the objects unless
155 /// the THashList is the owner (set via SetOwner()).
156 
158 {
159  fUnloaded->Clear(option);
160  fIds->Clear();
161  THashList::Clear(option);
162  fIsLoaded = kFALSE;
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// Delete all TDataMember object files.
167 
168 void TListOfEnums::Delete(Option_t *option /* ="" */)
169 {
170  fUnloaded->Delete(option);
171  THashList::Delete(option);
172  fIsLoaded = kFALSE;
173 }
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Return the TEnum corresponding to the Decl 'id' or NULL if it does not
177 /// exist.
178 
180 {
181  if (!id) return 0;
182 
183  return (TEnum *)fIds->GetValue((Long64_t)id);
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Return (after creating it if necessary) the TEnum
188 /// describing the enum corresponding to the Decl 'id'.
189 
191 {
192  if (!id) return 0;
193 
194  TEnum *e = Find(id);
195  if (e) return e;
196 
197  // If this declID is not found as key, we look for the enum by name.
198  // Indeed it could have been generated by protoclasses.
199 #if defined(R__MUST_REVISIT)
200 # if R__MUST_REVISIT(6,4)
201  "This special case can be removed once PCMs are available."
202 # endif
203 #endif
204  e = static_cast<TEnum*>(THashList::FindObject(name));
205  if (e) {
206  // In this case, we update the declId, update its constants and add the enum to the ids map and return.
207  // At this point it is like it came from the interpreter.
208  if (0 == e->GetDeclId()){
209  e->Update(id);
210  fIds->Add((Long64_t)id, (Long64_t)e);
211  gInterpreter->UpdateEnumConstants(e, fClass);
212  }
213  return e;
214  }
215 
216  if (fClass) {
218  // The interpreter does not know about this class yet (or a problem
219  // occurred that prevented the proper updating of fClassInfo).
220  // So this decl can not possibly be part of this class.
221  // [In addition calling GetClassInfo would trigger a late parsing
222  // of the header which we want to avoid].
223  return 0;
224  }
225  if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(), id)) return 0;
226  } else {
227  if (!gInterpreter->ClassInfo_Contains(0, id)) return 0;
228  }
229 
231 
232  // Let's see if this is a reload ...
233  // can we check for reloads for enums?
234  e = (TEnum *)fUnloaded->FindObject(name);
235  if (e) {
236  e->Update(id);
237  gInterpreter->UpdateEnumConstants(e, fClass);
238  } else {
239  e = gInterpreter->CreateEnum((void *)id, fClass);
240  }
241  // Calling 'just' THahList::Add would turn around and call
242  // TListOfEnums::AddLast which should *also* do the fIds->Add.
244  fIds->Add((Long64_t)id, (Long64_t)e);
245 
246  return e;
247 }
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 /// Return an object from the list of enums *if and only if* is has already
251 /// been loaded in the list. This is an internal routine.
252 
253 TEnum *TListOfEnums::GetObject(const char *name) const
254 {
255  return (TEnum*)THashList::FindObject(name);
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Remove a pair<id, object> from the map of functions and their ids.
260 
262 {
263  TEnum *e = dynamic_cast<TEnum *>(obj);
264  if (e) {
265  fIds->Remove((Long64_t)e->GetDeclId());
266  }
267 }
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// Remove object from this collection and recursively remove the object
271 /// from all other objects (and collections).
272 /// This function overrides TCollection::RecursiveRemove that calls
273 /// the Remove function. THashList::Remove cannot be called because
274 /// it uses the hash value of the hash table. This hash value
275 /// is not available anymore when RecursiveRemove is called from
276 /// the TObject destructor.
277 
279 {
280  if (!obj) return;
281 
284  UnmapObject(obj);
285 }
286 
287 ////////////////////////////////////////////////////////////////////////////////
288 /// Remove object from the list.
289 
291 {
292  Bool_t found;
293 
294  found = THashList::Remove(obj);
295  if (!found) {
296  found = fUnloaded->Remove(obj);
297  }
298  UnmapObject(obj);
299  if (found) return obj;
300  else return 0;
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Remove object via its objlink from the list.
305 
307 {
308  if (!lnk) return 0;
309 
310  TObject *obj = lnk->GetObject();
311 
312  THashList::Remove(lnk);
313  fUnloaded->Remove(obj);
314  UnmapObject(obj);
315  return obj;
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Load all the DataMembers known to the interpreter for the scope 'fClass'
320 /// into this collection.
321 
323 {
324  if (fClass && fClass->Property() & (kIsClass | kIsStruct | kIsUnion)) {
325  // Class and union are not extendable, if we already
326  // loaded all the data member there is no need to recheck
327  if (fIsLoaded) return;
328  }
329 
330  // This will provoke the parsing of the headers if need be.
331  if (fClass && fClass->GetClassInfo() == 0) return;
332 
334 
335  ULong64_t currentTransaction = gInterpreter->GetInterpreterStateMarker();
336  if (currentTransaction == fLastLoadMarker) {
337  return;
338  }
339  fLastLoadMarker = currentTransaction;
340 
341  // In the case of namespace, even if we have loaded before we need to
342  // load again in case there was new data member added.
343 
344  // Mark the list as loaded to avoid an infinite recursion in the case
345  // where we have a data member that is a variable size array. In that
346  // case TDataMember::Init needs to get/load the list to find the data
347  // member used as the array size.
348  fIsLoaded = kTRUE;
349 
350  // Respawn the unloaded enums if they come from protoclasses, i.e. they
351  // have a 0 declId.
352 #if defined(R__MUST_REVISIT)
353 # if R__MUST_REVISIT(6,4)
354  "This special case can be removed once PCMs are available."
355 # endif
356 #endif
357 
358  std::forward_list<TEnum*> respownedEnums;
359  for (auto enumAsObj : *fUnloaded){
360  TEnum* en = static_cast<TEnum*>(enumAsObj);
361  if (0 == en->GetDeclId()){
362  THashList::AddLast(en);
363  respownedEnums.push_front(en);
364  }
365  }
366 
367  for (auto en : respownedEnums)
368  fUnloaded->Remove(en);
369 
370  // We cannot clear the whole unloaded list. It is too much.
371 // fUnloaded->Clear();
372 
373  gInterpreter->LoadEnums(*this);
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Mark 'all func' as being unloaded.
378 /// After the unload, the data member can no longer be found directly,
379 /// until the decl can be found again in the interpreter (in which
380 /// the func object will be reused.
381 
383 {
384  TObjLink *lnk = FirstLink();
385  while (lnk) {
386  TEnum *data = (TEnum *)lnk->GetObject();
387 
388  if (data->GetDeclId())
389  fIds->Remove((Long64_t)data->GetDeclId());
390  fUnloaded->Add(data);
391 
392  lnk = lnk->Next();
393  }
394 
396  fIsLoaded = kFALSE;
397 }
398 
399 ////////////////////////////////////////////////////////////////////////////////
400 /// Mark enum 'e' as being unloaded.
401 /// After the unload, the data member can no longer be found directly,
402 /// until the decl can be found again in the interpreter (in which
403 /// the func object will be reused.
404 
406 {
407  if (THashList::Remove(e)) {
408  // We contains the object, let remove it from the other internal
409  // list and move it to the list of unloaded objects.
410  if (e->GetDeclId())
411  fIds->Remove((Long64_t)e->GetDeclId());
412  fUnloaded->Add(e);
413  }
414 }
virtual void Clear(Option_t *="")
Definition: TObject.h:91
void MapObject(TObject *obj)
Add pair<id, object> to the map of functions and their ids.
Bool_t HasInterpreterInfoInMemory() const
Definition: TClass.h:363
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition: TExMap.cxx:87
void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: THashList.cxx:68
The TEnum class implements the enum type.
Definition: TEnum.h:31
void Remove(ULong64_t hash, Long64_t key)
Remove entry with specified key from the TExMap.
Definition: TExMap.cxx:216
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
void AddLast(TObject *obj)
Add object at the end of the list.
Definition: THashList.cxx:90
long long Long64_t
Definition: RtypesCore.h:69
Bool_t fIsLoaded
Holder of TEnum for unloaded Enums.
Definition: TListOfEnums.h:44
void Update(DeclId_t id)
Definition: TEnum.cxx:101
THashList * fUnloaded
Map from DeclId_t to TEnum*.
Definition: TListOfEnums.h:43
const char Option_t
Definition: RtypesCore.h:62
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
ULong64_t fLastLoadMarker
Mark whether Load was executed.
Definition: TListOfEnums.h:45
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl &#39;id&#39;...
void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: THashList.cxx:184
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
#define gInterpreter
Definition: TInterpreter.h:499
TObject * FindObject(const char *name) const
Find object using its name.
Definition: THashList.cxx:213
void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: THashList.cxx:253
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
DeclId_t GetDeclId() const
Definition: TEnum.h:61
TExMap * fIds
Context of this list. Not owned.
Definition: TListOfEnums.h:42
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:381
TClass * fClass
Definition: TListOfEnums.h:40
void AddLast(TObject *obj) override
Add object at the end of the list.
void Clear(Option_t *option="")
Remove all objects from the list.
Definition: THashList.cxx:168
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:173
void AddAt(TObject *obj, Int_t idx)
Insert object at location idx in the list.
Definition: THashList.cxx:148
~TListOfEnums() override
Destructor.
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:285
virtual TEnum * GetObject(const char *) const
Return an object from the list of enums if and only if is has already been loaded in the list...
void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: THashList.cxx:130
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
void UnmapObject(TObject *obj)
Remove a pair<id, object> from the map of functions and their ids.
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5675
TObject * Remove(TObject *obj) override
Remove object from the list.
virtual TObjLink * FirstLink() const
Definition: TList.h:97
TDictionary::DeclId_t DeclId_t
Definition: TListOfEnums.h:59
const unsigned int listSize
const Bool_t kFALSE
Definition: RtypesCore.h:92
#define ClassImp(name)
Definition: Rtypes.h:336
void Clear(Option_t *option) override
Remove all objects from the list.
unsigned long long ULong64_t
Definition: RtypesCore.h:70
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
#define R__LOCKGUARD(mutex)
void Delete(Option_t *option="") override
Delete all TDataMember object files.
void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: THashList.cxx:112
void Load()
Load all the DataMembers known to the interpreter for the scope &#39;fClass&#39; into this collection...
Mother of all ROOT objects.
Definition: TObject.h:37
void Unload()
Mark &#39;all func&#39; as being unloaded.
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
Definition: TListOfEnums.h:32
virtual void Add(TObject *obj)
Definition: TList.h:77
const Bool_t kTRUE
Definition: RtypesCore.h:91
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl &#39;id&#39; or NULL if it does not exist.
This class stores a (key,value) pair using an external hash.
Definition: TExMap.h:33
void AddAt(TObject *obj, Int_t idx) override
Insert object at location idx in the list.