#include "TList.h"
#include <string>
namespace std {} using namespace std;
ClassImp(TList)
TList::~TList()
{
   
   
   Clear();
}
void TList::AddFirst(TObject *obj)
{
   
   if (IsArgNull("AddFirst", obj)) return;
   if (!fFirst) {
      fFirst = NewLink(obj);
      fLast = fFirst;
   } else {
      TObjLink *t = NewLink(obj);
      t->fNext = fFirst;
      fFirst->fPrev = t;
      fFirst = t;
   }
   fSize++;
   Changed();
}
void TList::AddFirst(TObject *obj, Option_t *opt)
{
   
   
   
   
   
   if (IsArgNull("AddFirst", obj)) return;
   if (!fFirst) {
      fFirst = NewOptLink(obj, opt);
      fLast = fFirst;
   } else {
      TObjLink *t = NewOptLink(obj, opt);
      t->fNext = fFirst;
      fFirst->fPrev = t;
      fFirst = t;
   }
   fSize++;
   Changed();
}
void TList::AddLast(TObject *obj)
{
   
   if (IsArgNull("AddLast", obj)) return;
   if (!fFirst) {
      fFirst = NewLink(obj);
      fLast  = fFirst;
   } else
      fLast = NewLink(obj, fLast);
   fSize++;
   Changed();
}
void TList::AddLast(TObject *obj, Option_t *opt)
{
   
   
   
   
   
   if (IsArgNull("AddLast", obj)) return;
   if (!fFirst) {
      fFirst = NewOptLink(obj, opt);
      fLast  = fFirst;
   } else
      fLast = NewOptLink(obj, opt, fLast);
   fSize++;
   Changed();
}
void TList::AddBefore(const TObject *before, TObject *obj)
{
   
   if (IsArgNull("AddBefore", obj)) return;
   if (!before)
      TList::AddFirst(obj);
   else {
      Int_t    idx;
      TObjLink *t = FindLink(before, idx);
      if (!t) {
         Error("AddBefore", "before not found, object not added");
         return;
      }
      if (t == fFirst)
         TList::AddFirst(obj);
      else {
         NewLink(obj, t->Prev());
         fSize++;
         Changed();
      }
   }
}
void TList::AddBefore(TObjLink *before, TObject *obj)
{
   
   
   
   if (IsArgNull("AddBefore", obj)) return;
   if (!before)
      TList::AddFirst(obj);
   else {
      if (before == fFirst)
         TList::AddFirst(obj);
      else {
         NewLink(obj, before->Prev());
         fSize++;
         Changed();
      }
   }
}
void TList::AddAfter(const TObject *after, TObject *obj)
{
   
   if (IsArgNull("AddAfter", obj)) return;
   if (!after)
      TList::AddLast(obj);
   else {
      Int_t    idx;
      TObjLink *t = FindLink(after, idx);
      if (!t) {
         Error("AddAfter", "after not found, object not added");
         return;
      }
      if (t == fLast)
         TList::AddLast(obj);
      else {
         NewLink(obj, t);
         fSize++;
         Changed();
      }
   }
}
void TList::AddAfter(TObjLink *after, TObject *obj)
{
   
   
   
   if (IsArgNull("AddAfter", obj)) return;
   if (!after)
      TList::AddLast(obj);
   else {
      if (after == fLast)
         TList::AddLast(obj);
      else {
         NewLink(obj, after);
         fSize++;
         Changed();
      }
   }
}
void TList::AddAt(TObject *obj, Int_t idx)
{
   
   if (IsArgNull("AddAt", obj)) return;
   TObjLink *lnk = LinkAt(idx);
   if (!lnk)
      TList::AddLast(obj);
   else if (lnk == fFirst)
      TList::AddFirst(obj);
   else {
      NewLink(obj, lnk->Prev());
      fSize++;
      Changed();
   }
}
TObject *TList::After(const TObject *obj) const
{
   
   
   TObjLink *t;
   if (fCache && fCache->GetObject() && fCache->GetObject()->IsEqual(obj)) {
      t = fCache;
      ((TList*)this)->fCache = fCache->Next();  
   } else {
      Int_t idx;
      t = FindLink(obj, idx);
      if (t) ((TList*)this)->fCache = t->Next();
   }
   if (t && t->Next())
      return t->Next()->GetObject();
   else
      return 0;
}
TObject *TList::At(Int_t idx) const
{
   
   TObjLink *lnk = LinkAt(idx);
   if (lnk) return lnk->GetObject();
   return 0;
}
TObject *TList::Before(const TObject *obj) const
{
   
   
   TObjLink *t;
   if (fCache && fCache->GetObject() && fCache->GetObject()->IsEqual(obj)) {
      t = fCache;
      ((TList*)this)->fCache = fCache->Prev();  
   } else {
      Int_t idx;
      t = FindLink(obj, idx);
      if (t) ((TList*)this)->fCache = t->Prev();
   }
   if (t && t->Prev())
      return t->Prev()->GetObject();
   else
      return 0;
}
void TList::Clear(Option_t *option)
{
   
   
   
   
   
   
   Bool_t nodel = option ? (!strcmp(option, "nodelete") ? kTRUE : kFALSE) : kFALSE;
   if (!nodel && IsOwner()) {
      Delete(option);
      return;
   }
   while (fFirst) {
      TObjLink *tlk = fFirst;
      fFirst = fFirst->Next();
      fSize--;
      
      if (!nodel && tlk->GetObject() && tlk->GetObject()->IsOnHeap()) {
         if (tlk->GetObject()->TestBit(kCanDelete)) {
            if(tlk->GetObject()->TestBit(kNotDeleted)) {
               TCollection::GarbageCollect(tlk->GetObject());
            }
         }
      }
      delete tlk;
   }
   fFirst = fLast = fCache = 0;
   fSize  = 0;
   Changed();
}
void TList::Delete(Option_t *option)
{
   
   
   
   
   
   Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
   if (slow) {
      while (fFirst) {
         TObjLink *tlk = fFirst;
         fFirst = fFirst->Next();
         fSize--;
         
         if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
            TCollection::GarbageCollect(tlk->GetObject());
         delete tlk;
      }
      fFirst = fLast = fCache = 0;
      fSize  = 0;
   } else {
      TObjLink *first = fFirst;    
      fFirst = fLast = fCache = 0;
      fSize  = 0;
      while (first) {
         TObjLink *tlk = first;
         first = first->Next();
         
         if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
            TCollection::GarbageCollect(tlk->GetObject());
         delete tlk;
      }
   }
   Changed();
}
void TList::DeleteLink(TObjLink *lnk)
{
   
   lnk->fNext = lnk->fPrev = 0;
   lnk->fObject = 0;
   delete lnk;
}
TObject *TList::FindObject(const char *name) const
{
   
   
   
   
   if (!name) return 0;
   TObjLink *lnk = FirstLink();
   while (lnk) {
      TObject *obj = lnk->GetObject();
      if (obj->GetName() && !strcmp(name, obj->GetName())) return obj;
      lnk = lnk->Next();
   }
   return 0;
}
TObject *TList::FindObject(const TObject *obj) const
{
   
   
   
   
   
   TObjLink *lnk = FirstLink();
   while (lnk) {
      TObject *ob = lnk->GetObject();
      if (ob->IsEqual(obj)) return ob;
      lnk = lnk->Next();
   }
   return 0;
}
TObjLink *TList::FindLink(const TObject *obj, Int_t &idx) const
{
   
   
   if (!fFirst) return 0;
   TObject *object;
   TObjLink *lnk = fFirst;
   idx = 0;
   while (lnk) {
      object = lnk->GetObject();
      if (object) {
         if (object->TestBit(kNotDeleted)) {
            if (object->IsEqual(obj)) return lnk;
         }
      }
      lnk = lnk->Next();
      idx++;
   }
   return 0;
}
TObject *TList::First() const
{
   
   if (fFirst) return fFirst->GetObject();
   return 0;
}
TObject **TList::GetObjectRef(const TObject *obj) const
{
   
   TObjLink *lnk = FirstLink();
   while (lnk) {
      TObject *ob = lnk->GetObject();
      if (ob->IsEqual(obj)) return lnk->GetObjectRef();
      lnk = lnk->Next();
   }
   return 0;
}
TObject *TList::Last() const
{
   
   if (fLast) return fLast->GetObject();
   return 0;
}
TObjLink *TList::LinkAt(Int_t idx) const
{
   
   Int_t    i = 0;
   TObjLink *lnk = fFirst;
   while (i < idx && lnk) {
      i++;
      lnk = lnk->Next();
   }
   return lnk;
}
TIterator *TList::MakeIterator(Bool_t dir) const
{
   
   return new TListIter(this, dir);
}
TObjLink *TList::NewLink(TObject *obj, TObjLink *prev)
{
   
   if (prev)
      return new TObjLink(obj, prev);
   else
      return new TObjLink(obj);
}
TObjLink *TList::NewOptLink(TObject *obj, Option_t *opt, TObjLink *prev)
{
   
   if (prev)
      return new TObjOptLink(obj, prev, opt);
   else
      return new TObjOptLink(obj, opt);
}
TObject *TList::Remove(TObject *obj)
{
   
   if (!obj) return 0;
   Int_t    idx;
   TObjLink *lnk = FindLink(obj, idx);
   if (!lnk) return 0;
   
   
   TObject *ob = lnk->GetObject();
   if (lnk == fFirst) {
      fFirst = lnk->Next();
      if (lnk == fLast)
         fLast = fFirst;
      else
         fFirst->fPrev = 0;
      DeleteLink(lnk);
   } else if (lnk == fLast) {
      fLast = lnk->Prev();
      fLast->fNext = 0;
      DeleteLink(lnk);
   } else {
      lnk->Prev()->fNext = lnk->Next();
      lnk->Next()->fPrev = lnk->Prev();
      DeleteLink(lnk);
   }
   fSize--;
   fCache = 0;
   Changed();
   return ob;
}
TObject *TList::Remove(TObjLink *lnk)
{
   
   
   if (!lnk) return 0;
   TObject *obj = lnk->GetObject();
   if (lnk == fFirst) {
      fFirst = lnk->Next();
      if (lnk == fLast)
         fLast = fFirst;
      else
         fFirst->fPrev = 0;
      DeleteLink(lnk);
   } else if (lnk == fLast) {
      fLast = lnk->Prev();
      fLast->fNext = 0;
      DeleteLink(lnk);
   } else {
      lnk->Prev()->fNext = lnk->Next();
      lnk->Next()->fPrev = lnk->Prev();
      DeleteLink(lnk);
   }
   fSize--;
   fCache = 0;
   Changed();
   return obj;
}
void TList::Sort(Bool_t order)
{
   
   
   
   if (!fFirst) return;
   fAscending = order;
   if (!fFirst->GetObject()->IsSortable()) {
      Error("Sort", "objects in list are not sortable");
      return;
   }
   DoSort(&fFirst, fSize);
   
   TObjLink *ol, *lnk = fFirst;
   if (lnk) lnk->fPrev = 0;
   while ((ol = lnk)) {
      lnk = lnk->fNext;
      if (lnk)
         lnk->fPrev = ol;
      else
         fLast = ol;
   }
   fSorted = kTRUE;
}
Bool_t TList::LnkCompare(TObjLink *l1, TObjLink *l2)
{
   
   
   
   Int_t cmp = l1->GetObject()->Compare(l2->GetObject());
   if ((IsAscending() && cmp <=0) || (!IsAscending() && cmp > 0))
      return kTRUE;
   return kFALSE;
}
TObjLink **TList::DoSort(TObjLink **head, Int_t n)
{
   
   TObjLink *p1, *p2, **h2, **t2;
   switch (n) {
      case 0:
         return head;
      case 1:
         return &((*head)->fNext);
      case 2:
         p2 = (p1 = *head)->fNext;
         if (LnkCompare(p1, p2)) return &(p2->fNext);
         p1->fNext = (*head = p2)->fNext;
         return &((p2->fNext = p1)->fNext);
   }
   int m;
   n -= m = n / 2;
   t2 = DoSort(h2 = DoSort(head, n), m);
   if (LnkCompare((p1 = *head), (p2 = *h2))) {
      do {
         if (!--n) return *h2 = p2, t2;
      } while (LnkCompare((p1 = *(head = &(p1->fNext))), p2));
   }
   while (1) {
      *head = p2;
      do {
         if (!--m) return *h2 = *t2, *t2 = p1, h2;
      } while (!LnkCompare(p1, (p2 = *(head = &(p2->fNext)))));
      *head = p1;
      do {
         if (!--n) return *h2 = p2, t2;
      } while (LnkCompare((p1 = *(head = &(p1->fNext))), p2));
   }
}
TObjLink::TObjLink(TObject *obj, TObjLink *prev)
          : fNext(prev->fNext), fPrev(prev), fObject(obj)
{
   
   fPrev->fNext = this;
   if (fNext) fNext->fPrev = this;
}
ClassImp(TListIter)
TListIter::TListIter(const TList *l, Bool_t dir)
        : fList(l), fCurCursor(0), fCursor(0), fDirection(dir), fStarted(kFALSE)
{
   
   
}
TListIter::TListIter(const TListIter &iter) : TIterator(iter)
{
   
   fList      = iter.fList;
   fCurCursor = iter.fCurCursor;
   fCursor    = iter.fCursor;
   fDirection = iter.fDirection;
   fStarted   = iter.fStarted;
}
TIterator &TListIter::operator=(const TIterator &rhs)
{
   
   if (this != &rhs && rhs.IsA() == TListIter::Class()) {
      const TListIter &rhs1 = (const TListIter &)rhs;
      fList      = rhs1.fList;
      fCurCursor = rhs1.fCurCursor;
      fCursor    = rhs1.fCursor;
      fDirection = rhs1.fDirection;
      fStarted   = rhs1.fStarted;
   }
   return *this;
}
TListIter &TListIter::operator=(const TListIter &rhs)
{
   
   if (this != &rhs) {
      fList      = rhs.fList;
      fCurCursor = rhs.fCurCursor;
      fCursor    = rhs.fCursor;
      fDirection = rhs.fDirection;
      fStarted   = rhs.fStarted;
   }
   return *this;
}
TObject *TListIter::Next()
{
   
   if (!fList) return 0;
   if (fDirection == kIterForward) {
      if (!fStarted) {
         fCursor = fList->fFirst;
         fStarted = kTRUE;
      }
      fCurCursor = fCursor;
      if (fCursor) fCursor = fCursor->Next();
   } else {
      if (!fStarted) {
         fCursor = fList->fLast;
         fStarted = kTRUE;
      }
      fCurCursor = fCursor;
      if (fCursor) fCursor = fCursor->Prev();
   }
   if (fCurCursor) return fCurCursor->GetObject();
   return 0;
}
Option_t *TListIter::GetOption() const
{
   
   if (fCurCursor) return fCurCursor->GetOption();
   return "";
}
void TListIter::SetOption(Option_t *option)
{
   
   if (fCurCursor) fCurCursor->SetOption(option);
}
void TList::Streamer(TBuffer &b)
{
   
   Int_t nobjects;
   UChar_t nch;
   Int_t nbig;
   TObject *obj;
   UInt_t R__s, R__c;
   if (b.IsReading()) {
      Version_t v = b.ReadVersion(&R__s, &R__c);
      if (v > 3) {
         TObject::Streamer(b);
         fName.Streamer(b);
         b >> nobjects;
         string readOption;
         for (Int_t i = 0; i < nobjects; i++) {
            b >> obj;
            b >> nch;
            if (v > 4 && nch == 255)  {
               b >> nbig;
            } else {
               nbig = nch;
            }
            readOption.resize(nbig,'\0');
            b.ReadFastArray((char*) readOption.data(),nbig);
            if (nch) {
               Add(obj,readOption.c_str());
            } else {
               Add(obj);
            }
         }
         b.CheckByteCount(R__s, R__c,TList::IsA());
         return;
      }
      
      if (v > 2)
         TObject::Streamer(b);
      if (v > 1)
         fName.Streamer(b);
      b >> nobjects;
      for (Int_t i = 0; i < nobjects; i++) {
         b >> obj;
         Add(obj);
      }
      b.CheckByteCount(R__s, R__c,TList::IsA());
   } else {
      R__c = b.WriteVersion(TList::IsA(), kTRUE);
      TObject::Streamer(b);
      fName.Streamer(b);
      nobjects = GetSize();
      b << nobjects;
      TObjLink *lnk = fFirst;
      while (lnk) {
         obj = lnk->GetObject();
         b << obj;
         nbig = strlen(lnk->GetAddOption());
         if (nbig > 254) {
            nch = 255;
            b << nch;
            b << nbig;
         } else {
            nch = UChar_t(nbig);
            b << nch;
         }
         b.WriteFastArray(lnk->GetAddOption(),nbig);
         lnk = lnk->Next();
      }
      b.SetByteCount(R__c, kTRUE);
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.