Logo ROOT   6.12/07
Reference Guide
TCollection.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Fons Rademakers 13/08/95
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 TCollection
13 \ingroup Containers
14 Collection abstract base class. This class describes the base
15 protocol all collection classes have to implement. The ROOT
16 collection classes always store pointers to objects that inherit
17 from TObject. They never adopt the objects. Therefore, it is the
18 user's responsibility to take care of deleting the actual objects
19 once they are not needed anymore. In exceptional cases, when the
20 user is 100% sure nothing else is referencing the objects in the
21 collection, one can delete all objects and the collection at the
22 same time using the Delete() function.
23 
24 Collections can be iterated using an iterator object (see
25 TIterator). Depending on the concrete collection class there may be
26 some additional methods of iterating. See the respective classes.
27 
28 TCollection inherits from TObject since we want to be able to have
29 collections of collections.
30 
31 In a later release the collections may become templatized.
32 */
33 
34 #include "TCollection.h"
35 #include "Riostream.h"
36 #include "Varargs.h"
37 #include "TClass.h"
38 #include "TROOT.h"
39 #include "TBrowser.h"
40 #include "TObjectTable.h"
41 #include "TRegexp.h"
42 #include "TPRegexp.h"
43 #include "TVirtualMutex.h"
44 #include "TError.h"
45 #include "TSystem.h"
46 #include <sstream>
47 
48 #include "TSpinLockGuard.h"
49 
51 
56 
59 
60 #ifdef R__CHECK_COLLECTION_MULTI_ACCESS
61 
62 void TCollection::TErrorLock::ConflictReport(std::thread::id holder, const char *accesstype,
63  const TCollection *collection, const char *function)
64 {
65 
66  auto local = std::this_thread::get_id();
67  std::stringstream cur, loc;
68  if (holder == std::thread::id())
69  cur << "None";
70  else
71  cur << "0x" << std::hex << holder;
72  loc << "0x" << std::hex << local;
73 
74  // std::cerr << "Error in " << function << ": Access (" << accesstype << ") to a collection (" <<
75  // collection->IsA()->GetName() << ":" << collection <<
76  // ") from multiple threads at a time. holder=" << "0x" << std::hex << holder << " readers=" << fReadSet.size() <<
77  // "0x" << std::hex << local << std::endl;
78 
79  ::Error(function,
80  "Access (%s) to a collection (%s:%p) from multiple threads at a time. holder=%s readers=%lu intruder=%s",
81  accesstype, collection->IsA()->GetName(), collection, cur.str().c_str(), fReadSet.size(), loc.str().c_str());
82 
83  std::set<std::thread::id> tmp;
84  for (auto r : fReadSet) tmp.insert(r);
85  for (auto r : tmp) {
86  std::stringstream reader;
87  reader << "0x" << std::hex << r;
88  ::Error(function, " Readers includes %s", reader.str().c_str());
89  }
91 }
92 
93 void TCollection::TErrorLock::Lock(const TCollection *collection, const char *function)
94 {
95  auto local = std::this_thread::get_id();
96 
97  std::thread::id holder;
98 
99  if (fWriteCurrent.compare_exchange_strong(holder, local)) {
100  // fWriteCurrent was the default id and is now local.
101  ++fWriteCurrentRecurse;
102  // std::cerr << "#" << "0x" << std::hex << local << " acquired first " << collection << " lock:" << this <<
103  // std::endl;
104 
105  // Now check if there is any readers lingering
106  if (fReadCurrentRecurse) {
107  if (fReadSet.size() > 1 || fReadSet.find(local) != fReadSet.end()) {
108  ConflictReport(std::thread::id(), "WriteLock while ReadLock taken", collection, function);
109  }
110  }
111  } else {
112  // fWriteCurrent was not the default id and is still the 'holder' thread id
113  // this id is now also in the holder variable
114  if (holder == local) {
115  // The holder was actually this thread, no problem there, we
116  // allow re-entrancy.
117  // std::cerr << "#" << "0x" << std::hex << local << " re-entered " << fWriteCurrentRecurse << " " << collection
118  // << " lock:" << this << std::endl;
119  } else {
120  ConflictReport(holder, "WriteLock", collection, function);
121  }
122  ++fWriteCurrentRecurse;
123  }
124 }
125 
126 void TCollection::TErrorLock::Unlock()
127 {
128  auto local = std::this_thread::get_id();
129  auto none = std::thread::id();
130 
131  --fWriteCurrentRecurse;
132  if (fWriteCurrentRecurse == 0) {
133  if (fWriteCurrent.compare_exchange_strong(local, none)) {
134  // fWriteCurrent was local and is now none.
135 
136  // std::cerr << "#" << "0x" << std::hex << local << " zero and cleaned : " << std::dec << fWriteCurrentRecurse
137  // << " 0x" << std::hex << fWriteCurrent.load() << " lock:" << this << std::endl;
138  } else {
139  // fWriteCurrent was not local, just live it as is.
140 
141  // std::cerr << "#" << "0x" << std::hex << local << " zero but somebody else : " << "0x" << std::hex <<
142  // fWriteCurrent.load() << " lock:" << this << std::endl;
143  }
144  } else {
145  // std::cerr << "#" << "0x" << std::hex << local << " still holding " << "0x" << std::hex << fWriteCurrentRecurse
146  // << " lock:" << this << std::endl;
147  }
148 
149  // std::cerr << "#" << "0x" << std::hex << local << " ended with : " << std::dec << fWriteCurrentRecurse << " 0x" <<
150  // std::hex << fWriteCurrent.load() << " lock:" << this << std::endl;
151 }
152 
153 void TCollection::TErrorLock::ReadLock(const TCollection *collection, const char *function)
154 {
155  auto local = std::this_thread::get_id();
156 
157  {
158  ROOT::Internal::TSpinLockGuard guard(fSpinLockFlag);
159  fReadSet.insert(local); // this is not thread safe ...
160  }
161  ++fReadCurrentRecurse;
162 
163  if (fWriteCurrentRecurse) {
164  auto holder = fWriteCurrent.load();
165  if (holder != local) ConflictReport(holder, "ReadLock with WriteLock taken", collection, function);
166  }
167 }
168 
169 void TCollection::TErrorLock::ReadUnlock()
170 {
171  auto local = std::this_thread::get_id();
172  {
173  ROOT::Internal::TSpinLockGuard guard(fSpinLockFlag);
174  fReadSet.erase(local); // this is not thread safe ...
175  }
176  --fReadCurrentRecurse;
177 }
178 
179 #endif // R__CHECK_COLLECTION_MULTI_ACCESS
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// TNamed destructor.
183 
185 {
186  // Required since we overload TObject::Hash.
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 /// Add all objects from collection col to this collection.
192 
194 {
195  TIter next(col);
196  TObject *obj;
197 
198  while ((obj = next()))
199  Add(obj);
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Add all arguments to the collection. The list of objects must be
204 /// terminated by 0, e.g.: l.AddVector(o1, o2, o3, o4, 0);
205 
207 {
208  va_list ap;
209  va_start(ap, va_(obj1));
210  TObject *obj;
211 
212  Add(va_(obj1));
213  while ((obj = va_arg(ap, TObject *)))
214  Add(obj);
215  va_end(ap);
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Make sure all objects in this collection inherit from class cl.
220 
222 {
223  TObject *obj;
224  TIter next(this);
225  Bool_t error = kFALSE;
226 
227  if (!cl) {
228  Error("AssertClass", "class == 0");
229  return kTRUE;
230  }
231 
232  for (int i = 0; (obj = next()); i++)
233  if (!obj->InheritsFrom(cl)) {
234  Error("AssertClass", "element %d is not an instance of class %s (%s)",
235  i, cl->GetName(), obj->ClassName());
236  error = kTRUE;
237  }
238  return error;
239 }
240 
241 ////////////////////////////////////////////////////////////////////////////////
242 /// Browse this collection (called by TBrowser).
243 /// If b=0, there is no Browse call TObject::Browse(0) instead.
244 /// This means TObject::Inspect() will be invoked indirectly
245 
247 {
248  TIter next(this);
249  TObject *obj;
250 
251  if (b)
252  while ((obj = next())) b->Add(obj);
253  else
254  TObject::Browse(b);
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Make a clone of an collection using the Streamer facility.
259 /// If newname is specified, this will be the name of the new collection.
260 
261 TObject *TCollection::Clone(const char *newname) const
262 {
263  TCollection *new_collection = (TCollection*)TObject::Clone(newname);
264  if (newname && strlen(newname)) new_collection->SetName(newname);
265  return new_collection;
266 }
267 
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// Compare two TCollection objects. Returns 0 when equal, -1 when this is
271 /// smaller and +1 when bigger (like strcmp()).
272 
274 {
275  if (this == obj) return 0;
276  return fName.CompareTo(obj->GetName());
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Draw all objects in this collection.
281 
283 {
284  TIter next(this);
285  TObject *object;
286 
287  while ((object = next())) {
288  object->Draw(option);
289  }
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Dump all objects in this collection.
294 
295 void TCollection::Dump() const
296 {
297  TIter next(this);
298  TObject *object;
299 
300  while ((object = next())) {
301  object->Dump();
302  }
303 }
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 /// Find an object in this collection using its name. Requires a sequential
307 /// scan till the object has been found. Returns 0 if object with specified
308 /// name is not found.
309 
311 {
312  TIter next(this);
313  TObject *obj;
314 
315  while ((obj = next()))
316  if (!strcmp(name, obj->GetName())) return obj;
317  return 0;
318 }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Find an object in this collection by name.
322 
324 {
325  return FindObject(name);
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Find an object in this collection using the object's IsEqual()
330 /// member function. Requires a sequential scan till the object has
331 /// been found. Returns 0 if object is not found.
332 /// Typically this function is overridden by a more efficient version
333 /// in concrete collection classes (e.g. THashTable).
334 
336 {
337  TIter next(this);
338  TObject *ob;
339 
340  while ((ob = next()))
341  if (ob->IsEqual(obj)) return ob;
342  return 0;
343 }
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// Return name of this collection.
347 /// if no name, return the collection class name.
348 
349 const char *TCollection::GetName() const
350 {
351  if (fName.Length() > 0) return fName.Data();
352  return ClassName();
353 }
354 
355 ////////////////////////////////////////////////////////////////////////////////
356 /// Increase the collection's capacity by delta slots.
357 
359 {
360  if (delta < 0) {
361  Error("GrowBy", "delta < 0");
362  delta = Capacity();
363  }
364  return Capacity() + TMath::Range(2, kMaxInt - Capacity(), delta);
365 }
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Returns true if object is a null pointer.
369 
370 Bool_t TCollection::IsArgNull(const char *where, const TObject *obj) const
371 {
372  return obj ? kFALSE : (Error(where, "argument is a null pointer"), kTRUE);
373 }
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// List (ls) all objects in this collection.
377 /// Wildcarding supported, eg option="xxx*" lists only objects
378 /// with names xxx*.
379 
380 void TCollection::ls(Option_t *option) const
381 {
383  std::cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
384  << Int_t(TestBit(kCanDelete)) << std::endl;
385 
386  TRegexp re(option,kTRUE);
387  TIter next(this);
388  TObject *object;
389  char *star = 0;
390  if (option) star = (char*)strchr(option,'*');
391 
393  while ((object = next())) {
394  if (star) {
395  TString s = object->GetName();
396  if (s != option && s.Index(re) == kNPOS) continue;
397  }
398  object->ls(option);
399  }
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 /// 'Notify' all objects in this collection.
406 {
407  Bool_t success = true;
408  for (auto obj : *this) success &= obj->Notify();
409  return success;
410 }
411 
412 ////////////////////////////////////////////////////////////////////////////////
413 /// Paint all objects in this collection.
414 
416 {
417  this->R__FOR_EACH(TObject,Paint)(option);
418 }
419 
420 ////////////////////////////////////////////////////////////////////////////////
421 /// Print the collection header.
422 
424 {
426  printf("Collection name='%s', class='%s', size=%d\n",
427  GetName(), ClassName(), GetSize());
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// For given collection entry return the string that is used to
432 /// identify the object and, potentially, perform wildcard/regexp
433 /// filtering on.
434 
436 {
437  return entry->GetName();
438 }
439 
440 ////////////////////////////////////////////////////////////////////////////////
441 /// Print the collection entry.
442 
443 void TCollection::PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const
444 {
445  TCollection* coll = dynamic_cast<TCollection*>(entry);
446  if (coll) {
447  coll->Print(option, recurse);
448  } else {
450  entry->Print(option);
451  }
452 }
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 /// Default print for collections, calls Print(option, 1).
456 /// This will print the collection header and Print() methods of
457 /// all the collection entries.
458 ///
459 /// If you want to override Print() for a collection class, first
460 /// see if you can accomplish it by overriding the following protected
461 /// methods:
462 /// ~~~ {.cpp}
463 /// void PrintCollectionHeader(Option_t* option) const;
464 /// const char* GetCollectionEntryName(TObject* entry) const;
465 /// void PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const;
466 /// ~~~
467 /// Otherwise override the `Print(Option_t *option, Int_t)`
468 /// variant. Remember to declare:
469 /// ~~~ {.cpp}
470 /// using TCollection::Print;
471 /// ~~~
472 /// somewhere close to the method declaration.
473 
474 void TCollection::Print(Option_t *option) const
475 {
476  Print(option, 1);
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// Print the collection header and its elements.
481 ///
482 /// If recurse is non-zero, descend into printing of
483 /// collection-entries with recurse - 1.
484 /// This means, if recurse is negative, the recursion is infinite.
485 ///
486 /// Option is passed recursively.
487 
488 void TCollection::Print(Option_t *option, Int_t recurse) const
489 {
490  PrintCollectionHeader(option);
491 
492  if (recurse != 0)
493  {
494  TIter next(this);
495  TObject *object;
496 
498  while ((object = next())) {
499  PrintCollectionEntry(object, option, recurse - 1);
500  }
502  }
503 }
504 
505 ////////////////////////////////////////////////////////////////////////////////
506 /// Print the collection header and its elements that match the wildcard.
507 ///
508 /// If recurse is non-zero, descend into printing of
509 /// collection-entries with recurse - 1.
510 /// This means, if recurse is negative, the recursion is infinite.
511 ///
512 /// Option is passed recursively, but wildcard is only used on the
513 /// first level.
514 
515 void TCollection::Print(Option_t *option, const char* wildcard, Int_t recurse) const
516 {
517  PrintCollectionHeader(option);
518 
519  if (recurse != 0)
520  {
521  if (!wildcard) wildcard = "";
522  TRegexp re(wildcard, kTRUE);
523  Int_t nch = strlen(wildcard);
524  TIter next(this);
525  TObject *object;
526 
528  while ((object = next())) {
529  TString s = GetCollectionEntryName(object);
530  if (nch == 0 || s == wildcard || s.Index(re) != kNPOS) {
531  PrintCollectionEntry(object, option, recurse - 1);
532  }
533  }
535  }
536 }
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 /// Print the collection header and its elements that match the regexp.
540 ///
541 /// If recurse is non-zero, descend into printing of
542 /// collection-entries with recurse - 1.
543 /// This means, if recurse is negative, the recursion is infinite.
544 ///
545 /// Option is passed recursively, but regexp is only used on the
546 /// first level.
547 
548 void TCollection::Print(Option_t *option, TPRegexp& regexp, Int_t recurse) const
549 {
550  PrintCollectionHeader(option);
551 
552  if (recurse != 0)
553  {
554  TIter next(this);
555  TObject *object;
556 
558  while ((object = next())) {
559  TString s = GetCollectionEntryName(object);
560  if (regexp.MatchB(s)) {
561  PrintCollectionEntry(object, option, recurse - 1);
562  }
563  }
565  }
566 }
567 
568 ////////////////////////////////////////////////////////////////////////////////
569 /// Remove object from this collection and recursively remove the object
570 /// from all other objects (and collections).
571 
573 {
574  if (!obj) return;
575 
576  // Scan list and remove obj in the list itself
577  while (Remove(obj))
578  ;
579 
580  // Scan again the list and invoke RecursiveRemove for all objects
581  TIter next(this);
582  TObject *object;
583 
584  while ((object = next())) {
585  if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
586  }
587 }
588 
589 ////////////////////////////////////////////////////////////////////////////////
590 /// Remove all objects in collection col from this collection.
591 
593 {
594  TIter next(col);
595  TObject *obj;
596 
597  while ((obj = next()))
598  Remove(obj);
599 }
600 
601 ////////////////////////////////////////////////////////////////////////////////
602 /// Stream all objects in the collection to or from the I/O buffer.
603 
604 void TCollection::Streamer(TBuffer &b)
605 {
606  Int_t nobjects;
607  TObject *obj;
608  UInt_t R__s, R__c;
609 
610  if (b.IsReading()) {
611  Version_t v = b.ReadVersion(&R__s, &R__c);
612  if (v > 2)
613  TObject::Streamer(b);
614  if (v > 1)
615  fName.Streamer(b);
616  b >> nobjects;
617  for (Int_t i = 0; i < nobjects; i++) {
618  b >> obj;
619  Add(obj);
620  }
621  b.CheckByteCount(R__s, R__c,TCollection::IsA());
622  } else {
623  R__c = b.WriteVersion(TCollection::IsA(), kTRUE);
624  TObject::Streamer(b);
625  fName.Streamer(b);
626  nobjects = GetSize();
627  b << nobjects;
628 
629  TIter next(this);
630 
631  while ((obj = next())) {
632  b << obj;
633  }
634  b.SetByteCount(R__c, kTRUE);
635  }
636 }
637 
638 ////////////////////////////////////////////////////////////////////////////////
639 /// Write all objects in this collection. By default all objects in
640 /// the collection are written individually (each object gets its
641 /// own key). Note, this is recursive, i.e. objects in collections
642 /// in the collection are also written individually. To write all
643 /// objects using a single key specify a name and set option to
644 /// TObject::kSingleKey (i.e. 1).
645 
646 Int_t TCollection::Write(const char *name, Int_t option, Int_t bsize) const
647 {
648  if ((option & kSingleKey)) {
649  return TObject::Write(name, option, bsize);
650  } else {
651  option &= ~kSingleKey;
652  Int_t nbytes = 0;
653  TIter next(this);
654  TObject *obj;
655  while ((obj = next())) {
656  nbytes += obj->Write(name, option, bsize);
657  }
658  return nbytes;
659  }
660 }
661 
662 ////////////////////////////////////////////////////////////////////////////////
663 /// Write all objects in this collection. By default all objects in
664 /// the collection are written individually (each object gets its
665 /// own key). Note, this is recursive, i.e. objects in collections
666 /// in the collection are also written individually. To write all
667 /// objects using a single key specify a name and set option to
668 /// TObject::kSingleKey (i.e. 1).
669 
670 Int_t TCollection::Write(const char *name, Int_t option, Int_t bsize)
671 {
672  return ((const TCollection*)this)->Write(name,option,bsize);
673 }
674 
675 ////////////////////////////////////////////////////////////////////////////////
676 /// Return the globally accessible collection.
677 
679 {
680  return fgCurrentCollection;
681 }
682 
683 ////////////////////////////////////////////////////////////////////////////////
684 /// Set this collection to be the globally accesible collection.
685 
687 {
688  fgCurrentCollection = this;
689 }
690 
691 ////////////////////////////////////////////////////////////////////////////////
692 /// Set up for garbage collection.
693 
695 {
696  R__LOCKGUARD2(gCollectionMutex);
697  if (!fgGarbageCollection) {
700  fgGarbageStack = 0;
701  }
702  fgGarbageStack++;
703 }
704 
705 ////////////////////////////////////////////////////////////////////////////////
706 /// Do the garbage collection.
707 
709 {
710  R__LOCKGUARD2(gCollectionMutex);
711  if (fgGarbageStack > 0) fgGarbageStack--;
717  }
718 }
719 
720 ////////////////////////////////////////////////////////////////////////////////
721 /// Add to the list of things to be cleaned up.
722 
724 {
725  {
726  R__LOCKGUARD2(gCollectionMutex);
727  if (fgGarbageCollection) {
728  if (!fgEmptyingGarbage) {
729  fgGarbageCollection->Add(obj);
730  return;
731  }
732  }
733  }
734  delete obj;
735 }
736 
737 ////////////////////////////////////////////////////////////////////////////////
738 /// Set whether this collection is the owner (enable==true)
739 /// of its content. If it is the owner of its contents,
740 /// these objects will be deleted whenever the collection itself
741 /// is delete. The objects might also be deleted or destructed when Clear
742 /// is called (depending on the collection).
743 
745 {
746  if (enable)
747  SetBit(kIsOwner);
748  else
750 }
751 
752 ////////////////////////////////////////////////////////////////////////////////
753 /// Set this collection to use a RW lock upon access, making it thread safe.
754 /// Return the previous state.
755 ///
756 /// Note: To test whether the usage is enabled do:
757 /// collection->TestBit(TCollection::kUseRWLock);
758 
760 {
761  bool prev = TestBit(TCollection::kUseRWLock);
763  return prev;
764 }
765 
766 ////////////////////////////////////////////////////////////////////////////////
767 /// Copy a TIter. This involves allocating a new TIterator of the right
768 /// sub class and assigning it with the original.
769 
770 TIter::TIter(const TIter &iter)
771 {
772  if (iter.fIterator) {
773  fIterator = iter.GetCollection()->MakeIterator();
774  fIterator->operator=(*iter.fIterator);
775  } else
776  fIterator = 0;
777 }
778 
779 ////////////////////////////////////////////////////////////////////////////////
780 /// Assigning an TIter to another. This involves allocating a new TIterator
781 /// of the right sub class and assigning it with the original.
782 
784 {
785  if (this != &rhs) {
786  if (rhs.fIterator) {
787  delete fIterator;
788  fIterator = rhs.GetCollection()->MakeIterator();
789  fIterator->operator=(*rhs.fIterator);
790  }
791  }
792  return *this;
793 }
794 
795 ////////////////////////////////////////////////////////////////////////////////
796 /// Pointing to the first element of the container.
797 
799 {
800  fIterator->Reset();
801  fIterator->Next();
802  return *this;
803 }
804 
805 ////////////////////////////////////////////////////////////////////////////////
806 /// Pointing to the element after the last - to a nullptr value in our case.
807 
809 {
810  return TIter(static_cast<TIterator*>(nullptr));
811 }
812 
813 ////////////////////////////////////////////////////////////////////////////////
814 /// Return an empty collection for use with nullptr TRangeCast
815 
817 {
818  static std::unique_ptr<TCollection> fgEmptyCollection((TCollection *)TClass::GetClass("TObjArray")->New());
819  return *fgEmptyCollection.get();
820 }
821 
822 ////////////////////////////////////////////////////////////////////////////////
823 /// Return true if 'cl' inherits from 'base'.
824 
826 {
827  return cl->InheritsFrom(base);
828 }
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:261
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
virtual TObject * Remove(TObject *obj)=0
static Int_t fgGarbageStack
Definition: TCollection.h:135
Bool_t IsReading() const
Definition: TBuffer.h:83
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition: TROOT.cxx:2683
const TCollection * GetCollection() const
Definition: TCollection.h:248
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:740
Bool_t MatchB(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
Definition: TPRegexp.h:78
short Version_t
Definition: RtypesCore.h:61
void CallRecursiveRemoveIfNeeded(TObject &obj)
call RecursiveRemove for obj if gROOT is valid and obj.TestBit(kMustCleanup) is true.
Definition: TROOT.h:391
const char Option_t
Definition: RtypesCore.h:62
virtual const char * GetCollectionEntryName(TObject *entry) const
For given collection entry return the string that is used to identify the object and, potentially, perform wildcard/regexp filtering on.
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
Int_t Compare(const TObject *obj) const
Compare two TCollection objects.
TIter & Begin()
Pointing to the first element of the container.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Bool_t IsArgNull(const char *where, const TObject *obj) const
Returns true if object is a null pointer.
virtual void Draw(Option_t *option="")
Draw all objects in this collection.
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
Regular expression class.
Definition: TRegexp.h:31
This class implements a mutex interface.
Definition: TVirtualMutex.h:34
bool ContaineeInheritsFrom(TClass *cl, TClass *base)
Return true if &#39;cl&#39; inherits from &#39;base&#39;.
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:585
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TVirtualMutex * gCollectionMutex
Definition: TCollection.cxx:50
Basic string class.
Definition: TString.h:125
virtual void Browse(TBrowser *b)
Browse object. May be overridden for another default action.
Definition: TObject.cxx:119
Short_t Range(Short_t lb, Short_t ub, Short_t x)
Definition: TMathBase.h:232
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:195
static TCollection * fgCurrentCollection
Definition: TCollection.h:132
TString fName
Definition: TCollection.h:147
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:550
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
void Reset()
Definition: TCollection.h:250
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
if object in a list can be deleted
Definition: TObject.h:58
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition: TObject.cxx:572
#define SafeDelete(p)
Definition: RConfig.h:509
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
TIterator * fIterator
Definition: TCollection.h:234
void AddVector(TObject *obj1,...)
Add all arguments to the collection.
#define va_(arg)
Definition: Varargs.h:41
virtual bool UseRWLock()
Set this collection to use a RW lock upon access, making it thread safe.
XFontStruct * id
Definition: TGX11.cxx:108
virtual void PrintCollectionEntry(TObject *entry, Option_t *option, Int_t recurse) const
Print the collection entry.
void Error(const char *location, const char *msgfmt,...)
object has not been deleted
Definition: TObject.h:78
virtual Bool_t IsEqual(const TObject *obj) const
Default equal comparison (objects are equal if they have the same address in memory).
Definition: TObject.cxx:483
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
TIter & operator=(const TIter &rhs)
Assigning an TIter to another.
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
virtual Int_t GrowBy(Int_t delta) const
Increase the collection&#39;s capacity by delta slots.
ROOT::R::TRInterface & r
Definition: Object.C:4
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
write collection with single key
Definition: TObject.h:87
SVector< double, 2 > v
Definition: Dict.h:5
static TCollection * GetCurrentCollection()
Return the globally accessible collection.
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const =0
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
Collection abstract base class.
Definition: TCollection.h:63
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Paint(Option_t *option="")
Paint all objects in this collection.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Ssiz_t Length() const
Definition: TString.h:386
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2746
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
static void StartGarbageCollection()
Set up for garbage collection.
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4688
This class registers all instances of TObject and its derived classes in a hash table.
Definition: TObjectTable.h:35
virtual Bool_t Notify()
&#39;Notify&#39; all objects in this collection.
void SetName(const char *name)
Definition: TCollection.h:202
void SetCurrentCollection()
Set this collection to be the globally accesible collection.
virtual void Dump() const
Dump all objects in this collection.
static Bool_t fgEmptyingGarbage
Definition: TCollection.h:134
static TIter End()
Pointing to the element after the last - to a nullptr value in our case.
#define R__LOCKGUARD2(mutex)
const Bool_t kFALSE
Definition: RtypesCore.h:88
void RemoveAll()
Definition: TCollection.h:200
static void GarbageCollect(TObject *obj)
Add to the list of things to be cleaned up.
#define ClassImp(name)
Definition: Rtypes.h:359
const TCollection & EmptyCollection()
Return an empty collection for use with nullptr TRangeCast.
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual ~TCollection()
TNamed destructor.
void Add(TObject *obj)
Add an object to the object table.
static TObjectTable * fgGarbageCollection
Definition: TCollection.h:133
virtual void Dump() const
Dump contents of object on stdout.
Definition: TObject.cxx:266
static constexpr double s
void Browse(TBrowser *b)
Browse this collection (called by TBrowser).
virtual void Add(TObject *obj)=0
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:396
static void EmptyGarbageCollection()
Do the garbage collection.
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:2887
Mother of all ROOT objects.
Definition: TObject.h:37
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:144
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition: TROOT.cxx:2738
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
virtual void PrintCollectionHeader(Option_t *option) const
Print the collection header.
Int_t Capacity() const
Definition: TCollection.h:165
const Int_t kMaxInt
Definition: RtypesCore.h:99
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Bool_t AssertClass(TClass *cl) const
Make sure all objects in this collection inherit from class cl.
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual Int_t GetSize() const
Definition: TCollection.h:180
void Delete(Option_t *opt="")
Delete all objects stored in the TObjectTable.
TObject * operator()(const char *name) const
Find an object in this collection by name.
#define R__FOR_EACH(type, proc)
Definition: TCollection.h:446
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
char name[80]
Definition: TGX11.cxx:109
virtual const char * GetName() const
Return name of this collection.
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
A spin mutex-as-code-guard class.
const char * Data() const
Definition: TString.h:345