Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TListOfDataMembers.cxx
Go to the documentation of this file.
1// @(#)root/cont
2// Author: Philippe Canal Aug 2013
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 TListOfDataMembers
13A collection of TDataMember objects designed for fast access given a
14DeclId_t and for keep track of TDataMember that were described
15unloaded data member.
16*/
17
18#include "TListOfDataMembers.h"
19#include "TBuffer.h"
20#include "TClass.h"
21#include "TClassRef.h"
22#include "TExMap.h"
23#include "TDataMember.h"
24#include "TGlobal.h"
25#include "TInterpreter.h"
26#include "TVirtualMutex.h"
27#include "TError.h"
28#include "TClassEdit.h"
29
30#include <sstream>
31
32const unsigned int idsSize=19;
33
34
35////////////////////////////////////////////////////////////////////////////////
36/// Destructor.
37
45
46////////////////////////////////////////////////////////////////////////////////
47/// Add a pair<id, object> to the map of data members and their ids.
48
50{
51 if (!fIds) fIds = new TExMap(idsSize);
52
53 if (fClass) {
54 TDataMember *d = dynamic_cast<TDataMember*>(obj);
55 if (d) {
56 fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
57 }
58 } else {
59 TGlobal *g = dynamic_cast<TGlobal*>(obj);
60 if (g && g->GetDeclId()) {
61 fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
62 }
63 }
64}
65
66////////////////////////////////////////////////////////////////////////////////
67/// Add object at the beginning of the list.
68
74
75////////////////////////////////////////////////////////////////////////////////
76/// Add object at the beginning of the list and also store option.
77/// Storing an option is useful when one wants to change the behaviour
78/// of an object a little without having to create a complete new
79/// copy of the object. This feature is used, for example, by the Draw()
80/// method. It allows the same object to be drawn in different ways.
81
83{
84 THashList::AddFirst(obj,opt);
85 MapObject(obj);
86}
87
88////////////////////////////////////////////////////////////////////////////////
89/// Add object at the end of the list.
90
96
97////////////////////////////////////////////////////////////////////////////////
98/// Add object at the end of the list and also store option.
99/// Storing an option is useful when one wants to change the behaviour
100/// of an object a little without having to create a complete new
101/// copy of the object. This feature is used, for example, by the Draw()
102/// method. It allows the same object to be drawn in different ways.
103
105{
106 THashList::AddLast(obj, opt);
107 MapObject(obj);
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// Insert object at location idx in the list.
112
114{
115 THashList::AddAt(obj, idx);
116 MapObject(obj);
117}
118
119////////////////////////////////////////////////////////////////////////////////
120/// Insert object after object after in the list.
121
123{
125 MapObject(obj);
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Insert object after object after in the list.
130
136
137////////////////////////////////////////////////////////////////////////////////
138/// Insert object before object before in the list.
139
145
146////////////////////////////////////////////////////////////////////////////////
147/// Insert object before object before in the list.
148
154
155////////////////////////////////////////////////////////////////////////////////
156/// Remove all objects from the list. Does not delete the objects unless
157/// the THashList is the owner (set via SetOwner()).
158
166
167////////////////////////////////////////////////////////////////////////////////
168/// Delete all TDataMember object files.
169
176
177////////////////////////////////////////////////////////////////////////////////
178/// Specialize FindObject to do search for the
179/// a data member just by name or create it if its not already in the list
180
182{
184 if (!result) {
186 // We already have all the information, no need to search more
187 return nullptr;
188 }
189
191
193 if (fClass) decl = gInterpreter->GetDataMember(fClass->GetClassInfo(),name);
194 else decl = gInterpreter->GetDataMember(nullptr,name);
195 if (decl) result = const_cast<TListOfDataMembers*>(this)->Get(decl);
196 }
197 return result;
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// Return (after creating it if necessary) the TDataMember
202/// describing the data member corresponding to the Decl 'id'.
203
205{
206 if (!id) return nullptr;
207
208 return fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : nullptr;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Return (after creating it if necessary) the TDataMember
213/// describing the data member corresponding to the Decl 'id'.
214
216{
217 if (!id) return nullptr;
218
220 //need the Find and possible Add to be one atomic operation
221 TDictionary *dm = Find(id);
222 if (dm) return dm;
223
224 if (fClass) {
226 // The interpreter does not know about this class yet (or a problem
227 // occurred that prevented the proper updating of fClassInfo).
228 // So this decl can not possibly be part of this class.
229 // [In addition calling GetClassInfo would trigger a late parsing
230 // of the header which we want to avoid].
231 return nullptr;
232 }
233 if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return nullptr;
234 } else {
235 if (!gInterpreter->ClassInfo_Contains(nullptr,id)) return nullptr;
236 }
237
238 DataMemberInfo_t *info = gInterpreter->DataMemberInfo_Factory(id,fClass ? fClass->GetClassInfo() : nullptr);
239
240 // Let's see if this is a reload ...
241 const char *name = gInterpreter->DataMemberInfo_Name(info);
243 if (update) {
244 if (fClass) {
245 ((TDataMember*)update)->Update(info);
246 } else {
247 ((TGlobal*)update)->Update(info);
248 }
249 dm = update;
250 }
251 if (!dm) {
252 if (fClass) dm = new TDataMember(info, fClass);
253 else dm = new TGlobal(info);
254 }
255 // Calling 'just' THahList::Add would turn around and call
256 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
258 if (!fIds) fIds = new TExMap(idsSize);
259 fIds->Add((Long64_t)id,(Long64_t)dm);
260
261 return dm;
262}
263
264////////////////////////////////////////////////////////////////////////////////
265/// Return (after creating it if necessary) the TDataMember
266/// describing the data member corresponding to the Decl 'id'.
267/// The skipChecks flag controls the consistency checks performed inspecting
268/// the AST. In some cases, we explicitly alter the datamembers in the
269/// typesystem with respect to the AST and therefore we must not enforce
270/// consistency.
271
273{
274 if (!info) return nullptr;
275
276 TDictionary::DeclId_t id = gInterpreter->GetDeclId(info);
277 R__ASSERT( id != nullptr && "DeclId should not be null");
278 TDictionary *dm = fIds ? (TDataMember*)fIds->GetValue((Long64_t)id) : nullptr;
279 if (!dm) {
280 if (fClass) {
282 // The interpreter does not know about this class yet (or a problem
283 // occurred that prevented the proper updating of fClassInfo).
284 // So this decl can not possibly be part of this class.
285 // [In addition calling GetClassInfo would trigger a late parsing
286 // of the header which we want to avoid].
287 return nullptr;
288 }
289 if (!skipChecks && !gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return nullptr;
290 } else {
291 if (!skipChecks && !gInterpreter->ClassInfo_Contains(nullptr,id)) return nullptr;
292 }
293
295
296 DataMemberInfo_t *dm_info = gInterpreter->DataMemberInfo_FactoryCopy(info);
297
298 // Let's see if this is a reload ...
299 const char *name = gInterpreter->DataMemberInfo_Name(info);
301 if (update) {
302 update->Update(dm_info);
303 dm = update;
304 }
305 if (!dm) {
306 if (fClass) dm = new TDataMember(dm_info, fClass);
307 else dm = new TGlobal(dm_info);
308 }
309 // Calling 'just' THahList::Add would turn around and call
310 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
312 if (!fIds) fIds = new TExMap(idsSize);
313 fIds->Add((Long64_t)id,(Long64_t)dm);
314 }
315 return dm;
316}
317
318////////////////////////////////////////////////////////////////////////////////
319/// Remove a pair<id, object> from the map of data members and their ids.
320
322{
323 if (!fIds) return;
324 if (fClass) {
325 TDataMember *d = dynamic_cast<TDataMember*>(obj);
326 if (d) {
327 if (d->GetDeclId()) {
328 fIds->Remove((Long64_t)d->GetDeclId());
329 }
330 d->Update(nullptr);
331 }
332 } else {
333 TGlobal *g = dynamic_cast<TGlobal*>(obj);
334 if (g) {
335 if (g->GetDeclId()) {
336 fIds->Remove((Long64_t)g->GetDeclId());
337 }
338 g->Update(nullptr);
339 }
340 }
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// Remove object from this collection and recursively remove the object
345/// from all other objects (and collections).
346/// This function overrides TCollection::RecursiveRemove that calls
347/// the Remove function. THashList::Remove cannot be called because
348/// it uses the hash value of the hash table. This hash value
349/// is not available anymore when RecursiveRemove is called from
350/// the TObject destructor.
351
353{
354 if (!obj) return;
355
358 UnmapObject(obj);
359
360}
361
362////////////////////////////////////////////////////////////////////////////////
363/// Remove object from the list.
364
366{
367 Bool_t found;
368
369 found = THashList::Remove(obj);
370 if (!found && fUnloaded) {
371 found = fUnloaded->Remove(obj);
372 }
373 UnmapObject(obj);
374 if (found) return obj;
375 else return nullptr;
376}
377
378////////////////////////////////////////////////////////////////////////////////
379/// Remove object via its objlink from the list.
380
382{
383 if (!lnk) return nullptr;
384
385 TObject *obj = lnk->GetObject();
386
388 if (fUnloaded) fUnloaded->Remove(obj);
389
390 UnmapObject(obj);
391 return obj;
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Load all the DataMembers known to the interpreter for the scope 'fClass'
396/// into this collection.
397
399{
401 // Class and union are not extendable, if we already
402 // loaded all the data member there is no need to recheck
403 if (fIsLoaded) return;
404 }
405
406 // This will provoke the parsing of the headers if need be.
407 if (fClass && fClass->GetClassInfo() == nullptr) return;
408
410
411 ULong64_t currentTransaction = gInterpreter->GetInterpreterStateMarker();
413 return;
414 }
416
417 // In the case of namespace, even if we have loaded before we need to
418 // load again in case there was new data member added.
419
420 // Mark the list as loaded to avoid an infinite recursion in the case
421 // where we have a data member that is a variable size array. In that
422 // case TDataMember::Init needs to get/load the list to find the data
423 // member used as the array size.
425
427 if (fClass) info = fClass->GetClassInfo();
428 else info = gInterpreter->ClassInfo_Factory();
429
430 // Treat the complex<float>, complex<double> in a special way, i.e. replacing
431 // the datamembers with the ones of _root_std_complex<T>
432 bool skipChecks = false;
433 if (fClass) {
435 switch(complexType) {
437 {
438 break;
439 }
441 {
442 skipChecks = true;
443 info = TClass::GetClass("_root_std_complex<float>")->GetClassInfo();
444 break;
445 }
447 {
448 skipChecks = true;
449 info = TClass::GetClass("_root_std_complex<double>")->GetClassInfo();
450 break;
451 }
453 {
454 skipChecks = true;
455 info = TClass::GetClass("_root_std_complex<int>")->GetClassInfo();
456 break;
457 }
459 {
460 skipChecks = true;
461 info = TClass::GetClass("_root_std_complex<long>")->GetClassInfo();
462 break;
463 }
464 }
465 }
466
467 // Now we follow the ordinary pattern
468 DataMemberInfo_t *t = gInterpreter->DataMemberInfo_Factory(info, fSelection);
469 while (gInterpreter->DataMemberInfo_Next(t)) {
470 if (gInterpreter->DataMemberInfo_IsValid(t)) {
471 // Get will check if there is already there or create a new one
472 // (or re-use a previously unloaded version).
473 Get(t,skipChecks);
474 }
475 }
476 gInterpreter->DataMemberInfo_Delete(t);
477 if (!fClass) gInterpreter->ClassInfo_Delete(info);
478}
479
480////////////////////////////////////////////////////////////////////////////////
481/// Stream an object of class TListOfDataMembers.
482
484{
485 if (R__b.IsReading()) {
486 R__b.ReadClassBuffer(TListOfDataMembers::Class(),this);
488 } else {
489 R__b.WriteClassBuffer(TListOfDataMembers::Class(),this);
490 }
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Move the member or data member to the expect set of list.
495
497 if (fClass) {
498 TDataMember *d = dynamic_cast<TDataMember*>(member);
499 if (d) {
500 if (d->GetDeclId()) {
501 if (!fIds) fIds = new TExMap(idsSize);
502 fIds->Add((Long64_t)d->GetDeclId(),(Long64_t)d);
503 }
504 TDictionary *update = fUnloaded ? (TDictionary *)fUnloaded->FindObject(d->GetName()) : nullptr;
506
507 if (! THashList::FindObject(d) ) {
508 // Calling 'just' THahList::Add would turn around and call
509 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
511 }
512 }
513 } else {
514 TGlobal *g = dynamic_cast<TGlobal*>(member);
515 if (g) {
516 if (g->GetDeclId()) {
517 if (!fIds) fIds = new TExMap(idsSize);
518 fIds->Add((Long64_t)g->GetDeclId(),(Long64_t)g);
519
520 TDictionary *update = fUnloaded ? (TDictionary *)fUnloaded->FindObject(g->GetName()) : nullptr;
522
523 if (! THashList::FindObject(g) ) {
524 // Calling 'just' THahList::Add would turn around and call
525 // TListOfDataMembers::AddLast which should *also* do the fIds->Add.
527 }
528 }
529 }
530 }
531
532
533}
534
535////////////////////////////////////////////////////////////////////////////////
536/// Mark 'all func' as being unloaded.
537/// After the unload, the data member can no longer be found directly,
538/// until the decl can be found again in the interpreter (in which
539/// the func object will be reused.
540
542{
544 while (lnk) {
545 TDictionary *data = (TDictionary *)lnk->GetObject();
547 if (!fUnloaded) fUnloaded = new THashList;
549
550 lnk = lnk->Next();
551 }
552
555}
556
557////////////////////////////////////////////////////////////////////////////////
558/// Mark 'func' as being unloaded.
559/// After the unload, the data member can no longer be found directly,
560/// until the decl can be found again in the interpreter (in which
561/// the func object will be reused.
562
564{
565 if (THashList::Remove(mem)) {
566 // We contains the object, let remove it from the other internal
567 // list and move it to the list of unloaded objects.
568
570 if (!fUnloaded) fUnloaded = new THashList;
571 fUnloaded->Add(mem);
572 }
573}
#define d(i)
Definition RSha256.hxx:102
#define g(i)
Definition RSha256.hxx:105
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kIsClass
Definition TDictionary.h:65
@ kIsStruct
Definition TDictionary.h:66
@ kIsUnion
Definition TDictionary.h:67
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define gInterpreter
const unsigned int idsSize
#define R__LOCKGUARD(mutex)
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Bool_t HasInterpreterInfoInMemory() const
Definition TClass.h:421
ClassInfo_t * GetClassInfo() const
Definition TClass.h:445
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6128
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2973
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
This class defines an abstract interface that must be implemented by all classes that contain diction...
const void * DeclId_t
This class stores a (key,value) pair using an external hash.
Definition TExMap.h:33
void Remove(ULong64_t hash, Long64_t key)
Remove entry with specified key from the TExMap.
Definition TExMap.cxx:216
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
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition TExMap.cxx:173
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
void Clear(Option_t *option="") override
Remove all objects from the list.
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
Definition THashList.cxx:68
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
void AddAt(TObject *obj, Int_t idx) override
Insert object at location idx in the list.
THashList(const THashList &)=delete
TObject * Remove(TObject *obj) override
Remove object from the list.
TObject * FindObject(const char *name) const override
Find object using its name.
void AddLast(TObject *obj) override
Add object at the end of the list.
Definition THashList.cxx:94
TDictionary::DeclId_t DeclId_t
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
void Delete(Option_t *option="") override
Delete all TDataMember object files.
void AddAt(TObject *obj, Int_t idx) override
Insert object at location idx in the list.
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
TDictionary::DeclId_t DeclId_t
void Streamer(TBuffer &) override
Stream an object of class TListOfDataMembers.
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
Bool_t IsLoaded() const
void Update(TDictionary *member)
Move the member or data member to the expect set of list.
TDictionary::EMemberSelection fSelection
Mark whether Load was executed.
void Clear(Option_t *option="") override
Remove all objects from the list.
ULong64_t fLastLoadMarker
Holder of TDataMember for unloaded DataMembers.
~TListOfDataMembers()
Destructor.
std::atomic< bool > fIsLoaded
Represent interpreter state when we last did a full load.
TObject * Remove(TObject *obj) override
Remove object from the list.
TExMap * fIds
Context of this list. Not owned.
void AddBefore(const TObject *before, TObject *obj) override
Insert object before object before in the list.
void UnmapObject(TObject *obj)
Remove a pair<id, object> from the map of data members and their ids.
void MapObject(TObject *obj)
Add a pair<id, object> to the map of data members and their ids.
void Unload()
Mark 'all func' as being unloaded.
THashList * fUnloaded
Map from DeclId_t to TDataMember*.
void AddLast(TObject *obj) override
Add object at the end of the list.
static TClass * Class()
TDictionary * Get(DeclId_t id)
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
void Load()
Load all the DataMembers known to the interpreter for the scope 'fClass' into this collection.
void AddFirst(TObject *obj) override
Add object at the beginning of the list.
void Add(TObject *obj) override
Definition TList.h:81
virtual TObjLink * FirstLink() const
Definition TList.h:102
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Clear(Option_t *="")
Definition TObject.h:125
EComplexType GetComplexType(const char *)