Logo ROOT   6.08/07
Reference Guide
TList.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Fons Rademakers 10/08/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 /** \class TList
13 \ingroup Containers
14 A doubly linked list.
15 
16 All classes inheriting from TObject can be
17 inserted in a TList. Before being inserted into the list the object
18 pointer is wrapped in a TObjLink object which contains, besides
19 the object pointer also a previous and next pointer.
20 
21 There are basically four ways to iterate over a TList (in order
22 of preference, if not forced by other constraints):
23 
24  1. Using the R__FOR_EACH macro:
25 ~~~ {.cpp}
26  GetListOfPrimitives()->R__FOR_EACH(TObject,Paint)(option);
27 ~~~
28  2. Using the TList iterator TListIter (via the wrapper class TIter):
29 ~~~ {.cpp}
30  TIter next(GetListOfPrimitives());
31  while ((TObject *obj = next()))
32  obj->Draw(next.GetOption());
33 ~~~
34  3. Using the TList iterator TListIter and std::for_each algorithm:
35 ~~~ {.cpp}
36  // A function object, which will be applied to each element
37  // of the given range.
38  struct STestFunctor {
39  bool operator()(TObject *aObj) {
40  ...
41  return true;
42  }
43  }
44  ...
45  ...
46  TIter iter(mylist);
47  for_each( iter.Begin(), TIter::End(), STestFunctor() );
48 ~~~
49  4. Using the TObjLink list entries (that wrap the TObject*):
50 ~~~ {.cpp}
51  TObjLink *lnk = GetListOfPrimitives()->FirstLink();
52  while (lnk) {
53  lnk->GetObject()->Draw(lnk->GetOption());
54  lnk = lnk->Next();
55  }
56 ~~~
57  5. Using the TList's After() and Before() member functions:
58 ~~~ {.cpp}
59  TFree *idcur = this;
60  while (idcur) {
61  ...
62  ...
63  idcur = (TFree*)GetListOfFree()->After(idcur);
64  }
65 ~~~
66 Methods 2, 3 and 4 can also easily iterate backwards using either
67 a backward TIter (using argument kIterBackward) or by using
68 LastLink() and lnk->Prev() or by using the Before() member.
69 */
70 
71 #include "TList.h"
72 #include "TClass.h"
73 #include "TROOT.h"
74 #include "TVirtualMutex.h"
75 
76 #include <string>
77 namespace std {} using namespace std;
78 
80 
81 ////////////////////////////////////////////////////////////////////////////////
82 /// Delete the list. Objects are not deleted unless the TList is the
83 /// owner (set via SetOwner()).
84 
86 {
87  Clear();
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Add object at the beginning of the list.
92 
94 {
95  if (IsArgNull("AddFirst", obj)) return;
96 
97  if (!fFirst) {
98  fFirst = NewLink(obj);
99  fLast = fFirst;
100  } else {
101  TObjLink *t = NewLink(obj);
102  t->fNext = fFirst;
103  fFirst->fPrev = t;
104  fFirst = t;
105  }
106  fSize++;
107  Changed();
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 /// Add object at the beginning of the list and also store option.
112 /// Storing an option is useful when one wants to change the behaviour
113 /// of an object a little without having to create a complete new
114 /// copy of the object. This feature is used, for example, by the Draw()
115 /// method. It allows the same object to be drawn in different ways.
116 
118 {
119  if (IsArgNull("AddFirst", obj)) return;
120 
121  if (!fFirst) {
122  fFirst = NewOptLink(obj, opt);
123  fLast = fFirst;
124  } else {
125  TObjLink *t = NewOptLink(obj, opt);
126  t->fNext = fFirst;
127  fFirst->fPrev = t;
128  fFirst = t;
129  }
130  fSize++;
131  Changed();
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// Add object at the end of the list.
136 
138 {
139  if (IsArgNull("AddLast", obj)) return;
140 
141  if (!fFirst) {
142  fFirst = NewLink(obj);
143  fLast = fFirst;
144  } else
145  fLast = NewLink(obj, fLast);
146  fSize++;
147  Changed();
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Add object at the end of the list and also store option.
152 /// Storing an option is useful when one wants to change the behaviour
153 /// of an object a little without having to create a complete new
154 /// copy of the object. This feature is used, for example, by the Draw()
155 /// method. It allows the same object to be drawn in different ways.
156 
158 {
159  if (IsArgNull("AddLast", obj)) return;
160 
161  if (!fFirst) {
162  fFirst = NewOptLink(obj, opt);
163  fLast = fFirst;
164  } else
165  fLast = NewOptLink(obj, opt, fLast);
166  fSize++;
167  Changed();
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// Insert object before object before in the list.
172 
173 void TList::AddBefore(const TObject *before, TObject *obj)
174 {
175  if (IsArgNull("AddBefore", obj)) return;
176 
177  if (!before)
178  TList::AddFirst(obj);
179  else {
180  Int_t idx;
181  TObjLink *t = FindLink(before, idx);
182  if (!t) {
183  Error("AddBefore", "before not found, object not added");
184  return;
185  }
186  if (t == fFirst)
187  TList::AddFirst(obj);
188  else {
189  NewLink(obj, t->Prev());
190  fSize++;
191  Changed();
192  }
193  }
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Insert object before the specified ObjLink object. If before = 0 then add
198 /// to the head of the list. An ObjLink can be obtained by looping over a list
199 /// using the above describe iterator method 3.
200 
201 void TList::AddBefore(TObjLink *before, TObject *obj)
202 {
203  if (IsArgNull("AddBefore", obj)) return;
204 
205  if (!before)
206  TList::AddFirst(obj);
207  else {
208  if (before == fFirst)
209  TList::AddFirst(obj);
210  else {
211  NewLink(obj, before->Prev());
212  fSize++;
213  Changed();
214  }
215  }
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Insert object after object after in the list.
220 
221 void TList::AddAfter(const TObject *after, TObject *obj)
222 {
223  if (IsArgNull("AddAfter", obj)) return;
224 
225  if (!after)
226  TList::AddLast(obj);
227  else {
228  Int_t idx;
229  TObjLink *t = FindLink(after, idx);
230  if (!t) {
231  Error("AddAfter", "after not found, object not added");
232  return;
233  }
234  if (t == fLast)
235  TList::AddLast(obj);
236  else {
237  NewLink(obj, t);
238  fSize++;
239  Changed();
240  }
241  }
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Insert object after the specified ObjLink object. If after = 0 then add
246 /// to the tail of the list. An ObjLink can be obtained by looping over a list
247 /// using the above describe iterator method 3.
248 
249 void TList::AddAfter(TObjLink *after, TObject *obj)
250 {
251  if (IsArgNull("AddAfter", obj)) return;
252 
253  if (!after)
254  TList::AddLast(obj);
255  else {
256  if (after == fLast)
257  TList::AddLast(obj);
258  else {
259  NewLink(obj, after);
260  fSize++;
261  Changed();
262  }
263  }
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 /// Insert object at position idx in the list.
268 
269 void TList::AddAt(TObject *obj, Int_t idx)
270 {
271  if (IsArgNull("AddAt", obj)) return;
272 
273  TObjLink *lnk = LinkAt(idx);
274  if (!lnk)
275  TList::AddLast(obj);
276  else if (lnk == fFirst)
277  TList::AddFirst(obj);
278  else {
279  NewLink(obj, lnk->Prev());
280  fSize++;
281  Changed();
282  }
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Returns the object after object obj. Obj is found using the
287 /// object's IsEqual() method. Returns 0 if obj is last in list.
288 
289 TObject *TList::After(const TObject *obj) const
290 {
291  TObjLink *t;
292 
293  if (fCache && fCache->GetObject() && fCache->GetObject()->IsEqual(obj)) {
294  t = fCache;
295  ((TList*)this)->fCache = fCache->Next(); //cast const away, fCache should be mutable
296  } else {
297  Int_t idx;
298  t = FindLink(obj, idx);
299  if (t) ((TList*)this)->fCache = t->Next();
300  }
301 
302  if (t && t->Next())
303  return t->Next()->GetObject();
304  else
305  return 0;
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Returns the object at position idx. Returns 0 if idx is out of range.
310 
312 {
313  TObjLink *lnk = LinkAt(idx);
314  if (lnk) return lnk->GetObject();
315  return 0;
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Returns the object before object obj. Obj is found using the
320 /// object's IsEqual() method. Returns 0 if obj is first in list.
321 
322 TObject *TList::Before(const TObject *obj) const
323 {
324  TObjLink *t;
325 
326  if (fCache && fCache->GetObject() && fCache->GetObject()->IsEqual(obj)) {
327  t = fCache;
328  ((TList*)this)->fCache = fCache->Prev(); //cast const away, fCache should be mutable
329  } else {
330  Int_t idx;
331  t = FindLink(obj, idx);
332  if (t) ((TList*)this)->fCache = t->Prev();
333  }
334 
335  if (t && t->Prev())
336  return t->Prev()->GetObject();
337  else
338  return 0;
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 /// Remove all objects from the list. Does not delete the objects
343 /// unless the TList is the owner (set via SetOwner()) and option
344 /// "nodelete" is not set.
345 /// If option="nodelete" then don't delete any heap objects that were
346 /// marked with the kCanDelete bit, otherwise these objects will be
347 /// deleted (this option is used by THashTable::Clear()).
348 
349 void TList::Clear(Option_t *option)
350 {
351  Bool_t nodel = option ? (!strcmp(option, "nodelete") ? kTRUE : kFALSE) : kFALSE;
352 
353  if (!nodel && IsOwner()) {
354  Delete(option);
355  return;
356  }
357 
358  // In some case, for example TParallelCoord, a list (the pad's list of
359  // primitives) will contain both the container and the containees
360  // (the TParallelCoorVar) but if the Clear is being called from
361  // the destructor of the container of this list, one of the first
362  // thing done will be the remove the container (the pad) for the
363  // list (of Primitives of the canvas) that was connecting it
364  // (indirectly) to the list of cleanups.
365  // So let's temporarily add the current list and remove it later.
366  bool needRegister = fFirst && TROOT::Initialized();
367  if(needRegister) {
369  needRegister = needRegister && !gROOT->GetListOfCleanups()->FindObject(this);
370  }
371  if (needRegister) {
373  gROOT->GetListOfCleanups()->Add(this);
374  }
375  while (fFirst) {
376  TObjLink *tlk = fFirst;
377  fFirst = fFirst->Next();
378  fSize--;
379  // delete only heap objects marked OK to clear
380  if (!nodel && tlk->GetObject() && tlk->GetObject()->IsOnHeap()) {
381  if (tlk->GetObject()->TestBit(kCanDelete)) {
382  if(tlk->GetObject()->TestBit(kNotDeleted)) {
384  }
385  }
386  }
387  delete tlk;
388  }
389  if (needRegister) {
392  }
393  fFirst = fLast = fCache = 0;
394  fSize = 0;
395  Changed();
396 }
397 
398 ////////////////////////////////////////////////////////////////////////////////
399 /// Remove all objects from the list AND delete all heap based objects.
400 /// If option="slow" then keep list consistent during delete. This allows
401 /// recursive list operations during the delete (e.g. during the dtor
402 /// of an object in this list one can still access the list to search for
403 /// other not yet deleted objects).
404 
405 void TList::Delete(Option_t *option)
406 {
407  Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
408 
409  TList removeDirectory; // need to deregister these from their directory
410 
411  if (slow) {
412 
413  // In some case, for example TParallelCoord, a list (the pad's list of
414  // primitives) will contain both the container and the containees
415  // (the TParallelCoorVar) but if the Clear is being called from
416  // the destructor of the container of this list, one of the first
417  // thing done will be the remove the container (the pad) for the
418  // list (of Primitives of the canvas) that was connecting it
419  // (indirectly) to the list of cleanups.
420  // So let's temporarily add the current list and remove it later.
421  bool needRegister = fFirst && TROOT::Initialized();
422  if(needRegister) {
424  needRegister = needRegister && !gROOT->GetListOfCleanups()->FindObject(this);
425  }
426  if (needRegister) {
428  gROOT->GetListOfCleanups()->Add(this);
429  }
430  while (fFirst) {
431  TObjLink *tlk = fFirst;
432  fFirst = fFirst->Next();
433  fSize--;
434  // delete only heap objects
435  if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
437  else if (tlk->GetObject() && tlk->GetObject()->IsA()->GetDirectoryAutoAdd())
438  removeDirectory.Add(tlk->GetObject());
439 
440  delete tlk;
441  }
442 
443  if (needRegister) {
446  }
447 
448  fFirst = fLast = fCache = 0;
449  fSize = 0;
450 
451  } else {
452 
453  TObjLink *first = fFirst; //pointer to first entry in linked list
454  fFirst = fLast = fCache = 0;
455  fSize = 0;
456  while (first) {
457  TObjLink *tlk = first;
458  first = first->Next();
459  // delete only heap objects
460  if (tlk->GetObject() && tlk->GetObject()->IsOnHeap())
462  else if (tlk->GetObject() && tlk->GetObject()->IsA()->GetDirectoryAutoAdd())
463  removeDirectory.Add(tlk->GetObject());
464 
465  delete tlk;
466  }
467  }
468 
469  // These objects cannot expect to have a valid TDirectory anymore;
470  // e.g. because *this is the TDirectory's list of objects. Even if
471  // not, they are supposed to be deleted, so we can as well unregister
472  // them from their directory, even if they are stack-based:
473  TIter iRemDir(&removeDirectory);
474  TObject* dirRem = 0;
475  while ((dirRem = iRemDir())) {
476  (*dirRem->IsA()->GetDirectoryAutoAdd())(dirRem, 0);
477  }
478  Changed();
479 }
480 
481 ////////////////////////////////////////////////////////////////////////////////
482 /// Delete a TObjLink object.
483 
485 {
486  lnk->fNext = lnk->fPrev = 0;
487  lnk->fObject = 0;
488  delete lnk;
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Find an object in this list using its name. Requires a sequential
493 /// scan till the object has been found. Returns 0 if object with specified
494 /// name is not found. This method overrides the generic FindObject()
495 /// of TCollection for efficiency reasons.
496 
497 TObject *TList::FindObject(const char *name) const
498 {
499  if (!name) return 0;
500  TObjLink *lnk = FirstLink();
501  while (lnk) {
502  TObject *obj = lnk->GetObject();
503  const char *objname = obj->GetName();
504  if (objname && !strcmp(name, objname)) return obj;
505  lnk = lnk->Next();
506  }
507  return 0;
508 }
509 
510 ////////////////////////////////////////////////////////////////////////////////
511 /// Find an object in this list using the object's IsEqual()
512 /// member function. Requires a sequential scan till the object has
513 /// been found. Returns 0 if object is not found.
514 /// This method overrides the generic FindObject() of TCollection for
515 /// efficiency reasons.
516 
518 {
519  TObjLink *lnk = FirstLink();
520 
521  while (lnk) {
522  TObject *ob = lnk->GetObject();
523  if (ob->IsEqual(obj)) return ob;
524  lnk = lnk->Next();
525  }
526  return 0;
527 }
528 
529 ////////////////////////////////////////////////////////////////////////////////
530 /// Returns the TObjLink object that contains object obj. In idx it returns
531 /// the position of the object in the list.
532 
533 TObjLink *TList::FindLink(const TObject *obj, Int_t &idx) const
534 {
535  if (!fFirst) return 0;
536 
537  TObject *object;
538  TObjLink *lnk = fFirst;
539  idx = 0;
540 
541  while (lnk) {
542  object = lnk->GetObject();
543  if (object) {
544  if (object->TestBit(kNotDeleted)) {
545  if (object->IsEqual(obj)) return lnk;
546  }
547  }
548  lnk = lnk->Next();
549  idx++;
550  }
551  return 0;
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// Return the first object in the list. Returns 0 when list is empty.
556 
558 {
559  if (fFirst) return fFirst->GetObject();
560  return 0;
561 }
562 
563 ////////////////////////////////////////////////////////////////////////////////
564 /// Return address of pointer to obj
565 
567 {
568  TObjLink *lnk = FirstLink();
569 
570  while (lnk) {
571  TObject *ob = lnk->GetObject();
572  if (ob->IsEqual(obj)) return lnk->GetObjectRef();
573  lnk = lnk->Next();
574  }
575  return 0;
576 }
577 
578 ////////////////////////////////////////////////////////////////////////////////
579 /// Return the last object in the list. Returns 0 when list is empty.
580 
582 {
583  if (fLast) return fLast->GetObject();
584  return 0;
585 }
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Return the TObjLink object at index idx.
589 
591 {
592  Int_t i = 0;
593  TObjLink *lnk = fFirst;
594  while (i < idx && lnk) {
595  i++;
596  lnk = lnk->Next();
597  }
598  return lnk;
599 }
600 
601 ////////////////////////////////////////////////////////////////////////////////
602 /// Return a list iterator.
603 
605 {
606  return new TListIter(this, dir);
607 }
608 
609 ////////////////////////////////////////////////////////////////////////////////
610 /// Return a new TObjLink.
611 
613 {
614  if (prev)
615  return new TObjLink(obj, prev);
616  else
617  return new TObjLink(obj);
618 }
619 
620 ////////////////////////////////////////////////////////////////////////////////
621 /// Return a new TObjOptLink (a TObjLink that also stores the option).
622 
624 {
625  if (prev)
626  return new TObjOptLink(obj, prev, opt);
627  else
628  return new TObjOptLink(obj, opt);
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Remove object from this collection and recursively remove the object
633 /// from all other objects (and collections).
634 
636 {
637  if (!obj) return;
638 
639  TObjLink *lnk = fFirst;
640  TObjLink *next = 0;
641  while (lnk) {
642  next = lnk->Next();
643  TObject *ob = lnk->GetObject();
644  if (ob->TestBit(kNotDeleted)) {
645  if (ob->IsEqual(obj)) {
646  if (lnk == fFirst) {
647  fFirst = next;
648  if (lnk == fLast)
649  fLast = fFirst;
650  else
651  fFirst->fPrev = 0;
652  DeleteLink(lnk);
653  } else if (lnk == fLast) {
654  fLast = lnk->Prev();
655  fLast->fNext = 0;
656  DeleteLink(lnk);
657  } else {
658  lnk->Prev()->fNext = next;
659  lnk->Next()->fPrev = lnk->Prev();
660  DeleteLink(lnk);
661  }
662  fSize--;
663  fCache = 0;
664  Changed();
665  } else
666  ob->RecursiveRemove(obj);
667  }
668  lnk = next;
669  }
670 }
671 
672 ////////////////////////////////////////////////////////////////////////////////
673 /// Remove object from the list.
674 
676 {
677  if (!obj) return 0;
678 
679  Int_t idx;
680  TObjLink *lnk = FindLink(obj, idx);
681 
682  if (!lnk) return 0;
683 
684  // return object found, which may be (pointer wise) different than the
685  // input object (depending on what IsEqual() is doing)
686 
687  TObject *ob = lnk->GetObject();
688  if (lnk == fFirst) {
689  fFirst = lnk->Next();
690  if (lnk == fLast)
691  fLast = fFirst;
692  else
693  fFirst->fPrev = 0;
694  DeleteLink(lnk);
695  } else if (lnk == fLast) {
696  fLast = lnk->Prev();
697  fLast->fNext = 0;
698  DeleteLink(lnk);
699  } else {
700  lnk->Prev()->fNext = lnk->Next();
701  lnk->Next()->fPrev = lnk->Prev();
702  DeleteLink(lnk);
703  }
704  fSize--;
705  fCache = 0;
706  Changed();
707 
708  return ob;
709 }
710 
711 ////////////////////////////////////////////////////////////////////////////////
712 /// Remove object link (and therefore the object it contains)
713 /// from the list.
714 
716 {
717  if (!lnk) return 0;
718 
719  TObject *obj = lnk->GetObject();
720 
721  if (lnk == fFirst) {
722  fFirst = lnk->Next();
723  if (lnk == fLast)
724  fLast = fFirst;
725  else
726  fFirst->fPrev = 0;
727  DeleteLink(lnk);
728  } else if (lnk == fLast) {
729  fLast = lnk->Prev();
730  fLast->fNext = 0;
731  DeleteLink(lnk);
732  } else {
733  lnk->Prev()->fNext = lnk->Next();
734  lnk->Next()->fPrev = lnk->Prev();
735  DeleteLink(lnk);
736  }
737  fSize--;
738  fCache = 0;
739  Changed();
740 
741  return obj;
742 }
743 
744 ////////////////////////////////////////////////////////////////////////////////
745 /// Remove the last object of the list.
746 
748 {
749  TObjLink *lnk = fLast;
750  if (!lnk) return;
751 
752  if (lnk == fFirst) {
753  fFirst = 0;
754  fLast = 0;
755  } else {
756  fLast = lnk->Prev();
757  fLast->fNext = 0;
758  }
759  DeleteLink(lnk);
760 
761  fSize--;
762  fCache = 0;
763  Changed();
764 }
765 
766 ////////////////////////////////////////////////////////////////////////////////
767 /// Sort linked list. Real sorting is done in private function DoSort().
768 /// The list can only be sorted when is contains objects of a sortable
769 /// class.
770 
771 void TList::Sort(Bool_t order)
772 {
773  if (!fFirst) return;
774 
775  fAscending = order;
776 
777  if (!fFirst->GetObject()->IsSortable()) {
778  Error("Sort", "objects in list are not sortable");
779  return;
780  }
781 
782  DoSort(&fFirst, fSize);
783 
784  // correct back links
785  TObjLink *ol, *lnk = fFirst;
786 
787  if (lnk) lnk->fPrev = 0;
788  while ((ol = lnk)) {
789  lnk = lnk->fNext;
790  if (lnk)
791  lnk->fPrev = ol;
792  else
793  fLast = ol;
794  }
795  fSorted = kTRUE;
796 }
797 
798 ////////////////////////////////////////////////////////////////////////////////
799 /// Compares the objects stored in the TObjLink objects.
800 /// Depending on the flag IsAscending() the function returns
801 /// true if the object in l1 <= l2 (ascending) or l2 <= l1 (descending).
802 
804 {
805  Int_t cmp = l1->GetObject()->Compare(l2->GetObject());
806 
807  if ((IsAscending() && cmp <=0) || (!IsAscending() && cmp > 0))
808  return kTRUE;
809  return kFALSE;
810 }
811 
812 ////////////////////////////////////////////////////////////////////////////////
813 /// Sort linked list.
814 
816 {
817  TObjLink *p1, *p2, **h2, **t2;
818 
819  switch (n) {
820  case 0:
821  return head;
822 
823  case 1:
824  return &((*head)->fNext);
825 
826  case 2:
827  p2 = (p1 = *head)->fNext;
828  if (LnkCompare(p1, p2)) return &(p2->fNext);
829  p1->fNext = (*head = p2)->fNext;
830  return &((p2->fNext = p1)->fNext);
831  }
832 
833  int m;
834  n -= m = n / 2;
835 
836  t2 = DoSort(h2 = DoSort(head, n), m);
837 
838  if (LnkCompare((p1 = *head), (p2 = *h2))) {
839  do {
840  if (!--n) return *h2 = p2, t2;
841  } while (LnkCompare((p1 = *(head = &(p1->fNext))), p2));
842  }
843 
844  while (1) {
845  *head = p2;
846  do {
847  if (!--m) return *h2 = *t2, *t2 = p1, h2;
848  } while (!LnkCompare(p1, (p2 = *(head = &(p2->fNext)))));
849  *head = p1;
850  do {
851  if (!--n) return *h2 = p2, t2;
852  } while (LnkCompare((p1 = *(head = &(p1->fNext))), p2));
853  }
854 }
855 
856 /** \class TObjLink
857 Wrapper around a TObject so it can be stored in a TList.
858 */
859 
860 ////////////////////////////////////////////////////////////////////////////////
861 /// Create a new TObjLink.
862 
864  : fNext(prev->fNext), fPrev(prev), fObject(obj)
865 {
866  fPrev->fNext = this;
867  if (fNext) fNext->fPrev = this;
868 }
869 
870 /** \class TListIter
871 Iterator of linked list.
872 */
873 
875 
876 ////////////////////////////////////////////////////////////////////////////////
877 /// Create a new list iterator. By default the iteration direction
878 /// is kIterForward. To go backward use kIterBackward.
879 
881  : fList(l), fCurCursor(0), fCursor(0), fDirection(dir), fStarted(kFALSE)
882 {
883 }
884 
885 ////////////////////////////////////////////////////////////////////////////////
886 /// Copy ctor.
887 
889 {
890  fList = iter.fList;
891  fCurCursor = iter.fCurCursor;
892  fCursor = iter.fCursor;
893  fDirection = iter.fDirection;
894  fStarted = iter.fStarted;
895 }
896 
897 ////////////////////////////////////////////////////////////////////////////////
898 /// Overridden assignment operator.
899 
901 {
902  const TListIter *rhs1 = dynamic_cast<const TListIter *>(&rhs);
903  if (this != &rhs && rhs1) {
905  fList = rhs1->fList;
906  fCurCursor = rhs1->fCurCursor;
907  fCursor = rhs1->fCursor;
908  fDirection = rhs1->fDirection;
909  fStarted = rhs1->fStarted;
910  }
911  return *this;
912 }
913 
914 ////////////////////////////////////////////////////////////////////////////////
915 /// Overloaded assignment operator.
916 
918 {
919  if (this != &rhs) {
921  fList = rhs.fList;
922  fCurCursor = rhs.fCurCursor;
923  fCursor = rhs.fCursor;
924  fDirection = rhs.fDirection;
925  fStarted = rhs.fStarted;
926  }
927  return *this;
928 }
929 
930 ////////////////////////////////////////////////////////////////////////////////
931 /// Return next object in the list. Returns 0 when no more objects in list.
932 
934 {
935  if (!fList) return 0;
936 
937  if (fDirection == kIterForward) {
938  if (!fStarted) {
939  fCursor = fList->fFirst;
940  fStarted = kTRUE;
941  }
943  if (fCursor) fCursor = fCursor->Next();
944  } else {
945  if (!fStarted) {
946  fCursor = fList->fLast;
947  fStarted = kTRUE;
948  }
950  if (fCursor) fCursor = fCursor->Prev();
951  }
952 
953  if (fCurCursor) return fCurCursor->GetObject();
954  return 0;
955 }
956 
957 ////////////////////////////////////////////////////////////////////////////////
958 /// Returns the object option stored in the list.
959 
961 {
962  if (fCurCursor) return fCurCursor->GetOption();
963  return "";
964 }
965 
966 ////////////////////////////////////////////////////////////////////////////////
967 /// Sets the object option stored in the list.
968 
970 {
971  if (fCurCursor) fCurCursor->SetOption(option);
972 }
973 
974 ////////////////////////////////////////////////////////////////////////////////
975 /// Reset list iterator.
976 
978 {
979  fStarted = kFALSE;
980 }
981 
982 ////////////////////////////////////////////////////////////////////////////////
983 /// This operator compares two TIterator objects.
984 
986 {
987  if (IsA() == aIter.IsA()) {
988  // We compared equal only two iterator of the same type.
989  // Since this is a function of TListIter, we consequently know that
990  // both this and aIter are of type inheriting from TListIter.
991  const TListIter &iter(dynamic_cast<const TListIter &>(aIter));
992  return (fCurCursor != iter.fCurCursor);
993  }
994  return false; // for base class we don't implement a comparison
995 }
996 
997 ////////////////////////////////////////////////////////////////////////////////
998 /// This operator compares two TListIter objects.
999 
1001 {
1002  return (fCurCursor != aIter.fCurCursor);
1003 }
1004 
1005 ////////////////////////////////////////////////////////////////////////////////
1006 /// Stream all objects in the collection to or from the I/O buffer.
1007 
1008 void TList::Streamer(TBuffer &b)
1009 {
1010  Int_t nobjects;
1011  UChar_t nch;
1012  Int_t nbig;
1013  TObject *obj;
1014  UInt_t R__s, R__c;
1015 
1016  if (b.IsReading()) {
1017  Clear(); // Get rid of old data if any.
1018  Version_t v = b.ReadVersion(&R__s, &R__c);
1019  if (v > 3) {
1020  TObject::Streamer(b);
1021  fName.Streamer(b);
1022  b >> nobjects;
1023  string readOption;
1024  for (Int_t i = 0; i < nobjects; i++) {
1025  b >> obj;
1026  b >> nch;
1027  if (v > 4 && nch == 255) {
1028  b >> nbig;
1029  } else {
1030  nbig = nch;
1031  }
1032  readOption.resize(nbig,'\0');
1033  b.ReadFastArray((char*) readOption.data(),nbig);
1034  if (obj) { // obj can be null if the class had a custom streamer and we do not have the shared library nor a streamerInfo.
1035  if (nch) {
1036  Add(obj,readOption.c_str());
1037  } else {
1038  Add(obj);
1039  }
1040  }
1041  }
1042  b.CheckByteCount(R__s, R__c,TList::IsA());
1043  return;
1044  }
1045 
1046  // process old versions when TList::Streamer was in TCollection::Streamer
1047  if (v > 2)
1048  TObject::Streamer(b);
1049  if (v > 1)
1050  fName.Streamer(b);
1051  b >> nobjects;
1052  for (Int_t i = 0; i < nobjects; i++) {
1053  b >> obj;
1054  Add(obj);
1055  }
1056  b.CheckByteCount(R__s, R__c,TList::IsA());
1057 
1058  } else {
1059  R__c = b.WriteVersion(TList::IsA(), kTRUE);
1060  TObject::Streamer(b);
1061  fName.Streamer(b);
1062  nobjects = GetSize();
1063  b << nobjects;
1064 
1065  TObjLink *lnk = fFirst;
1066  while (lnk) {
1067  obj = lnk->GetObject();
1068  b << obj;
1069 
1070  nbig = strlen(lnk->GetAddOption());
1071  if (nbig > 254) {
1072  nch = 255;
1073  b << nch;
1074  b << nbig;
1075  } else {
1076  nch = UChar_t(nbig);
1077  b << nch;
1078  }
1079  b.WriteFastArray(lnk->GetAddOption(),nbig);
1080 
1081  lnk = lnk->Next();
1082  }
1083  b.SetByteCount(R__c, kTRUE);
1084  }
1085 }
virtual TObject * Remove(TObject *obj)=0
virtual void AddAt(TObject *obj, Int_t idx)
Insert object at position idx in the list.
Definition: TList.cxx:269
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
virtual TObjLink * NewOptLink(TObject *obj, Option_t *opt, TObjLink *prev=NULL)
Return a new TObjOptLink (a TObjLink that also stores the option).
Definition: TList.cxx:623
Bool_t fStarted
Definition: TList.h:197
TSeqCollection * GetListOfCleanups() const
Definition: TROOT.h:256
TObjLink * fCursor
Definition: TList.h:195
short Version_t
Definition: RtypesCore.h:61
virtual void DeleteLink(TObjLink *lnk)
Delete a TObjLink object.
Definition: TList.cxx:484
const char Option_t
Definition: RtypesCore.h:62
virtual void RemoveLast()
Remove the last object of the list.
Definition: TList.cxx:747
TObjLink * LinkAt(Int_t idx) const
sorting order (when calling Sort() or for TSortedList)
Definition: TList.cxx:590
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:581
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:93
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
const TList * fList
Definition: TList.h:193
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:364
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
TObjLink * fCurCursor
Definition: TList.h:194
STL namespace.
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
TObject * Next()
Return next object in the list. Returns 0 when no more objects in list.
Definition: TList.cxx:933
Iterator abstract base class.
Definition: TIterator.h:32
Iterator of linked list.
Definition: TList.h:187
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:137
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition: TObject.cxx:617
virtual void Sort(Bool_t order=kSortAscending)
Sort linked list.
Definition: TList.cxx:771
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2626
static double p2(double t, double a, double b, double c)
Bool_t fDirection
Definition: TList.h:196
void Add(THist< DIMENSIONS, PRECISION_TO, STAT_TO... > &to, THist< DIMENSIONS, PRECISION_FROM, STAT_FROM... > &from)
Add two histograms.
Definition: THist.hxx:327
const Bool_t kIterForward
Definition: TCollection.h:43
Bool_t LnkCompare(TObjLink *l1, TObjLink *l2)
Compares the objects stored in the TObjLink objects.
Definition: TList.cxx:803
void Error(const char *location, const char *msgfmt,...)
virtual Bool_t IsEqual(const TObject *obj) const
Default equal comparison (objects are equal if they have the same address in memory).
Definition: TObject.cxx:528
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const
Return a list iterator.
Definition: TList.cxx:604
A doubly linked list.
Definition: TList.h:47
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:557
SVector< double, 2 > v
Definition: Dict.h:5
TListIter()
Definition: TList.h:199
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:675
virtual TObject * Before(const TObject *obj) const
Returns the object before object obj.
Definition: TList.cxx:322
TObjLink * fLast
pointer to first entry in linked list
Definition: TList.h:53
unsigned int UInt_t
Definition: RtypesCore.h:42
TMarker * m
Definition: textangle.C:8
TLine * l
Definition: textangle.C:4
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:289
virtual Int_t Compare(const TObject *obj) const
Compare abstract method.
Definition: TObject.cxx:219
static double p1(double t, double a, double b)
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
TROOT * GetROOT()
Definition: TROOT.cxx:487
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: TList.cxx:173
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
virtual void WriteFastArray(const Bool_t *b, Int_t n)=0
TObjLink * fFirst
Definition: TList.h:52
#define R__LOCKGUARD2(mutex)
static void GarbageCollect(TObject *obj)
Add to the list of things to be cleaned up.
Bool_t IsOnHeap() const
Definition: TObject.h:119
#define ClassImp(name)
Definition: Rtypes.h:279
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:349
void SetOption(Option_t *option)
Sets the object option stored in the list.
Definition: TList.cxx:969
virtual void AddAfter(const TObject *after, TObject *obj)
Insert object after object after in the list.
Definition: TList.cxx:221
Mother of all ROOT objects.
Definition: TObject.h:37
TObjLink ** DoSort(TObjLink **head, Int_t n)
Sort linked list.
Definition: TList.cxx:815
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:635
virtual TIterator & operator=(const TIterator &)
Definition: TIterator.h:39
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
Bool_t operator!=(const TIterator &aIter) const
This operator compares two TIterator objects.
Definition: TList.cxx:985
void Reset()
Reset list iterator.
Definition: TList.cxx:977
virtual TObjLink * NewLink(TObject *obj, TObjLink *prev=NULL)
Return a new TObjLink.
Definition: TList.cxx:612
unsigned char UChar_t
Definition: RtypesCore.h:34
Definition: first.py:1
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:416
TIterator & operator=(const TIterator &rhs)
Overridden assignment operator.
Definition: TList.cxx:900
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual TObject ** GetObjectRef(const TObject *obj) const
Return address of pointer to obj.
Definition: TList.cxx:566
const Int_t n
Definition: legend1.C:16
Option_t * GetOption() const
Returns the object option stored in the list.
Definition: TList.cxx:960
char name[80]
Definition: TGX11.cxx:109
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
TObjLink * FindLink(const TObject *obj, Int_t &idx) const
Returns the TObjLink object that contains object obj.
Definition: TList.cxx:533
T1 fFirst
Definition: X11Events.mm:86