Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:30:16

0001 // @(#)root/cont:$Id$
0002 // Author: Rene Brun    02/10/2001
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TRefArray
0013 #define ROOT_TRefArray
0014 
0015 
0016 //////////////////////////////////////////////////////////////////////////
0017 //                                                                      //
0018 // TRefArray                                                            //
0019 //                                                                      //
0020 // An array of references to TObjects.                                  //
0021 // The array expands automatically when adding elements.                //
0022 //                                                                      //
0023 //////////////////////////////////////////////////////////////////////////
0024 
0025 #include "TSeqCollection.h"
0026 #include "TProcessID.h"
0027 
0028 #include <iterator>
0029 
0030 class TSystem;
0031 class TRefArrayIter;
0032 
0033 class TRefArray : public TSeqCollection {
0034 
0035 friend class TRefArrayIter;
0036 
0037 protected:
0038    TProcessID   *fPID;         //Pointer to Process Unique Identifier
0039    UInt_t       *fUIDs;        //[fSize] To store uids of referenced objects
0040    Int_t         fLowerBound;  //Lower bound of the array
0041    Int_t         fLast;        //Last element in array containing an object
0042 
0043    Bool_t        BoundsOk(const char *where, Int_t at) const;
0044    void          Init(Int_t s, Int_t lowerBound);
0045    Bool_t        OutOfBoundsError(const char *where, Int_t i) const;
0046    Int_t         GetAbsLast() const;
0047    TObject      *GetFromTable(Int_t idx) const;
0048    Bool_t        GetObjectUID(Int_t &uid, TObject *obj, const char *methodname);
0049 
0050 public:
0051    typedef TRefArrayIter Iterator_t;
0052 
0053    TRefArray(TProcessID *pid = nullptr);
0054    TRefArray(Int_t s, TProcessID *pid);
0055    TRefArray(Int_t s, Int_t lowerBound = 0, TProcessID *pid = nullptr);
0056    TRefArray(const TRefArray &a);
0057    TRefArray& operator=(const TRefArray &a);
0058    virtual          ~TRefArray();
0059    void             Clear(Option_t *option="") override;
0060    virtual void     Compress();
0061    void             Delete(Option_t *option="") override;
0062    virtual void     Expand(Int_t newSize);   // expand or shrink an array
0063    Int_t            GetEntries() const override;
0064    Int_t            GetEntriesFast() const {
0065       return GetAbsLast() + 1;   //only OK when no gaps
0066    }
0067    Int_t            GetLast() const override;
0068    TObject        **GetObjectRef(const TObject *obj) const override;
0069    TProcessID      *GetPID() const {return fPID;}
0070    UInt_t           GetUID(Int_t at) const;
0071    Bool_t           IsEmpty() const  override { return GetAbsLast() == -1; }
0072    TIterator       *MakeIterator(Bool_t dir = kIterForward) const override;
0073 
0074    void             Add(TObject *obj) override { AddLast(obj); }
0075    void             AddFirst(TObject *obj) override;
0076    void             AddLast(TObject *obj) override;
0077    void             AddAt(TObject *obj, Int_t idx) override;
0078    virtual void     AddAtAndExpand(TObject *obj, Int_t idx);
0079    virtual Int_t    AddAtFree(TObject *obj);
0080    void             AddAfter(const TObject *after, TObject *obj) override;
0081    void             AddBefore(const TObject *before, TObject *obj) override;
0082    TObject         *RemoveAt(Int_t idx) override;
0083    TObject         *Remove(TObject *obj) override;
0084 
0085    TObject         *At(Int_t idx) const override;
0086    TObject         *Before(const TObject *obj) const override;
0087    TObject         *After(const TObject *obj) const override;
0088    TObject         *First() const override;
0089    TObject         *Last() const override;
0090    virtual TObject *operator[](Int_t i) const;
0091    Int_t            LowerBound() const { return fLowerBound; }
0092    Int_t            IndexOf(const TObject *obj) const override;
0093    void             SetLast(Int_t last);
0094 
0095    virtual void     Sort(Int_t upto = kMaxInt);
0096    virtual Int_t    BinarySearch(TObject *obj, Int_t upto = kMaxInt); // the TRefArray has to be sorted, -1 == not found !!
0097 
0098    ClassDefOverride(TRefArray,1)  //An array of references to TObjects
0099 };
0100 
0101 
0102 // Preventing warnings with -Weffc++ in GCC since it is a false positive for the TRefArrayIter destructor.
0103 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
0104 #pragma GCC diagnostic push
0105 #pragma GCC diagnostic ignored "-Weffc++"
0106 #endif
0107 
0108 //////////////////////////////////////////////////////////////////////////
0109 //                                                                      //
0110 // TRefArrayIter                                                        //
0111 //                                                                      //
0112 // Iterator of object array.                                            //
0113 //                                                                      //
0114 //////////////////////////////////////////////////////////////////////////
0115 
0116 class TRefArrayIter : public TIterator {
0117 
0118 private:
0119    const TRefArray  *fArray;      //array being iterated
0120    Int_t             fCurCursor;  //current position in array
0121    Int_t             fCursor;     //next position in array
0122    Bool_t            fDirection;  //iteration direction
0123 
0124    TRefArrayIter() : fArray(nullptr), fCurCursor(0), fCursor(0), fDirection(kIterForward) {}
0125 
0126 public:
0127    using iterator_category = std::bidirectional_iterator_tag; // TODO: ideally it should be a randomaccess_iterator_tag
0128    using value_type = TObject *;
0129    using difference_type = std::ptrdiff_t;
0130    using pointer = TObject **;
0131    using const_pointer = const TObject **;
0132    using reference = const TObject *&;
0133 
0134    TRefArrayIter(const TRefArray *arr, Bool_t dir = kIterForward);
0135    TRefArrayIter(const TRefArrayIter &iter);
0136    ~TRefArrayIter() { }
0137    TIterator         &operator=(const TIterator &rhs) override;
0138    TRefArrayIter     &operator=(const TRefArrayIter &rhs);
0139 
0140    const TCollection *GetCollection() const override { return fArray; }
0141    TObject           *Next() override;
0142    void               Reset() override;
0143    Bool_t             operator!=(const TIterator &aIter) const override;
0144    Bool_t             operator!=(const TRefArrayIter &aIter) const;
0145    TObject           *operator*() const override;
0146 
0147    ClassDefOverride(TRefArrayIter,0)  //Object array iterator
0148 };
0149 
0150 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
0151 #pragma GCC diagnostic pop
0152 #endif
0153 
0154 
0155 //---- inlines -----------------------------------------------------------------
0156 
0157 inline Bool_t TRefArray::BoundsOk(const char *where, Int_t at) const
0158 {
0159    return (at < fLowerBound || at-fLowerBound >= fSize)
0160                   ? OutOfBoundsError(where, at)
0161                   : kTRUE;
0162 }
0163 
0164 inline TObject *TRefArray::operator[](Int_t at) const
0165 {
0166    int j = at-fLowerBound;
0167    if (j >= 0 && j < fSize) {
0168       if (!fPID) return nullptr;
0169       if (!TProcessID::IsValid(fPID)) return nullptr;
0170       TObject *obj = fPID->GetObjectWithID(fUIDs[j]);
0171       if (!obj) obj = GetFromTable(j);
0172       return obj;
0173    }
0174    BoundsOk("At", at);
0175    return nullptr;
0176 }
0177 
0178 inline TObject *TRefArray::At(Int_t at) const
0179 {
0180    // Return the object at position i. Returns 0 if i is out of bounds.
0181    int j = at-fLowerBound;
0182    if (j >= 0 && j < fSize) {
0183       if (!fPID) return nullptr;
0184       if (!TProcessID::IsValid(fPID)) return nullptr;
0185       TObject *obj = fPID->GetObjectWithID(fUIDs[j]);
0186       if (!obj) obj = GetFromTable(j);
0187       return obj;
0188    }
0189    BoundsOk("At", at);
0190    return nullptr;
0191 }
0192 
0193 #endif