// @(#)root/cont:$Id$
// Author: Fons Rademakers   11/09/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_TObjArray
#define ROOT_TObjArray


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TObjArray                                                            //
//                                                                      //
// An array of TObjects. The array expands automatically when adding    //
// elements (shrinking can be done by hand).                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TSeqCollection
#include "TSeqCollection.h"
#endif

#include <iterator>

#if (__GNUC__ >= 3) && !defined(__INTEL_COMPILER)
// Prevent -Weffc++ from complaining about the inheritance
// TObjArrayIter from std::iterator.
#pragma GCC system_header
#endif

class TObjArrayIter;

class TObjArray : public TSeqCollection {

friend class TObjArrayIter;
friend class TClonesArray;

protected:
   TObject     **fCont;        //!Array contents
   Int_t         fLowerBound;  //Lower bound of the array
   Int_t         fLast;        //Last element in array containing an object

   Bool_t        BoundsOk(const char *where, Int_t at) const;
   void          Init(Int_t s, Int_t lowerBound);
   Bool_t        OutOfBoundsError(const char *where, Int_t i) const;
   Int_t         GetAbsLast() const;

public:
   typedef TObjArrayIter Iterator_t;

   TObjArray(Int_t s = TCollection::kInitCapacity, Int_t lowerBound = 0);
   TObjArray(const TObjArray &a);
   virtual          ~TObjArray();
   TObjArray& operator=(const TObjArray&);
   virtual void     Clear(Option_t *option="");
   virtual void     Compress();
   virtual void     Delete(Option_t *option="");
   virtual void     Expand(Int_t newSize);   // expand or shrink an array
   Int_t            GetEntries() const;
   Int_t            GetEntriesFast() const {
      return GetAbsLast() + 1;   //only OK when no gaps
   }
   Int_t            GetLast() const;
   TObject        **GetObjectRef() const { return fCont; };
   TObject        **GetObjectRef(const TObject *obj) const;
   Bool_t           IsEmpty() const { return GetAbsLast() == -1; }
   TIterator       *MakeIterator(Bool_t dir = kIterForward) const;

   void             Add(TObject *obj) { AddLast(obj); }
   virtual void     AddFirst(TObject *obj);
   virtual void     AddLast(TObject *obj);
   virtual void     AddAt(TObject *obj, Int_t idx);
   virtual void     AddAtAndExpand(TObject *obj, Int_t idx);
   virtual Int_t    AddAtFree(TObject *obj);
   virtual void     AddAfter(const TObject *after, TObject *obj);
   virtual void     AddBefore(const TObject *before, TObject *obj);
   virtual TObject *FindObject(const char *name) const;
   virtual TObject *FindObject(const TObject *obj) const;
   virtual TObject *RemoveAt(Int_t idx);
   virtual TObject *Remove(TObject *obj);
   virtual void     RemoveRange(Int_t idx1, Int_t idx2);
   virtual void     RecursiveRemove(TObject *obj);

   TObject         *At(Int_t idx) const;
   TObject         *UncheckedAt(Int_t i) const { return fCont[i-fLowerBound]; }
   TObject         *Before(const TObject *obj) const;
   TObject         *After(const TObject *obj) const;
   TObject         *First() const;
   TObject         *Last() const;
   virtual TObject *&operator[](Int_t i);
   virtual TObject *operator[](Int_t i) const;
   Int_t            LowerBound() const { return fLowerBound; }
   Int_t            IndexOf(const TObject *obj) const;
   void             SetLast(Int_t last);

   virtual void     Randomize(Int_t ntimes=1);
   virtual void     Sort(Int_t upto = kMaxInt);
   virtual Int_t    BinarySearch(TObject *obj, Int_t upto = kMaxInt); // the TObjArray has to be sorted, -1 == not found !!

   ClassDef(TObjArray,3)  //An array of objects
};


// Preventing warnings with -Weffc++ in GCC since it is a false positive for the TObjArrayIter destructor.
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#endif

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TObjArrayIter                                                        //
//                                                                      //
// Iterator of object array.                                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TObjArrayIter : public TIterator,
                      public std::iterator<std::bidirectional_iterator_tag, // TODO: ideally it should be a  randomaccess_iterator_tag
                                           TObject*, std::ptrdiff_t,
                                           const TObject**, const TObject*&> {

private:
   const TObjArray  *fArray;     //array being iterated
   Int_t             fCurCursor; //current position in array
   Int_t             fCursor;    //next position in array
   Bool_t            fDirection; //iteration direction

   TObjArrayIter() : fArray(0), fCurCursor(0), fCursor(0), fDirection(kIterForward) { }

public:
   TObjArrayIter(const TObjArray *arr, Bool_t dir = kIterForward);
   TObjArrayIter(const TObjArrayIter &iter);
   ~TObjArrayIter() { }
   TIterator     &operator=(const TIterator &rhs);
   TObjArrayIter &operator=(const TObjArrayIter &rhs);

   const TCollection *GetCollection() const { return fArray; }
   TObject           *Next();
   void               Reset();
   Bool_t             operator!=(const TIterator &aIter) const;
   Bool_t             operator!=(const TObjArrayIter &aIter) const;
   TObject           *operator*() const;

   ClassDef(TObjArrayIter,0)  //Object array iterator
};

#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
#pragma GCC diagnostic pop
#endif

//---- inlines -----------------------------------------------------------------

inline Bool_t TObjArray::BoundsOk(const char *where, Int_t at) const
{
   return (at < fLowerBound || at-fLowerBound >= fSize)
                  ? OutOfBoundsError(where, at)
                  : kTRUE;
}

inline TObject *TObjArray::At(Int_t i) const
{
   // Return the object at position i. Returns 0 if i is out of bounds.
   int j = i-fLowerBound;
   if (j >= 0 && j < fSize) return fCont[j];
   BoundsOk("At", i);
   return 0;
}

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