ROOT logo
// @(#)root/cont:$Id$
// Author: Fons Rademakers   13/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TCollection
#define ROOT_TCollection


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TCollection                                                          //
//                                                                      //
// Collection abstract base class. This class inherits from TObject     //
// because we want to be able to have collections of collections.       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif

#ifndef ROOT_TIterator
#include "TIterator.h"
#endif

#ifndef ROOT_TString
#include "TString.h"
#endif


class TClass;
class TObjectTable;
class TVirtualMutex;
class TIter;

const Bool_t kIterForward  = kTRUE;
const Bool_t kIterBackward = !kIterForward;

R__EXTERN TVirtualMutex *gCollectionMutex;

class TCollection : public TObject {

private:
   static TCollection  *fgCurrentCollection;  //used by macro R__FOR_EACH
   static TObjectTable *fgGarbageCollection;  //used by garbage collector
   static Bool_t        fgEmptyingGarbage;    //used by garbage collector
   static Int_t         fgGarbageStack;       //used by garbage collector

   TCollection(const TCollection &);    //private and not-implemented, collections
   void operator=(const TCollection &); //are too complex to be automatically copied

protected:
   enum { kIsOwner = BIT(14) };

   TString   fName;               //name of the collection
   Int_t     fSize;               //number of elements in collection

   TCollection() : fName(), fSize(0) { }

   virtual void        PrintCollectionHeader(Option_t* option) const;
   virtual const char* GetCollectionEntryName(TObject* entry) const;
   virtual void        PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const;

public:
   enum { kInitCapacity = 16, kInitHashTableCapacity = 17 };

   virtual            ~TCollection() { }
   virtual void       Add(TObject *obj) = 0;
   void               AddVector(TObject *obj1, ...);
   virtual void       AddAll(const TCollection *col);
   Bool_t             AssertClass(TClass *cl) const;
   void               Browse(TBrowser *b);
   Int_t              Capacity() const { return fSize; }
   virtual void       Clear(Option_t *option="") = 0;
   virtual TObject   *Clone(const char *newname="") const;
   Int_t              Compare(const TObject *obj) const;
   Bool_t             Contains(const char *name) const { return FindObject(name) != 0; }
   Bool_t             Contains(const TObject *obj) const { return FindObject(obj) != 0; }
   virtual void       Delete(Option_t *option="") = 0;
   virtual void       Draw(Option_t *option="");
   virtual void       Dump() const ;
   virtual TObject   *FindObject(const char *name) const;
   TObject           *operator()(const char *name) const;
   virtual TObject   *FindObject(const TObject *obj) const;
   virtual Int_t      GetEntries() const { return GetSize(); }
   virtual const char *GetName() const;
   virtual TObject  **GetObjectRef(const TObject *obj) const = 0;
   virtual Int_t      GetSize() const { return fSize; }
   virtual Int_t      GrowBy(Int_t delta) const;
   ULong_t            Hash() const { return fName.Hash(); }
   Bool_t             IsArgNull(const char *where, const TObject *obj) const;
   virtual Bool_t     IsEmpty() const { return GetSize() <= 0; }
   virtual Bool_t     IsFolder() const { return kTRUE; }
   Bool_t             IsOwner() const { return TestBit(kIsOwner); }
   Bool_t             IsSortable() const { return kTRUE; }
   virtual void       ls(Option_t *option="") const ;
   virtual TIterator *MakeIterator(Bool_t dir = kIterForward) const = 0;
   virtual TIterator *MakeReverseIterator() const { return MakeIterator(kIterBackward); }
   virtual void       Paint(Option_t *option="");
   virtual void       Print(Option_t *option="") const;
   virtual void       Print(Option_t *option, Int_t recurse) const;
   virtual void       Print(Option_t *option, const char* wildcard, Int_t recurse=1) const;
   virtual void       Print(Option_t *option, TPRegexp& regexp, Int_t recurse=1) const;
   virtual void       RecursiveRemove(TObject *obj);
   virtual TObject   *Remove(TObject *obj) = 0;
   virtual void       RemoveAll(TCollection *col);
   void               RemoveAll() { Clear(); }
   void               SetCurrentCollection();
   void               SetName(const char *name) { fName = name; }
   virtual void       SetOwner(Bool_t enable = kTRUE);
   virtual Int_t      Write(const char *name=0, Int_t option=0, Int_t bufsize=0);
   virtual Int_t      Write(const char *name=0, Int_t option=0, Int_t bufsize=0) const;

