1    	// @(#)root/cont:$Id$
2    	// Author: Fons Rademakers   11/09/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_TObjArray
13   	#define ROOT_TObjArray
14   	
15   	
16   	//////////////////////////////////////////////////////////////////////////
17   	//                                                                      //
18   	// TObjArray                                                            //
19   	//                                                                      //
20   	// An array of TObjects. The array expands automatically when adding    //
21   	// elements (shrinking can be done by hand).                            //
22   	//                                                                      //
23   	//////////////////////////////////////////////////////////////////////////
24   	
25   	#ifndef ROOT_TSeqCollection
26   	#include "TSeqCollection.h"
27   	#endif
28   	
29   	#include <iterator>
30   	
31   	#if (__GNUC__ >= 3) && !defined(__INTEL_COMPILER)
32   	// Prevent -Weffc++ from complaining about the inheritance
33   	// TObjArrayIter from std::iterator.
34   	#pragma GCC system_header
35   	#endif
36   	
37   	class TObjArrayIter;
38   	
39   	class TObjArray : public TSeqCollection {
40   	
41   	friend class TObjArrayIter;
42   	friend class TClonesArray;
43   	
44   	protected:
45   	   TObject     **fCont;        //!Array contents
46   	   Int_t         fLowerBound;  //Lower bound of the array
47   	   Int_t         fLast;        //Last element in array containing an object
48   	
49   	   Bool_t        BoundsOk(const char *where, Int_t at) const;
50   	   void          Init(Int_t s, Int_t lowerBound);
51   	   Bool_t        OutOfBoundsError(const char *where, Int_t i) const;
52   	   Int_t         GetAbsLast() const;
53   	
54   	public:
55   	   typedef TObjArrayIter Iterator_t;
56   	
57   	   TObjArray(Int_t s = TCollection::kInitCapacity, Int_t lowerBound = 0);
58   	   TObjArray(const TObjArray &a);
59   	   virtual          ~TObjArray();
60   	   TObjArray& operator=(const TObjArray&);
61   	   virtual void     Clear(Option_t *option="");
62   	   virtual void     Compress();
63   	   virtual void     Delete(Option_t *option="");
64   	   virtual void     Expand(Int_t newSize);   // expand or shrink an array
65   	   Int_t            GetEntries() const;
66   	   Int_t            GetEntriesFast() const {
67   	      return GetAbsLast() + 1;   //only OK when no gaps
68   	   }
69   	   Int_t            GetLast() const;
70   	   TObject        **GetObjectRef() const { return fCont; };
71   	   TObject        **GetObjectRef(const TObject *obj) const;
72   	   Bool_t           IsEmpty() const { return GetAbsLast() == -1; }
73   	   TIterator       *MakeIterator(Bool_t dir = kIterForward) const;
74   	
75   	   void             Add(TObject *obj) { AddLast(obj); }
76   	   virtual void     AddFirst(TObject *obj);
77   	   virtual void     AddLast(TObject *obj);
78   	   virtual void     AddAt(TObject *obj, Int_t idx);
79   	   virtual void     AddAtAndExpand(TObject *obj, Int_t idx);
80   	   virtual Int_t    AddAtFree(TObject *obj);
81   	   virtual void     AddAfter(const TObject *after, TObject *obj);
82   	   virtual void     AddBefore(const TObject *before, TObject *obj);
83   	   virtual TObject *FindObject(const char *name) const;
84   	   virtual TObject *FindObject(const TObject *obj) const;
85   	   virtual TObject *RemoveAt(Int_t idx);
86   	   virtual TObject *Remove(TObject *obj);
87   	   virtual void     RemoveRange(Int_t idx1, Int_t idx2);
88   	   virtual void     RecursiveRemove(TObject *obj);
89   	
90   	   TObject         *At(Int_t idx) const;
91   	   TObject         *UncheckedAt(Int_t i) const { return fCont[i-fLowerBound]; }
92   	   TObject         *Before(const TObject *obj) const;
93   	   TObject         *After(const TObject *obj) const;
94   	   TObject         *First() const;
95   	   TObject         *Last() const;
96   	   virtual TObject *&operator[](Int_t i);
97   	   virtual TObject *operator[](Int_t i) const;
98   	   Int_t            LowerBound() const { return fLowerBound; }
99   	   Int_t            IndexOf(const TObject *obj) const;
100  	   void             SetLast(Int_t last);
101  	
102  	   virtual void     Randomize(Int_t ntimes=1);
103  	   virtual void     Sort(Int_t upto = kMaxInt);
104  	   virtual Int_t    BinarySearch(TObject *obj, Int_t upto = kMaxInt); // the TObjArray has to be sorted, -1 == not found !!
105  	
106  	   ClassDef(TObjArray,3)  //An array of objects
107  	};
108  	
109  	
110  	// Preventing warnings with -Weffc++ in GCC since it is a false positive for the TObjArrayIter destructor.
111  	#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
112  	#pragma GCC diagnostic push
113  	#pragma GCC diagnostic ignored "-Weffc++"
114  	#endif
115  	
116  	//////////////////////////////////////////////////////////////////////////
117  	//                                                                      //
118  	// TObjArrayIter                                                        //
119  	//                                                                      //
120  	// Iterator of object array.                                            //
121  	//                                                                      //
122  	//////////////////////////////////////////////////////////////////////////
123  	
124  	class TObjArrayIter : public TIterator,
125  	                      public std::iterator<std::bidirectional_iterator_tag, // TODO: ideally it should be a  randomaccess_iterator_tag
126  	                                           TObject*, std::ptrdiff_t,
127  	                                           const TObject**, const TObject*&> {
128  	
129  	private:
130  	   const TObjArray  *fArray;     //array being iterated
131  	   Int_t             fCurCursor; //current position in array
132  	   Int_t             fCursor;    //next position in array
133  	   Bool_t            fDirection; //iteration direction
134  	
135  	   TObjArrayIter() : fArray(0), fCurCursor(0), fCursor(0), fDirection(kIterForward) { }
136  	
137  	public:
138  	   TObjArrayIter(const TObjArray *arr, Bool_t dir = kIterForward);
139  	   TObjArrayIter(const TObjArrayIter &iter);
140  	   ~TObjArrayIter() { }
141  	   TIterator     &operator=(const TIterator &rhs);
142  	   TObjArrayIter &operator=(const TObjArrayIter &rhs);
143  	
144  	   const TCollection *GetCollection() const { return fArray; }
145  	   TObject           *Next();
146  	   void               Reset();
147  	   Bool_t             operator!=(const TIterator &aIter) const;
148  	   Bool_t             operator!=(const TObjArrayIter &aIter) const;
149  	   TObject           *operator*() const;
150  	
151  	   ClassDef(TObjArrayIter,0)  //Object array iterator
152  	};
153  	
154  	#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
155  	#pragma GCC diagnostic pop
156  	#endif
157  	
158  	//---- inlines -----------------------------------------------------------------
159  	
160  	inline Bool_t TObjArray::BoundsOk(const char *where, Int_t at) const
161  	{
162  	   return (at < fLowerBound || at-fLowerBound >= fSize)
163  	                  ? OutOfBoundsError(where, at)
164  	                  : kTRUE;
165  	}
166  	
167  	inline TObject *TObjArray::At(Int_t i) const
168  	{
169  	   // Return the object at position i. Returns 0 if i is out of bounds.
170  	   int j = i-fLowerBound;
171  	   if (j >= 0 && j < fSize) return fCont[j];
172  	   BoundsOk("At", i);
173  	   return 0;
174  	}
175  	
176  	#endif
177