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