   static TCollection  *GetCurrentCollection();
   static void          StartGarbageCollection();
   static void          GarbageCollect(TObject *obj);
   static void          EmptyGarbageCollection();

   TIter begin() const;
   TIter end() const;

   ClassDef(TCollection,3)  //Collection abstract base class
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TIter                                                                //
//                                                                      //
// Iterator wrapper. Type of iterator used depends on type of           //
// collection.                                                          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TIter {

private:
   TIterator    *fIterator;         //collection iterator

protected:
   TIter() : fIterator(nullptr) { }

public:
   TIter(const TCollection *col, Bool_t dir = kIterForward)
         : fIterator(col ? col->MakeIterator(dir) : 0) { }
   TIter(TIterator *it) : fIterator(it) { }
   TIter(const TIter &iter);
   TIter &operator=(const TIter &rhs);
   virtual ~TIter() { SafeDelete(fIterator); }
   TObject           *operator()() { return Next(); }
   TObject           *Next() { return fIterator ? fIterator->Next() : nullptr; }
   const TCollection *GetCollection() const { return fIterator ? fIterator->GetCollection() : nullptr; }
   Option_t          *GetOption() const { return fIterator ? fIterator->GetOption() : ""; }
   void               Reset() { if (fIterator) fIterator->Reset(); }
   TIter             &operator++() { Next(); return *this; }
   Bool_t             operator==(const TIter &aIter) const {
      if (fIterator == nullptr)
         return aIter.fIterator == nullptr || **aIter.fIterator == nullptr;
      if (aIter.fIterator == nullptr)
         return fIterator == nullptr || **fIterator == nullptr;
      return *fIterator == *aIter.fIterator;
   }
   Bool_t             operator!=(const TIter &aIter) const {
      return !(*this == aIter);
   }
   TObject           *operator*() const { return fIterator ? *(*fIterator): nullptr; }
   TIter             &Begin();
   static TIter       End();

   ClassDef(TIter,0)  //Iterator wrapper
};

template <class T>
class TIterCategory: public TIter, public std::iterator_traits<typename T::Iterator_t> {

public:
   TIterCategory(const TCollection *col, Bool_t dir = kIterForward) : TIter(col, dir) { }
   TIterCategory(TIterator *it) : TIter(it) { }
   virtual ~TIterCategory() { }
   TIterCategory &Begin() { TIter::Begin(); return *this; }
   static TIterCategory End() { return TIterCategory(static_cast<TIterator*>(nullptr)); }
};


inline TIter TCollection::begin() const { return ++(TIter(this)); }
inline TIter TCollection::end() const { return TIter::End(); }


//---- R__FOR_EACH macro -------------------------------------------------------

// Macro to loop over all elements of a list of type "type" while executing
// procedure "proc" on each element

#define R__FOR_EACH(type,proc) \
    SetCurrentCollection(); \
    TIter _NAME3_(nxt_,type,proc)(TCollection::GetCurrentCollection()); \
    type *_NAME3_(obj_,type,proc); \
    while ((_NAME3_(obj_,type,proc) = (type*) _NAME3_(nxt_,type,proc)())) \
       _NAME3_(obj_,type,proc)->proc

