// @(#)root/cont:$Id$
// Author: Rene Brun    02/10/2001

/*************************************************************************
 * Copyright (C) 1995-2001, 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_TRefArray
#define ROOT_TRefArray


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRefArray                                                            //
//                                                                      //
// An array of references to TObjects.                                  //
// The array expands automatically when adding elements.                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

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

#include <iterator>

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

class TSystem;
class TRefArrayIter;

class TRefArray : public TSeqCollection {

friend class TRefArrayIter;

protected:
   TProcessID   *fPID;         //Pointer to Process Unique Identifier
   UInt_t       *fUIDs;        //[fSize] To store uids of referenced objects
   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;
   TObject      *GetFromTable(Int_t idx) const;
   Bool_t        GetObjectUID(Int_t &uid, TObject *obj, const char *methodname);

public:
   typedef TRefArrayIter Iterator_t;

   TRefArray(TProcessID *pid = 0);
   TRefArray(Int_t s, TProcessID *pid);
   TRefArray(Int_t s, Int_t lowerBound = 0, TProcessID *pid = 0);
   TRefArray(const TRefArray &a);
   TRefArray& operator=(const TRefArray &a);
   virtual          ~TRefArray();
   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 TObject *obj) const;
   TProcessID      *GetPID() const {return fPID;}
   UInt_t           GetUID(Int_t at) 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 *RemoveAt(Int_t idx);
   virtual TObject *Remove(TObject *obj);

   TObject         *At(Int_t idx) const;
   TObject         *Before(const TObject *obj) const;
   TObject         *After(const TObject *obj) const;
   TObject         *First() const;
   TObject         *Last() const;
   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     Sort(Int_t upto = kMaxInt);
   virtual Int_t    BinarySearch(TObject *obj, Int_t upto = kMaxInt); // the TRefArray has to be sorted, -1 == not found !!

   ClassDef(TRefArray,1)  //An array of references to TObjects
};


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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRefArrayIter                                                        //
//                                                                      //
// Iterator of object array.                                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TRefArrayIter : 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 TRefArray  *fArray;      //array being iterated
   Int_t             fCurCursor;  //current position in array
   Int_t             fCursor;     //next position in array
   Bool_t            fDirection;  //iteration direction

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

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

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

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

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


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

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

inline TObject *TRefArray::operator[](Int_t at) const
{
   int j = at-fLowerBound;
   if (j >= 0 && j < fSize) {
      if (!fPID) return 0;
      if (!TProcessID::IsValid(fPID)) return 0;
      TObject *obj = fPID->GetObjectWithID(fUIDs[j]);
      if (obj==0) obj = GetFromTable(j);
      return obj;
   }
   BoundsOk("At", at);
   return 0;
}

inline TObject *TRefArray::At(Int_t at) const
{
   // Return the object at position i. Returns 0 if i is out of bounds.
   int j = at-fLowerBound;
   if (j >= 0 && j < fSize) {
      if (!fPID) return 0;
      if (!TProcessID::IsValid(fPID)) return 0;
      TObject *obj = fPID->GetObjectWithID(fUIDs[j]);
      if (obj==0) obj = GetFromTable(j);
      return obj;
   }
   BoundsOk("At", at);
   return 0;
}

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