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