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 #ifndef ROOT_TCollection 13 #define ROOT_TCollection 14 15 16 ////////////////////////////////////////////////////////////////////////// 17 // // 18 // TCollection // 19 // // 20 // Collection abstract base class. This class inherits from TObject // 21 // because we want to be able to have collections of collections. // 22 // // 23 ////////////////////////////////////////////////////////////////////////// 24 25 #ifndef ROOT_TObject 26 #include "TObject.h" 27 #endif 28 29 #ifndef ROOT_TIterator 30 #include "TIterator.h" 31 #endif 32 33 #ifndef ROOT_TString 34 #include "TString.h" 35 #endif 36 37 38 class TClass; 39 class TObjectTable; 40 class TVirtualMutex; 41 class TIter; 42 43 const Bool_t kIterForward = kTRUE; 44 const Bool_t kIterBackward = !kIterForward; 45 46 R__EXTERN TVirtualMutex *gCollectionMutex; 47 48 class TCollection : public TObject { 49 50 private: 51 static TCollection *fgCurrentCollection; //used by macro R__FOR_EACH 52 static TObjectTable *fgGarbageCollection; //used by garbage collector 53 static Bool_t fgEmptyingGarbage; //used by garbage collector 54 static Int_t fgGarbageStack; //used by garbage collector 55 56 TCollection(const TCollection &); //private and not-implemented, collections 57 void operator=(const TCollection &); //are too complex to be automatically copied 58 59 protected: 60 enum { kIsOwner = BIT(14) }; 61 62 TString fName; //name of the collection 63 Int_t fSize; //number of elements in collection 64 65 TCollection() : fName(), fSize(0) { } 66 67 virtual void PrintCollectionHeader(Option_t* option) const; 68 virtual const char* GetCollectionEntryName(TObject* entry) const; 69 virtual void PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const; 70 71 public: 72 enum { kInitCapacity = 16, kInitHashTableCapacity = 17 }; 73 74 virtual ~TCollection() { } 75 virtual void Add(TObject *obj) = 0; 76 void AddVector(TObject *obj1, ...); 77 virtual void AddAll(const TCollection *col); 78 Bool_t AssertClass(TClass *cl) const; 79 void Browse(TBrowser *b); 80 Int_t Capacity() const { return fSize; } 81 virtual void Clear(Option_t *option="") = 0; 82 virtual TObject *Clone(const char *newname="") const; 83 Int_t Compare(const TObject *obj) const; 84 Bool_t Contains(const char *name) const { return FindObject(name) != 0; } 85 Bool_t Contains(const TObject *obj) const { return FindObject(obj) != 0; } 86 virtual void Delete(Option_t *option="") = 0; 87 virtual void Draw(Option_t *option=""); 88 virtual void Dump() const ; 89 virtual TObject *FindObject(const char *name) const; 90 TObject *operator()(const char *name) const; 91 virtual TObject *FindObject(const TObject *obj) const; 92 virtual Int_t GetEntries() const { return GetSize(); } 93 virtual const char *GetName() const; 94 virtual TObject **GetObjectRef(const TObject *obj) const = 0; 95 virtual Int_t GetSize() const { return fSize; } 96 virtual Int_t GrowBy(Int_t delta) const; 97 ULong_t Hash() const { return fName.Hash(); } 98 Bool_t IsArgNull(const char *where, const TObject *obj) const; 99 virtual Bool_t IsEmpty() const { return GetSize() <= 0; } 100 virtual Bool_t IsFolder() const { return kTRUE; } 101 Bool_t IsOwner() const { return TestBit(kIsOwner); } 102 Bool_t IsSortable() const { return kTRUE; } 103 virtual void ls(Option_t *option="") const ; 104 virtual TIterator *MakeIterator(Bool_t dir = kIterForward) const = 0; 105 virtual TIterator *MakeReverseIterator() const { return MakeIterator(kIterBackward); } 106 virtual void Paint(Option_t *option=""); 107 virtual void Print(Option_t *option="") const; 108 virtual void Print(Option_t *option, Int_t recurse) const; 109 virtual void Print(Option_t *option, const char* wildcard, Int_t recurse=1) const; 110 virtual void Print(Option_t *option, TPRegexp& regexp, Int_t recurse=1) const; 111 virtual void RecursiveRemove(TObject *obj); 112 virtual TObject *Remove(TObject *obj) = 0; 113 virtual void RemoveAll(TCollection *col); 114 void RemoveAll() { Clear(); } 115 void SetCurrentCollection(); 116 void SetName(const char *name) { fName = name; } 117 virtual void SetOwner(Bool_t enable = kTRUE); 118 virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0); 119 virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0) const; 120 121 static TCollection *GetCurrentCollection(); 122 static void StartGarbageCollection(); 123 static void GarbageCollect(TObject *obj); 124 static void EmptyGarbageCollection(); 125 126 TIter begin() const; 127 TIter end() const; 128 129 ClassDef(TCollection,3) //Collection abstract base class 130 }; 131 132 133 ////////////////////////////////////////////////////////////////////////// 134 // // 135 // TIter // 136 // // 137 // Iterator wrapper. Type of iterator used depends on type of // 138 // collection. // 139 // // 140 ////////////////////////////////////////////////////////////////////////// 141 142 class TIter { 143 144 private: 145 TIterator *fIterator; //collection iterator 146 147 protected: 148 TIter() : fIterator(nullptr) { } 149 150 public: 151 TIter(const TCollection *col, Bool_t dir = kIterForward) 152 : fIterator(col ? col->MakeIterator(dir) : 0) { } 153 TIter(TIterator *it) : fIterator(it) { } 154 TIter(const TIter &iter); 155 TIter &operator=(const TIter &rhs); 156 virtual ~TIter() { SafeDelete(fIterator); } 157 TObject *operator()() { return Next(); } 158 TObject *Next() { return fIterator ? fIterator->Next() : nullptr; } 159 const TCollection *GetCollection() const { return fIterator ? fIterator->GetCollection() : nullptr; } 160 Option_t *GetOption() const { return fIterator ? fIterator->GetOption() : ""; } 161 void Reset() { if (fIterator) fIterator->Reset(); } 162 TIter &operator++() { Next(); return *this; } 163 Bool_t operator==(const TIter &aIter) const { 164 if (fIterator == nullptr) 165 return aIter.fIterator == nullptr || **aIter.fIterator == nullptr; 166 if (aIter.fIterator == nullptr) 167 return fIterator == nullptr || **fIterator == nullptr; 168 return *fIterator == *aIter.fIterator; 169 } 170 Bool_t operator!=(const TIter &aIter) const { 171 return !(*this == aIter); 172 } 173 TObject *operator*() const { return fIterator ? *(*fIterator): nullptr; } 174 TIter &Begin(); 175 static TIter End(); 176 177 ClassDef(TIter,0) //Iterator wrapper 178 }; 179 180 template <class T> 181 class TIterCategory: public TIter, public std::iterator_traits<typename T::Iterator_t> { 182 183 public: 184 TIterCategory(const TCollection *col, Bool_t dir = kIterForward) : TIter(col, dir) { } 185 TIterCategory(TIterator *it) : TIter(it) { } 186 virtual ~TIterCategory() { } 187 TIterCategory &Begin() { TIter::Begin(); return *this; } 188 static TIterCategory End() { return TIterCategory(static_cast<TIterator*>(nullptr)); } 189 }; 190 191 192 inline TIter TCollection::begin() const { return ++(TIter(this)); } 193 inline TIter TCollection::end() const { return TIter::End(); } 194 195 196 //---- R__FOR_EACH macro ------------------------------------------------------- 197 198 // Macro to loop over all elements of a list of type "type" while executing 199 // procedure "proc" on each element 200 201 #define R__FOR_EACH(type,proc) \ 202 SetCurrentCollection(); \ 203 TIter _NAME3_(nxt_,type,proc)(TCollection::GetCurrentCollection()); \ 204 type *_NAME3_(obj_,type,proc); \ 205 while ((_NAME3_(obj_,type,proc) = (type*) _NAME3_(nxt_,type,proc)())) \ 206 _NAME3_(obj_,type,proc)->proc 207 208 #endif 209