ROOT  6.06/09
Reference Guide
TObjArray.cxx
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Fons Rademakers 11/09/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 TObjArray
13 An array of TObjects. The array expands automatically when
14 objects are added (shrinking can be done by hand using Expand(),
15 how nice to have meaningful names -:)).
16 Use operator[] to have "real" array behaviour.
17 
18 Note on ownership and copy:
19 By default the TObjArray does not own the objects it points to and
20 will not delete them unless explicitly asked (via a call to the
21 Delete member function). To assign ownership of the content to
22 the array, call:
23 ~~~ {.cpp}
24  myarr->SetOwner(kTRUE);
25 ~~~
26 When the array owns its content a call to Clear or the deletion of
27 the array itself will lead to the deletion of its contents.
28 
29 You can either make a shallow copy of the array:
30 ~~~ {.cpp}
31  otherarr = new TObjArray(*myarr);
32  *otherarr = *myarr;
33 ~~~
34 in which case ownership (if any) is not transfered but the other
35 array points to the same object as the original array. Note that
36 if the content of either array is deleted the other array is not
37 notified in any way (i.e. still points to the now deleted objects).
38 
39 You can also make a deep copy of the array:
40 ~~~ {.cpp}
41  otherarr = (TObjArray*)myarr->Clone();
42 ~~~
43 in which case the array and the content are both duplicated (i.e.
44 otherarr and myarr do not point to the same objects). If myarr
45 is set to the be the owner of its content, otherarr will also be
46 set to the owner of its own content.
47 */
48 
49 #include "TObjArray.h"
50 #include "TError.h"
51 #include "TROOT.h"
52 #include "TVirtualMutex.h"
53 #include <stdlib.h>
54 
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// Create an object array. Using s one can set the array size (default is
59 /// kInitCapacity=16) and lowerBound can be used to set the array lowerbound
60 /// index (default is 0).
61 
62 TObjArray::TObjArray(Int_t s, Int_t lowerBound)
63 {
64  if (s < 0) {
65  Warning("TObjArray", "size (%d) < 0", s);
67  } else if (s == 0)
69  fCont = 0;
70  Init(s, lowerBound);
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// Create a copy of TObjArray a. Note, does not copy the kIsOwner flag.
75 
77 {
78  fCont = 0;
79  Init(a.fSize, a.fLowerBound);
80 
81  for (Int_t i = 0; i < fSize; i++)
82  fCont[i] = a.fCont[i];
83 
84  fLast = a.fLast;
85  fName = a.fName;
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 /// Delete an array. Objects are not deleted unless the TObjArray is the
90 /// owner (set via SetOwner()).
91 
93 {
94  if (IsOwner())
95  Delete();
96 
98  fCont = 0;
99  fSize = 0;
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 /// Assignment operator. Note, unsets the kIsOwner flag.
104 
106 {
107  if (this != &a) {
108  if (IsOwner())
109  Delete();
110  SetOwner(kFALSE);
111 
112  Init(a.fSize, a.fLowerBound);
113 
114  for (Int_t i = 0; i < fSize; i++)
115  fCont[i] = a.fCont[i];
116 
117  fLast = a.fLast;
118  fName = a.fName;
119  }
120  return *this;
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Return the object at position i. Returns address at position 0
125 /// if i is out of bounds. Result may be used as an lvalue.
126 
128 {
129  int j = i-fLowerBound;
130  if (j >= 0 && j < fSize) {
131  fLast = TMath::Max(j, GetAbsLast());
132  Changed();
133  return fCont[j];
134  }
135  BoundsOk("operator[]", i);
136  fLast = -2; // invalidate fLast since the result may be used as an lvalue
137  return fCont[0];
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Return the object at position at. Returns 0 if i is out of bounds.
142 
144 {
145  int j = i-fLowerBound;
146  if (j >= 0 && j < fSize) return fCont[j];
147  BoundsOk("operator[] const", i);
148  return 0;
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Add object in the first slot of the array. This will overwrite the
153 /// first element that might have been there. To have insertion semantics
154 /// use either a TList or a TOrdCollection.
155 
157 {
158  fCont[0] = obj;
159  if (fLast == -1)
160  fLast = 0;
161  Changed();
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// Add object in the next empty slot in the array. Expand the array
166 /// if necessary.
167 
169 {
170  AddAtAndExpand(obj, GetAbsLast()+1+fLowerBound);
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Add object in the slot before object before. If before=0 add object
175 /// in the first slot. Note that this will overwrite any object that
176 /// might have already been in this slot. For insertion semantics use
177 /// either a TList or a TOrdCollection.
178 
179 void TObjArray::AddBefore(const TObject *before, TObject *obj)
180 {
181  if (!before)
182  AddFirst(obj);
183  else {
184  Int_t idx = IndexOf(before) - fLowerBound;
185  if (idx == -1) {
186  Error("AddBefore", "before not found, object not added");
187  return;
188  }
189  if (idx == 0) {
190  Error("AddBefore", "cannot add before lowerbound (%d)", fLowerBound);
191  return;
192  }
193  AddAt(obj, idx+fLowerBound-1);
194  }
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Add object in the slot after object after. If after=0 add object in
199 /// the last empty slot. Note that this will overwrite any object that
200 /// might have already been in this slot. For insertion semantics use
201 /// either a TList or a TOrdCollection.
202 
203 void TObjArray::AddAfter(const TObject *after, TObject *obj)
204 {
205  if (!after)
206  AddLast(obj);
207  else {
208  Int_t idx = IndexOf(after) - fLowerBound;
209  if (idx == -1) {
210  Error("AddAfter", "after not found, object not added");
211  return;
212  }
213  AddAtAndExpand(obj, idx+fLowerBound+1);
214  }
215 }
216 
217 ////////////////////////////////////////////////////////////////////////////////
218 /// Add object at position idx. If idx is larger than the current size
219 /// of the array, expand the array (double its size).
220 
222 {
223  if (idx < fLowerBound) {
224  Error("AddAt", "out of bounds at %d in %lx", idx, (Long_t)this);
225  return;
226  }
227  if (idx-fLowerBound >= fSize)
228  Expand(TMath::Max(idx-fLowerBound+1, GrowBy(fSize)));
229  fCont[idx-fLowerBound] = obj;
230  fLast = TMath::Max(idx-fLowerBound, GetAbsLast());
231  Changed();
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Add object at position ids. Give an error when idx is out of bounds
236 /// (i.e. the array is not expanded).
237 
239 {
240  if (!BoundsOk("AddAt", idx)) return;
241 
242  fCont[idx-fLowerBound] = obj;
243  fLast = TMath::Max(idx-fLowerBound, GetAbsLast());
244  Changed();
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// Return the position of the new object.
249 /// Find the first empty cell or AddLast if there is no empty cell
250 
252 {
253  if (Last()) { // <---------- This is to take in account "empty" TObjArray's
254  Int_t i;
255  for (i = 0; i < fSize; i++)
256  if (!fCont[i]) { // Add object at position i
257  fCont[i] = obj;
258  fLast = TMath::Max(i, GetAbsLast());
259  Changed();
260  return i+fLowerBound;
261  }
262  }
263  AddLast(obj);
264  return GetLast();
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// Return the object after obj. Returns 0 if obj is last object.
269 
270 TObject *TObjArray::After(const TObject *obj) const
271 {
272  if (!obj) return 0;
273 
274  Int_t idx = IndexOf(obj) - fLowerBound;
275  if (idx == -1 || idx == fSize-1) return 0;
276 
277  return fCont[idx+1];
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Return the object before obj. Returns 0 if obj is first object.
282 
284 {
285  if (!obj) return 0;
286 
287  Int_t idx = IndexOf(obj) - fLowerBound;
288  if (idx == -1 || idx == 0) return 0;
289 
290  return fCont[idx-1];
291 }
292 
293 ////////////////////////////////////////////////////////////////////////////////
294 /// Remove all objects from the array. Does not delete the objects
295 /// unless the TObjArray is the owner (set via SetOwner()).
296 
298 {
299  if (IsOwner())
300  Delete();
301  else
302  Init(fSize, fLowerBound);
303 }
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 /// Remove empty slots from array.
307 
309 {
310  Int_t j = 0;
311 
312  for (Int_t i = 0; i < fSize; i++) {
313  if (fCont[i]) {
314  fCont[j] = fCont[i];
315  j++;
316  }
317  }
318 
319  fLast = j - 1;
320 
321  for ( ; j < fSize; j++)
322  fCont[j] = 0;
323 }
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 /// Remove all objects from the array AND delete all heap based objects.
327 
329 {
330  // In some case, for example TParallelCoord, a list (the pad's list of
331  // primitives) will contain both the container and the containees
332  // (the TParallelCoorVar) but if the Clear is being called from
333  // the destructor of the container of this list, one of the first
334  // thing done will be the remove the container (the pad) from the
335  // list (of Primitives of the canvas) that was connecting it
336  // (indirectly) to the list of cleanups.
337  // So let's temporarily add the current list and remove it later.
338  //
339  // If opt is "noregistration", then this protect is skipped.
340  // (To avoid performance penalties, the option must be spelt exactly (no
341  // uppercase, no spaces)
342  const char *noreg = "noregistration";
343  bool needRegister = fSize && TROOT::Initialized() && strcmp(opt,noreg) == 0;
344  if(needRegister) {
346  needRegister = needRegister && !gROOT->GetListOfCleanups()->FindObject(this);
347  }
348  if (needRegister) {
350  gROOT->GetListOfCleanups()->Add(this);
351  }
352  for (Int_t i = 0; i < fSize; i++) {
353  if (fCont[i] && fCont[i]->IsOnHeap()) {
355  fCont[i] = 0;
356  }
357  }
358  if (needRegister) {
361  }
362 
363  Init(fSize, fLowerBound);
364 }
365 
366 ////////////////////////////////////////////////////////////////////////////////
367 /// Expand or shrink the array to newSize elements.
368 
370 {
371  if (newSize < 0) {
372  Error ("Expand", "newSize must be positive (%d)", newSize);
373  return;
374  }
375  if (newSize == fSize)
376  return;
377  if (newSize < fSize) {
378  // if the array is shrunk check whether there are nonempty entries
379  for (Int_t j = newSize; j < fSize; j++)
380  if (fCont[j]) {
381  Error ("Expand", "expand would cut off nonempty entries at %d", j);
382  return;
383  }
384  }
385  fCont = (TObject**) TStorage::ReAlloc(fCont, newSize * sizeof(TObject*),
386  fSize * sizeof(TObject*));
387  fSize = newSize;
388 }
389 
390 ////////////////////////////////////////////////////////////////////////////////
391 /// Find an object in this collection using its name. Requires a sequential
392 /// scan till the object has been found. Returns 0 if object with specified
393 /// name is not found.
394 
395 TObject *TObjArray::FindObject(const char *name) const
396 {
397  Int_t nobjects = GetAbsLast()+1;
398  for (Int_t i = 0; i < nobjects; ++i) {
399  TObject *obj = fCont[i];
400  if (obj && 0==strcmp(name, obj->GetName())) return obj;
401  }
402  return 0;
403 }
404 
405 ////////////////////////////////////////////////////////////////////////////////
406 /// Find an object in this collection using the object's IsEqual()
407 /// member function. Requires a sequential scan till the object has
408 /// been found. Returns 0 if object is not found.
409 /// Typically this function is overridden by a more efficient version
410 /// in concrete collection classes (e.g. THashTable).
411 
413 {
414  Int_t nobjects = GetAbsLast()+1;
415  for (Int_t i = 0; i < nobjects; ++i) {
416  TObject *obj = fCont[i];
417  if (obj && obj->IsEqual(iobj)) return obj;
418  }
419  return 0;
420 }
421 
422 ////////////////////////////////////////////////////////////////////////////////
423 /// Stream all objects in the array to or from the I/O buffer.
424 
425 void TObjArray::Streamer(TBuffer &b)
426 {
427  UInt_t R__s, R__c;
428  Int_t nobjects;
429  if (b.IsReading()) {
430  Version_t v = b.ReadVersion(&R__s, &R__c);
431  if (v > 2)
432  TObject::Streamer(b);
433  if (v > 1)
434  fName.Streamer(b);
435 
436  if (GetEntriesFast() > 0) Clear();
437 
438  b >> nobjects;
439  b >> fLowerBound;
440  if (nobjects >= fSize) Expand(nobjects);
441  fLast = -1;
442  TObject *obj;
443  for (Int_t i = 0; i < nobjects; i++) {
444  obj = (TObject*) b.ReadObjectAny(TObject::Class());
445  if (obj) {
446  fCont[i] = obj;
447  fLast = i;
448  }
449  }
450  Changed();
451  b.CheckByteCount(R__s, R__c,TObjArray::IsA());
452  } else {
453  R__c = b.WriteVersion(TObjArray::IsA(), kTRUE);
454  TObject::Streamer(b);
455  fName.Streamer(b);
456  nobjects = GetAbsLast()+1;
457  b << nobjects;
458  b << fLowerBound;
459 
460  for (Int_t i = 0; i < nobjects; i++) {
461  b << fCont[i];
462  }
463  b.SetByteCount(R__c, kTRUE);
464  }
465 }
466 
467 ////////////////////////////////////////////////////////////////////////////////
468 /// Return the object in the first slot.
469 
471 {
472  return fCont[0];
473 }
474 
475 ////////////////////////////////////////////////////////////////////////////////
476 /// Return the object in the last filled slot. Returns 0 if no entries.
477 
479 {
480  if (fLast == -1)
481  return 0;
482  else
483  return fCont[GetAbsLast()];
484 }
485 
486 ////////////////////////////////////////////////////////////////////////////////
487 /// Return the number of objects in array (i.e. number of non-empty slots).
488 /// Attention: use this method ONLY if you want to know the number of
489 /// non-empty slots. This function loops over the complete array and
490 /// is therefore very slow when applied in a loop. Most of the time you
491 /// better use GetEntriesFast() (only in case when there are no empty slots).
492 
494 {
495  Int_t cnt = 0;
496 
497  for (Int_t i = 0; i < fSize; i++)
498  if (fCont[i]) cnt++;
499 
500  return cnt;
501 }
502 
503 ////////////////////////////////////////////////////////////////////////////////
504 /// Return absolute index to last object in array. Returns -1 in case
505 /// array is empty.
506 
508 {
509  // For efficiency we need sometimes to update fLast so we have
510  // to cast const away. Ugly, but making GetAbsLast() not const breaks
511  // many other const functions.
512  if (fLast == -2) {
513  for (Int_t i = fSize-1; i >= 0; i--)
514  if (fCont[i]) {
515  ((TObjArray*)this)->fLast = i;
516  return fLast;
517  }
518  ((TObjArray*)this)->fLast = -1;
519  }
520  return fLast;
521 }
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 /// Return index of last object in array. Returns lowerBound-1 in case
525 /// array is empty.
526 
528 {
529  return fLowerBound+GetAbsLast();
530 }
531 
532 ////////////////////////////////////////////////////////////////////////////////
533 /// Return address of pointer obj. If obj is 0 returns address of container.
534 
536 {
537  if (!obj)
538  return fCont;
539 
540  Int_t index = IndexOf(obj);
541  return &fCont[index];
542 }
543 
544 ////////////////////////////////////////////////////////////////////////////////
545 /// - obj != 0 Return index of object in array.
546 /// Returns lowerBound-1 in case array doesn't contain the obj.
547 ///
548 /// - obj == 0 Return the index of the first empty slot.
549 /// Returns lowerBound-1 in case array doesn't contain any empty slot.
550 
552 {
553  Int_t i;
554  if (obj) {
555  for (i = 0; i < fSize; i++)
556  if (fCont[i] && fCont[i]->IsEqual(obj))
557  return i+fLowerBound;
558  } else { // Look for the first empty slot
559  for (i = 0; i < fSize; i++)
560  if (!fCont[i])
561  return i+fLowerBound;
562  }
563 
564  return fLowerBound-1;
565 }
566 
567 ////////////////////////////////////////////////////////////////////////////////
568 /// Initialize a TObjArray.
569 
570 void TObjArray::Init(Int_t s, Int_t lowerBound)
571 {
572  if (fCont && fSize != s) {
574  fCont = 0;
575  }
576 
577  fSize = s;
578 
579  if (!fCont)
580  fCont = (TObject**) TStorage::Alloc(fSize*sizeof(TObject*)); //new TObject* [fSize];
581  memset(fCont, 0, fSize*sizeof(TObject*));
582  fLowerBound = lowerBound;
583  fLast = -1;
584  Changed();
585 }
586 
587 ////////////////////////////////////////////////////////////////////////////////
588 /// Returns an array iterator.
589 
591 {
592  return new TObjArrayIter(this, dir);
593 }
594 
595 ////////////////////////////////////////////////////////////////////////////////
596 /// Generate an out-of-bounds error. Always returns false.
597 
598 Bool_t TObjArray::OutOfBoundsError(const char *where, Int_t i) const
599 {
600  Error(where, "index %d out of bounds (size: %d, this: 0x%lx)", i, fSize, (Long_t)this);
601  return kFALSE;
602 }
603 
604 ////////////////////////////////////////////////////////////////////////////////
605 /// Remove object from this collection and recursively remove the object
606 /// from all other objects (and collections).
607 
609 {
610  if (!obj) return;
611 
612  for (int i = 0; i < fSize; i++) {
613  if (fCont[i] && fCont[i]->TestBit(kNotDeleted) && fCont[i]->IsEqual(obj)) {
614  fCont[i] = 0;
615  // recalculate array size
616  if (i == fLast)
617  do {
618  fLast--;
619  } while (fLast >= 0 && fCont[fLast] == 0);
620  Changed();
621  } else if (fCont[i] && fCont[i]->TestBit(kNotDeleted))
622  fCont[i]->RecursiveRemove(obj);
623  }
624 }
625 
626 ////////////////////////////////////////////////////////////////////////////////
627 /// Remove object at index idx.
628 
630 {
631  if (!BoundsOk("RemoveAt", idx)) return 0;
632 
633  int i = idx-fLowerBound;
634 
635  TObject *obj = 0;
636  if (fCont[i]) {
637  obj = fCont[i];
638  fCont[i] = 0;
639  // recalculate array size
640  if (i == fLast)
641  do {
642  fLast--;
643  } while (fLast >= 0 && fCont[fLast] == 0);
644  Changed();
645  }
646  return obj;
647 }
648 
649 ////////////////////////////////////////////////////////////////////////////////
650 /// Remove object from array.
651 
653 {
654  if (!obj) return 0;
655 
656  Int_t idx = IndexOf(obj) - fLowerBound;
657 
658  if (idx == -1) return 0;
659 
660  TObject *ob = fCont[idx];
661  fCont[idx] = 0;
662  // recalculate array size
663  if (idx == fLast)
664  do {
665  fLast--;
666  } while (fLast >= 0 && fCont[fLast] == 0);
667  Changed();
668  return ob;
669 }
670 
671 ////////////////////////////////////////////////////////////////////////////////
672 /// Remove objects from index idx1 to idx2 included.
673 
675 {
676  if (!BoundsOk("RemoveRange", idx1)) return;
677  if (!BoundsOk("RemoveRange", idx2)) return;
678 
679  idx1 -= fLowerBound;
680  idx2 -= fLowerBound;
681 
682  Bool_t change = kFALSE;
683  for (TObject **obj = fCont+idx1; obj <= fCont+idx2; obj++) {
684  if (*obj) {
685  *obj = 0;
686  change = kTRUE;
687  }
688  }
689 
690  // recalculate array size
691  if (change) Changed();
692  if (idx1 < fLast || fLast > idx2) return;
693  do { fLast--; } while (fLast >= 0 && fCont[fLast] == 0);
694 }
695 
696 ////////////////////////////////////////////////////////////////////////////////
697 /// Set index of last object in array, effectively truncating the
698 /// array. Use carefully since whenever last position has to be
699 /// recalculated, e.g. after a Remove() or Sort() it will be reset
700 /// to the last non-empty slot. If last is -2 this will force the
701 /// recalculation of the last used slot.
702 /// If last is -1, this effectively truncate the array completely.
703 
705 {
706  if (last == -2 || last == -1)
707  fLast = last;
708  else if (BoundsOk("SetLast", last))
709  fLast = last - fLowerBound;
710 }
711 
712 ////////////////////////////////////////////////////////////////////////////////
713 /// Randomize objects inside the array, i.e. permute randomly objects.
714 /// With fLast being the index of the last entry in the array, the following
715 /// algorithm is applied to the array:
716 ///
717 /// - for each entry j between 0 and fLast, another entry k is chosen
718 /// randomly between 0 and fLast.
719 /// - the objects at j and k are swapped.
720 /// - this process is repeated ntimes (ntimes = 1 by default).
721 
723 {
724  for (Int_t i = 0; i < ntimes; i++) {
725  for (Int_t j = 0; j < fLast; j++) {
726 #ifdef R__WIN32
727  Int_t k = (Int_t)(0.5+fLast*Double_t(rand())/Double_t((RAND_MAX+1.0)));
728 #else
729  Int_t k = (Int_t)(0.5+fLast*Double_t(random())/Double_t((RAND_MAX+1.0)));
730 #endif
731  if (k == j) continue;
732  TObject *obj = fCont[j];
733  fCont[j] = fCont[k];
734  fCont[k] = obj;
735  }
736  }
737 }
738 
739 ////////////////////////////////////////////////////////////////////////////////
740 /// If objects in array are sortable (i.e. IsSortable() returns true
741 /// for all objects) then sort array.
742 
744 {
745  if (GetAbsLast() == -1 || fSorted) return;
746  for (Int_t i = 0; i < fSize; i++)
747  if (fCont[i]) {
748  if (!fCont[i]->IsSortable()) {
749  Error("Sort", "objects in array are not sortable");
750  return;
751  }
752  }
753 
754  QSort(fCont, 0, TMath::Min(fSize, upto-fLowerBound));
755 
756  fLast = -2;
757  fSorted = kTRUE;
758 }
759 
760 ////////////////////////////////////////////////////////////////////////////////
761 /// Find object using a binary search. Array must first have been sorted.
762 /// Search can be limited by setting upto to desired index.
763 
765 {
766  Int_t base, position, last, result = 0;
767  TObject *op2;
768 
769  if (!op) return -1;
770 
771  if (!fSorted) {
772  Error("BinarySearch", "array must first be sorted");
773  return -1;
774  }
775 
776  base = 0;
777  last = TMath::Min(fSize, upto-fLowerBound) - 1;
778 
779  while (last >= base) {
780  position = (base+last) / 2;
781  op2 = fCont[position];
782  if (op2 && (result = op->Compare(op2)) == 0)
783  return position + fLowerBound;
784  if (!op2 || result < 0)
785  last = position-1;
786  else
787  base = position+1;
788  }
789  return -1;
790 }
791 
792 /** \class TObjArrayIter
793 Iterator of object array.
794 */
795 
797 
798 ////////////////////////////////////////////////////////////////////////////////
799 /// Create array iterator. By default the iteration direction
800 /// is kIterForward. To go backward use kIterBackward.
801 
803 {
804  fArray = arr;
805  fDirection = dir;
806  Reset();
807 }
808 
809 ////////////////////////////////////////////////////////////////////////////////
810 /// Copy ctor.
811 
813 {
814  fArray = iter.fArray;
815  fDirection = iter.fDirection;
816  fCursor = iter.fCursor;
817  fCurCursor = iter.fCurCursor;
818 }
819 
820 ////////////////////////////////////////////////////////////////////////////////
821 /// Overridden assignment operator.
822 
824 {
825  if (this != &rhs && rhs.IsA() == TObjArrayIter::Class()) {
826  const TObjArrayIter &rhs1 = (const TObjArrayIter &)rhs;
827  fArray = rhs1.fArray;
828  fDirection = rhs1.fDirection;
829  fCursor = rhs1.fCursor;
830  fCurCursor = rhs1.fCurCursor;
831  }
832  return *this;
833 }
834 
835 ////////////////////////////////////////////////////////////////////////////////
836 /// Overloaded assignment operator.
837 
839 {
840  if (this != &rhs) {
841  fArray = rhs.fArray;
842  fDirection = rhs.fDirection;
843  fCursor = rhs.fCursor;
844  fCurCursor = rhs.fCurCursor;
845  }
846  return *this;
847 }
848 
849 ////////////////////////////////////////////////////////////////////////////////
850 /// Return next object in array. Returns 0 when no more objects in array.
851 
853 {
854  if (fDirection == kIterForward) {
855  for ( ; fCursor < fArray->Capacity() && fArray->fCont[fCursor] == 0;
856  fCursor++) { }
857 
859  if (fCursor < fArray->Capacity()) {
860  return fArray->fCont[fCursor++];
861  }
862  } else {
863  for ( ; fCursor >= 0 && fArray->fCont[fCursor] == 0;
864  fCursor--) { }
865 
867  if (fCursor >= 0) {
868  return fArray->fCont[fCursor--];
869  }
870  }
871  return 0;
872 }
873 
874 ////////////////////////////////////////////////////////////////////////////////
875 /// Reset array iterator.
876 
878 {
879  if (fDirection == kIterForward)
880  fCursor = 0;
881  else
882  fCursor = fArray->Capacity() - 1;
883 
885 }
886 
887 ////////////////////////////////////////////////////////////////////////////////
888 /// This operator compares two TIterator objects.
889 
891 {
892  if (aIter.IsA() == TObjArrayIter::Class()) {
893  const TObjArrayIter &iter(dynamic_cast<const TObjArrayIter &>(aIter));
894  return (fCurCursor != iter.fCurCursor);
895  }
896  return false; // for base class we don't implement a comparison
897 }
898 
899 ////////////////////////////////////////////////////////////////////////////////
900 /// This operator compares two TObjArrayIter objects.
901 
903 {
904  return (fCurCursor != aIter.fCurCursor);
905 }
906 
907 ////////////////////////////////////////////////////////////////////////////////
908 /// Return current object or nullptr.
909 
911 {
912  return (((fCurCursor >= 0) && (fCurCursor < fArray->Capacity())) ?
913  fArray->fCont[fCurCursor] : nullptr);
914 }
static void Dealloc(void *ptr)
De-allocate block of memory, that was allocated via TStorage::Alloc().
Definition: TStorage.cxx:164
virtual TObject * Remove(TObject *obj)=0
ClassImp(TObjArray) TObjArray
Create an object array.
Definition: TObjArray.cxx:55
TObjArray(Int_t s=TCollection::kInitCapacity, Int_t lowerBound=0)
An array of TObjects.
Definition: TObjArray.h:39
Bool_t IsOnHeap() const
Definition: TObject.h:140
virtual Int_t AddAtFree(TObject *obj)
Return the position of the new object.
Definition: TObjArray.cxx:251
Bool_t IsReading() const
Definition: TBuffer.h:81
short Version_t
Definition: RtypesCore.h:61
virtual void Sort(Int_t upto=kMaxInt)
If objects in array are sortable (i.e.
Definition: TObjArray.cxx:743
Int_t Capacity() const
Definition: TCollection.h:80
virtual void Clear(Option_t *option="")
Remove all objects from the array.
Definition: TObjArray.cxx:297
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:527
const char Option_t
Definition: RtypesCore.h:62
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:328
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
Bool_t IsSortable() const
Definition: TCollection.h:102
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:340
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:652
TObject * ob
virtual void Randomize(Int_t ntimes=1)
Randomize objects inside the array, i.e.
Definition: TObjArray.cxx:722
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
Iterator of object array.
Definition: TObjArray.h:124
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
TString fName
Definition: TCollection.h:62
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
virtual void AddFirst(TObject *obj)
Add object in the first slot of the array.
Definition: TObjArray.cxx:156
const TObjArray * fArray
Definition: TObjArray.h:130
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
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:527
TIterator * MakeIterator(Bool_t dir=kIterForward) const
Returns an array iterator.
Definition: TObjArray.cxx:590
Iterator abstract base class.
Definition: TIterator.h:32
virtual void RemoveRange(Int_t idx1, Int_t idx2)
Remove objects from index idx1 to idx2 included.
Definition: TObjArray.cxx:674
virtual TObject *& operator[](Int_t i)
Return the object at position i.
Definition: TObjArray.cxx:127
virtual void RecursiveRemove(TObject *obj)
Recursively remove this object from a list.
Definition: TObject.cxx:616
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:395
Bool_t fDirection
Definition: TObjArray.h:133
Sequenceable collection abstract base class.
void Class()
Definition: Class.C:29
void SetLast(Int_t last)
Set index of last object in array, effectively truncating the array.
Definition: TObjArray.cxx:704
virtual void Changed()
virtual void AddAfter(const TObject *after, TObject *obj)
Add object in the slot after object after.
Definition: TObjArray.cxx:203
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2469
virtual ~TObjArray()
Delete an array.
Definition: TObjArray.cxx:92
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:118
virtual Int_t GrowBy(Int_t delta) const
Increase the collection's capacity by delta slots.
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
TObjArray & operator=(const TObjArray &)
Assignment operator. Note, unsets the kIsOwner flag.
Definition: TObjArray.cxx:105
TObject * Next()
Return next object in array. Returns 0 when no more objects in array.
Definition: TObjArray.cxx:852
void Reset()
Reset array iterator.
Definition: TObjArray.cxx:877
const Bool_t kIterForward
Definition: TCollection.h:43
virtual Int_t BinarySearch(TObject *obj, Int_t upto=kMaxInt)
Find object using a binary search.
Definition: TObjArray.cxx:764
TObject * First() const
Return the object in the first slot.
Definition: TObjArray.cxx:470
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
TSeqCollection * GetListOfCleanups() const
Definition: TROOT.h:232
friend class TObjArrayIter
Definition: TObjArray.h:41
Int_t fLast
Definition: TObjArray.h:47
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:551
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:221
Bool_t operator!=(const TIterator &aIter) const
This operator compares two TIterator objects.
Definition: TObjArray.cxx:890
Bool_t IsOwner() const
Definition: TCollection.h:101
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:629
TClass * IsA() const
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TObject * Before(const TObject *obj) const
Return the object before obj. Returns 0 if obj is first object.
Definition: TObjArray.cxx:283
Int_t fCurCursor
Definition: TObjArray.h:131
Int_t fSize
Definition: TCollection.h:63
void Init(Int_t s, Int_t lowerBound)
Initialize a TObjArray.
Definition: TObjArray.cxx:570
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
void Reset(Detail::TBranchProxy *x)
TROOT * GetROOT()
Definition: TROOT.cxx:375
void Warning(const char *location, const char *msgfmt,...)
TObject ** fCont
Definition: TObjArray.h:45
static void QSort(TObject **a, Int_t first, Int_t last)
Sort array of TObject pointers using a quicksort algorithm.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:238
Int_t fLowerBound
Array contents.
Definition: TObjArray.h:46
static void * Alloc(size_t size)
Allocate a block of memory, that later can be resized using TStorage::ReAlloc().
Definition: TStorage.cxx:146
static void GarbageCollect(TObject *obj)
Add to the list of things to be cleaned up.
Int_t fCursor
Definition: TObjArray.h:132
long Long_t
Definition: RtypesCore.h:50
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
TIterator & operator=(const TIterator &rhs)
Overridden assignment operator.
Definition: TObjArray.cxx:823
double Double_t
Definition: RtypesCore.h:55
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
Definition: TObjArray.cxx:369
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:493
virtual void * ReadObjectAny(const TClass *cast)=0
#define name(a, b)
Definition: linkTestLib0.cpp:5
TObject * operator*() const
Return current object or nullptr.
Definition: TObjArray.cxx:910
Mother of all ROOT objects.
Definition: TObject.h:58
Bool_t OutOfBoundsError(const char *where, Int_t i) const
Generate an out-of-bounds error. Always returns false.
Definition: TObjArray.cxx:598
static void * ReAlloc(void *vp, size_t size)
Reallocate (i.e.
Definition: TStorage.cxx:177
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Definition: TObjArray.cxx:478
TObject * After(const TObject *obj) const
Return the object after obj. Returns 0 if obj is last object.
Definition: TObjArray.cxx:270
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TObjArray.cxx:608
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual Int_t Compare(const TObject *obj) const
Compare abstract method.
Definition: TObject.cxx:218
virtual void AddLast(TObject *obj)
Add object in the next empty slot in the array.
Definition: TObjArray.cxx:168
double result[121]
TObject ** GetObjectRef() const
Definition: TObjArray.h:70
Int_t GetAbsLast() const
Return absolute index to last object in array.
Definition: TObjArray.cxx:507
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:308
const Bool_t kTRUE
Definition: Rtypes.h:91
TObject * obj
Bool_t BoundsOk(const char *where, Int_t at) const
Definition: TObjArray.h:160
const char * cnt
Definition: TXMLSetup.cxx:75
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual void AddBefore(const TObject *before, TObject *obj)
Add object in the slot before object before.
Definition: TObjArray.cxx:179