#endif
 TCollection.h:1
 TCollection.h:2
 TCollection.h:3
 TCollection.h:4
 TCollection.h:5
 TCollection.h:6
 TCollection.h:7
 TCollection.h:8
 TCollection.h:9
 TCollection.h:10
 TCollection.h:11
 TCollection.h:12
 TCollection.h:13
 TCollection.h:14
 TCollection.h:15
 TCollection.h:16
 TCollection.h:17
 TCollection.h:18
 TCollection.h:19
 TCollection.h:20
 TCollection.h:21
 TCollection.h:22
 TCollection.h:23
 TCollection.h:24
 TCollection.h:25
 TCollection.h:26
 TCollection.h:27
 TCollection.h:28
 TCollection.h:29
 TCollection.h:30
 TCollection.h:31
 TCollection.h:32
 TCollection.h:33
 TCollection.h:34
 TCollection.h:35
 TCollection.h:36
 TCollection.h:37
 TCollection.h:38
 TCollection.h:39
 TCollection.h:40
 TCollection.h:41
 TCollection.h:42
 TCollection.h:43
 TCollection.h:44
 TCollection.h:45
 TCollection.h:46
 TCollection.h:47
 TCollection.h:48
 TCollection.h:49
 TCollection.h:50
 TCollection.h:51
 TCollection.h:52
 TCollection.h:53
 TCollection.h:54
 TCollection.h:55
 TCollection.h:56
 TCollection.h:57
 TCollection.h:58
 TCollection.h:59
 TCollection.h:60
 TCollection.h:61
 TCollection.h:62
 TCollection.h:63
 TCollection.h:64
 TCollection.h:65
 TCollection.h:66
 TCollection.h:67
 TCollection.h:68
 TCollection.h:69
 TCollection.h:70
 TCollection.h:71
 TCollection.h:72
 TCollection.h:73
 TCollection.h:74
 TCollection.h:75
 TCollection.h:76
 TCollection.h:77
 TCollection.h:78
 TCollection.h:79
 TCollection.h:80
 TCollection.h:81
 TCollection.h:82
 TCollection.h:83
 TCollection.h:84
 TCollection.h:85
 TCollection.h:86
 TCollection.h:87
 TCollection.h:88
 TCollection.h:89
 TCollection.h:90
 TCollection.h:91
 TCollection.h:92
 TCollection.h:93
 TCollection.h:94
 TCollection.h:95
 TCollection.h:96
 TCollection.h:97
 TCollection.h:98
 TCollection.h:99
 TCollection.h:100
 TCollection.h:101
 TCollection.h:102
 TCollection.h:103
 TCollection.h:104
 TCollection.h:105
 TCollection.h:106
 TCollection.h:107
 TCollection.h:108
 TCollection.h:109
 TCollection.h:110
 TCollection.h:111
 TCollection.h:112
 TCollection.h:113
 TCollection.h:114
 TCollection.h:115
 TCollection.h:116
 TCollection.h:117
 TCollection.h:118
 TCollection.h:119
 TCollection.h:120
 TCollection.h:121
 TCollection.h:122
 TCollection.h:123
 TCollection.h:124
 TCollection.h:125
 TCollection.h:126
 TCollection.h:127
 TCollection.h:128
 TCollection.h:129
 TCollection.h:130
 TCollection.h:131
 TCollection.h:132
 TCollection.h:133
 TCollection.h:134
 TCollection.h:135
 TCollection.h:136
 TCollection.h:137
 TCollection.h:138
 TCollection.h:139
 TCollection.h:140
 TCollection.h:141
 TCollection.h:142
 TCollection.h:143
 TCollection.h:144
 TCollection.h:145
 TCollection.h:146
 TCollection.h:147
 TCollection.h:148
 TCollection.h:149
 TCollection.h:150
 TCollection.h:151
 TCollection.h:152
 TCollection.h:153
 TCollection.h:154
 TCollection.h:155
 TCollection.h:156
 TCollection.h:157
 TCollection.h:158
 TCollection.h:159
 TCollection.h:160
 TCollection.h:161
 TCollection.h:162
 TCollection.h:163
 TCollection.h:164
 TCollection.h:165
 TCollection.h:166
 TCollection.h:167
 TCollection.h:168
 TCollection.h:169
 TCollection.h:170
 TCollection.h:171
 TCollection.h:172
 TCollection.h:173
 TCollection.h:174
 TCollection.h:175
 TCollection.h:176
 TCollection.h:177
 TCollection.h:178
 TCollection.h:179
 TCollection.h:180
 TCollection.h:181
 TCollection.h:182
 TCollection.h:183
 TCollection.h:184
 TCollection.h:185
 TCollection.h:186
 TCollection.h:187
 TCollection.h:188
 TCollection.h:189
 TCollection.h:190
 TCollection.h:191
 TCollection.h:192
 TCollection.h:193
 TCollection.h:194
 TCollection.h:195
 TCollection.h:196
 TCollection.h:197
 TCollection.h:198
 TCollection.h:199
 TCollection.h:200
 TCollection.h:201
 TCollection.h:202
 TCollection.h:203
 TCollection.h:204
 TCollection.h:205
 TCollection.h:206
 TCollection.h:207
 TCollection.h:208