27 ClassImp(TOrdCollection);
32 TOrdCollection::TOrdCollection(Int_t capacity)
35 Warning(
"TOrdCollection",
"capacity (%d) < 0", capacity);
36 capacity = kDefaultCapacity;
37 }
else if (capacity == 0)
38 capacity = kDefaultCapacity;
46 TOrdCollection::~TOrdCollection()
51 TStorage::Dealloc(fCont);
59 void TOrdCollection::AddAt(TObject *obj, Int_t idx)
63 if (idx > fSize) idx = fSize;
66 SetCapacity(GrowBy(TMath::Max(fCapacity, (
int)kMinExpand)));
68 if (idx == fGapStart) {
72 physIdx = PhysIndex(idx);
73 if (physIdx < fGapStart) {
78 MoveGapTo(physIdx - fGapSize);
79 physIdx = fGapStart + fGapSize - 1;
82 R__ASSERT(physIdx >= 0 && physIdx < fCapacity);
92 void TOrdCollection::AddFirst(TObject *obj)
100 void TOrdCollection::AddLast(TObject *obj)
108 void TOrdCollection::AddBefore(
const TObject *before, TObject *obj)
113 Int_t idx = IndexOf(before);
115 Error(
"AddBefore",
"before not found, object not added");
129 void TOrdCollection::AddAfter(
const TObject *after, TObject *obj)
134 Int_t idx = IndexOf(after);
136 Error(
"AddAfter",
"after not found, object not added");
147 TObject *TOrdCollection::After(
const TObject *obj)
const
151 Int_t idx = IndexOf(obj);
152 if (idx == -1 || idx == fSize-1)
return 0;
160 TObject *TOrdCollection::At(Int_t idx)
const
162 if (IllegalIndex(
"At", idx))
return 0;
163 return fCont[PhysIndex(idx)];
170 TObject *TOrdCollection::Before(
const TObject *obj)
const
174 Int_t idx = IndexOf(obj);
175 if (idx == -1 || idx == 0)
return 0;
184 void TOrdCollection::Clear(Option_t *)
189 TStorage::Dealloc(fCont);
199 void TOrdCollection::Delete(Option_t *)
201 for (Int_t i = 0; i < fSize; i++) {
202 TObject *obj = At(i);
203 if (obj && obj->IsOnHeap())
204 TCollection::GarbageCollect(obj);
206 TStorage::Dealloc(fCont);
216 TObject *TOrdCollection::First()
const
224 TObject **TOrdCollection::GetObjectRef(
const TObject *obj)
const
226 Int_t index = IndexOf(obj);
227 return &fCont[index];
234 TObject *TOrdCollection::Last()
const
242 Bool_t TOrdCollection::IllegalIndex(
const char *method, Int_t idx)
const
244 if (idx < 0 || idx >= fSize) {
245 Error(method,
"index error (= %d) < 0 or > Size() (= %d)", idx, fSize);
255 Int_t TOrdCollection::IndexOf(
const TObject *obj)
const
257 for (Int_t i = 0; i < GetSize(); i++)
258 if (fCont[PhysIndex(i)]->IsEqual(obj))
267 void TOrdCollection::Init(Int_t capacity)
269 fCapacity = capacity;
270 fCont = (TObject**) TStorage::Alloc(fCapacity*
sizeof(TObject*));
271 memset(fCont, 0, fCapacity*
sizeof(TObject*));
280 TIterator *TOrdCollection::MakeIterator(Bool_t dir)
const
282 return new TOrdCollectionIter(
this, dir);
289 void TOrdCollection::MoveGapTo(Int_t start)
293 R__ASSERT(start + fGapSize - 1 < fCapacity);
299 if (start < fGapStart) {
300 for (i = fGapStart - 1; i >= start; i--)
301 fCont[i + fGapSize] = fCont[i];
302 }
else if (start > fGapStart) {
303 Int_t stop = start + fGapSize;
304 for (i = fGapStart + fGapSize; i < stop; i++)
305 fCont[i - fGapSize] = fCont[i];
308 for (i = fGapStart; i < fGapStart + fGapSize; i++)
315 void TOrdCollection::PutAt(TObject *obj, Int_t idx)
317 if (IllegalIndex(
"PutAt", idx))
return;
319 Int_t phx = PhysIndex(idx);
320 R__ASSERT(phx >= 0 && phx < fCapacity);
328 TObject *TOrdCollection::RemoveAt(Int_t idx)
332 if (idx == fGapStart - 1 || idx == fGapStart) {
333 if (idx == fGapStart)
334 physIdx = fGapStart + fGapSize;
336 physIdx = --fGapStart;
338 physIdx = PhysIndex(idx);
339 if (physIdx < fGapStart) {
340 MoveGapTo(physIdx + 1);
341 physIdx = --fGapStart;
343 MoveGapTo(physIdx - fGapSize);
344 physIdx = fGapStart + fGapSize;
347 R__ASSERT(physIdx >= 0 && physIdx < fCapacity);
348 TObject *obj = fCont[physIdx];
354 if (LowWaterMark()) {
355 Int_t newCapacity = TMath::Max(
int(fCapacity / kShrinkFactor), 1);
356 if (fCapacity > newCapacity)
357 SetCapacity(newCapacity);
365 TObject *TOrdCollection::Remove(TObject *obj)
369 Int_t idx = IndexOf(obj);
370 if (idx == -1)
return 0;
372 return RemoveAt(idx);
378 void TOrdCollection::SetCapacity(Int_t newCapacity)
380 R__ASSERT(newCapacity > 0);
381 R__ASSERT(fSize <= newCapacity);
383 if (fCapacity == newCapacity)
return;
385 Int_t newGapSize = newCapacity - fSize;
386 MoveGapTo(fCapacity - fGapSize);
387 fCont = (TObject**) TStorage::ReAlloc(fCont, newCapacity*
sizeof(TObject*),
388 fCapacity*
sizeof(TObject*));
389 fGapSize = newGapSize;
390 fCapacity = newCapacity;
397 void TOrdCollection::Sort()
399 if (fSize <= 0 || fSorted)
return;
400 if (!At(0)->IsSortable()) {
401 Error(
"Sort",
"objects in collection are not sortable");
405 MoveGapTo(fCapacity - fGapSize);
406 QSort(fCont, 0, fSize);
415 Int_t TOrdCollection::BinarySearch(TObject *obj)
422 Error(
"BinarySearch",
"collection must first be sorted");
426 MoveGapTo(fCapacity - fGapSize);
429 Int_t last = base + GetSize() - 1;
430 while (last >= base) {
431 Int_t position = (base + last) / 2;
432 TObject *obj2 = fCont[position];
433 if ((obj2 == 0) || (result = obj->Compare(obj2)) == 0)
434 return LogIndex(position);
447 ClassImp(TOrdCollectionIter);
453 TOrdCollectionIter::TOrdCollectionIter(
const TOrdCollection *col, Bool_t dir): fCol(col), fDirection(dir)
461 TOrdCollectionIter::TOrdCollectionIter(
const TOrdCollectionIter &iter) : TIterator(iter)
464 fDirection = iter.fDirection;
465 fCursor = iter.fCursor;
466 fCurCursor = iter.fCurCursor;
472 TIterator &TOrdCollectionIter::operator=(
const TIterator &rhs)
474 if (
this != &rhs && rhs.IsA() == TOrdCollectionIter::Class()) {
475 const TOrdCollectionIter &rhs1 = (
const TOrdCollectionIter &)rhs;
477 fDirection = rhs1.fDirection;
478 fCursor = rhs1.fCursor;
479 fCurCursor = rhs1.fCurCursor;
487 TOrdCollectionIter &TOrdCollectionIter::operator=(
const TOrdCollectionIter &rhs)
491 fDirection = rhs.fDirection;
492 fCursor = rhs.fCursor;
493 fCurCursor = rhs.fCurCursor;
502 TObject *TOrdCollectionIter::Next()
504 fCurCursor = fCursor;
505 if (fDirection == kIterForward) {
506 if (fCursor < fCol->GetSize())
507 return fCol->At(fCursor++);
510 return fCol->At(fCursor--);
518 void TOrdCollectionIter::Reset()
520 if (fDirection == kIterForward)
523 fCursor = fCol->GetSize() - 1;
525 fCurCursor = fCursor;
531 Bool_t TOrdCollectionIter::operator!=(
const TIterator &aIter)
const
533 if (aIter.IsA() == TOrdCollectionIter::Class()) {
534 const TOrdCollectionIter &iter(dynamic_cast<const TOrdCollectionIter &>(aIter));
535 return (fCurCursor != iter.fCurCursor);
543 Bool_t TOrdCollectionIter::operator!=(
const TOrdCollectionIter &aIter)
const
545 return (fCurCursor != aIter.fCurCursor);
551 TObject *TOrdCollectionIter::operator*()
const
553 return (((fCurCursor >= 0) && (fCurCursor < fCol->GetSize())) ?
554 fCol->At(fCurCursor) :
nullptr);