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