136 ClassImp(TClonesArray);
 
  140 using Updater_t = void (*)(Int_t nobjects, TObject **from, TObject **to);
 
  141 Updater_t gClonesArrayTF1Updater = 
nullptr;
 
  142 Updater_t gClonesArrayTFormulaUpdater = 
nullptr;
 
  144 bool R__SetClonesArrayTF1Updater(Updater_t func) {
 
  145    gClonesArrayTF1Updater = func;
 
  149 bool R__SetClonesArrayTFormulaUpdater(Updater_t func) {
 
  150    gClonesArrayTFormulaUpdater = func;
 
  155 static inline void R__ReleaseMemory(TClass *cl, TObject *obj)
 
  157    if (obj && obj->TestBit(TObject::kNotDeleted)) {
 
  164       if (TObject::GetObjectStat() && gObjectTable) {
 
  165          gObjectTable->RemoveQuietly(obj);
 
  167       ::operator 
delete(obj);
 
  175 TClonesArray::TClonesArray() : TObjArray()
 
  191 TClonesArray::TClonesArray(
const char *classname, Int_t s, Bool_t) : TObjArray(s)
 
  194    SetClass(classname,s);
 
  207 TClonesArray::TClonesArray(
const TClass *cl, Int_t s, Bool_t) : TObjArray(s)
 
  216 TClonesArray::TClonesArray(
const TClonesArray& tc): TObjArray(tc)
 
  218    fKeep = 
new TObjArray(tc.fSize);
 
  221    BypassStreamer(kTRUE);
 
  223    for (Int_t i = 0; i < fSize; i++) {
 
  224       if (tc.fCont[i]) fCont[i] = tc.fCont[i]->Clone();
 
  225       fKeep->fCont[i] = fCont[i];
 
  232 TClonesArray& TClonesArray::operator=(
const TClonesArray& tc)
 
  234    if (
this == &tc) 
return *
this;
 
  236    if (fClass != tc.fClass) {
 
  237       Error(
"operator=", 
"cannot copy TClonesArray's when classes are different");
 
  241    if (tc.fSize > fSize)
 
  242       Expand(TMath::Max(tc.fSize, GrowBy(fSize)));
 
  246    for (i = 0; i < fSize; i++)
 
  247       if (fKeep->fCont[i]) {
 
  248          R__ReleaseMemory(fClass,fKeep->fCont[i]);
 
  249          fKeep->fCont[i] = 
nullptr;
 
  253    BypassStreamer(kTRUE);
 
  255    for (i = 0; i < tc.fSize; i++) {
 
  256       if (tc.fCont[i]) fKeep->fCont[i] = tc.fCont[i]->Clone();
 
  257       fCont[i] = fKeep->fCont[i];
 
  268 TClonesArray::~TClonesArray()
 
  271       for (Int_t i = 0; i < fKeep->fSize; i++) {
 
  272          R__ReleaseMemory(fClass,fKeep->fCont[i]);
 
  273          fKeep->fCont[i] = 
nullptr;
 
  308 void TClonesArray::BypassStreamer(Bool_t bypass)
 
  311       SetBit(kBypassStreamer);
 
  313       ResetBit(kBypassStreamer);
 
  319 void TClonesArray::Compress()
 
  323    TObject **tmp = 
new TObject* [fSize];
 
  325    for (Int_t i = 0; i < fSize; i++) {
 
  328          fKeep->fCont[j] = fKeep->fCont[i];
 
  331          tmp[je] = fKeep->fCont[i];
 
  339    for ( ; j < fSize; j++) {
 
  341       fKeep->fCont[j] = tmp[jf];
 
  364 TObject *TClonesArray::ConstructedAt(Int_t idx)
 
  366    TObject *obj = (*this)[idx];
 
  367    if ( obj && obj->TestBit(TObject::kNotDeleted) ) {
 
  370    return (fClass) ? 
static_cast<TObject*
>(fClass->New(obj)) : 0;
 
  386 TObject *TClonesArray::ConstructedAt(Int_t idx, Option_t *clear_options)
 
  388    TObject *obj = (*this)[idx];
 
  389    if ( obj && obj->TestBit(TObject::kNotDeleted) ) {
 
  390       obj->Clear(clear_options);
 
  393    return (fClass) ? 
static_cast<TObject*
>(fClass->New(obj)) : 0;
 
  407 void TClonesArray::Clear(Option_t *option)
 
  409    if (option && option[0] == 
'C') {
 
  410       const char *cplus = strstr(option,
"+");
 
  416       Int_t n = GetEntriesFast();
 
  417       for (Int_t i = 0; i < n; i++) {
 
  418          TObject *obj = UncheckedAt(i);
 
  421             obj->ResetBit( kHasUUID );
 
  422             obj->ResetBit( kIsReferenced );
 
  423             obj->SetUniqueID( 0 );
 
  439 void TClonesArray::Delete(Option_t *)
 
  441    if ( fClass->TestBit(TClass::kIsEmulation) ) {
 
  444       for (Int_t i = 0; i < fSize; i++) {
 
  445          if (fCont[i] && fCont[i]->TestBit(kNotDeleted)) {
 
  446             fClass->Destructor(fCont[i],kTRUE);
 
  450       for (Int_t i = 0; i < fSize; i++) {
 
  451          if (fCont[i] && fCont[i]->TestBit(kNotDeleted)) {
 
  452             fCont[i]->~TObject();
 
  466 void TClonesArray::Expand(Int_t newSize)
 
  469       Error (
"Expand", 
"newSize must be positive (%d)", newSize);
 
  473       Error(
"ExpandCreate", 
"Not initialized properly, fKeep is still a nullptr");
 
  476    if (newSize == fSize)
 
  478    if (newSize < fSize) {
 
  481       for (
int i = newSize; i < fSize; i++)
 
  482          if (fKeep->fCont[i]) {
 
  483             R__ReleaseMemory(fClass,fKeep->fCont[i]);
 
  484             fKeep->fCont[i] = 
nullptr;
 
  488    TObjArray::Expand(newSize);
 
  489    fKeep->Expand(newSize);
 
  500 void TClonesArray::ExpandCreate(Int_t n)
 
  503       Error(
"ExpandCreate", 
"n must be positive (%d)", n);
 
  507       Error(
"ExpandCreate", 
"Not initialized properly, fKeep is still a nullptr");
 
  511       Expand(TMath::Max(n, GrowBy(fSize)));
 
  514    for (i = 0; i < n; i++) {
 
  515       if (!fKeep->fCont[i]) {
 
  516          fKeep->fCont[i] = (TObject*)fClass->New();
 
  517       } 
else if (!fKeep->fCont[i]->TestBit(kNotDeleted)) {
 
  519          fClass->New(fKeep->fCont[i]);
 
  521       fCont[i] = fKeep->fCont[i];
 
  524    for (i = n; i < fSize; i++)
 
  525       if (fKeep->fCont[i]) {
 
  526          R__ReleaseMemory(fClass,fKeep->fCont[i]);
 
  527          fKeep->fCont[i] = 
nullptr;
 
  544 void TClonesArray::ExpandCreateFast(Int_t n)
 
  546    Int_t oldSize = fKeep->GetSize();
 
  548       Expand(TMath::Max(n, GrowBy(fSize)));
 
  551    for (i = 0; i < n; i++) {
 
  552       if (i >= oldSize || !fKeep->fCont[i]) {
 
  553          fKeep->fCont[i] = (TObject*)fClass->New();
 
  554       } 
else if (!fKeep->fCont[i]->TestBit(kNotDeleted)) {
 
  556          fClass->New(fKeep->fCont[i]);
 
  558       fCont[i] = fKeep->fCont[i];
 
  561       memset(fCont + n, 0, (fLast - n + 1) * 
sizeof(TObject*));
 
  570 TObject *TClonesArray::RemoveAt(Int_t idx)
 
  572    if (!BoundsOk(
"RemoveAt", idx)) 
return 0;
 
  574    int i = idx-fLowerBound;
 
  576    if (fCont[i] && fCont[i]->TestBit(kNotDeleted)) {
 
  577       fCont[i]->~TObject();
 
  584          do { fLast--; } 
while (fLast >= 0 && fCont[fLast] == 0);
 
  594 TObject *TClonesArray::Remove(TObject *obj)
 
  598    Int_t i = IndexOf(obj) - fLowerBound;
 
  600    if (i == -1) 
return 0;
 
  602    if (fCont[i] && fCont[i]->TestBit(kNotDeleted)) {
 
  603       fCont[i]->~TObject();
 
  609       do { fLast--; } 
while (fLast >= 0 && fCont[fLast] == 0);
 
  617 void TClonesArray::RemoveRange(Int_t idx1, Int_t idx2)
 
  619    if (!BoundsOk(
"RemoveRange", idx1)) 
return;
 
  620    if (!BoundsOk(
"RemoveRange", idx2)) 
return;
 
  625    Bool_t change = kFALSE;
 
  626    for (TObject **obj=fCont+idx1; obj<=fCont+idx2; obj++) {
 
  628       if ((*obj)->TestBit(kNotDeleted)) {
 
  636    if (change) Changed();
 
  637    if (idx1 < fLast || fLast > idx2) 
return;
 
  638    do { fLast--; } 
while (fLast >= 0 && fCont[fLast] == 0);
 
  651 void TClonesArray::SetClass(
const TClass *cl, Int_t s)
 
  654       Error(
"SetClass", 
"TClonesArray already initialized with another class");
 
  657    fClass = (TClass*)cl;
 
  660       Error(
"SetClass", 
"called with a null pointer");
 
  663    const char *classname = fClass->GetName();
 
  664    if (!fClass->IsTObject()) {
 
  666       Error(
"SetClass", 
"%s does not inherit from TObject", classname);
 
  669    if (fClass->GetBaseClassOffset(TObject::Class())!=0) {
 
  671       Error(
"SetClass", 
"%s must inherit from TObject as the left most base class.", classname);
 
  674    Int_t nch = strlen(classname)+2;
 
  675    char *name = 
new char[nch];
 
  676    snprintf(name,nch, 
"%ss", classname);
 
  680    fKeep = 
new TObjArray(s);
 
  682    BypassStreamer(kTRUE);
 
  688 void TClonesArray::SetClass(
const char *classname, Int_t s)
 
  690    SetClass(TClass::GetClass(classname),s);
 
  699 void TClonesArray::SetOwner(Bool_t )
 
  708 void TClonesArray::Sort(Int_t upto)
 
  710    Int_t nentries = GetAbsLast()+1;
 
  711    if (nentries <= 0 || fSorted) 
return;
 
  712    for (Int_t i = 0; i < fSize; i++)
 
  714          if (!fCont[i]->IsSortable()) {
 
  715             Error(
"Sort", 
"objects in array are not sortable");
 
  720    QSort(fCont, fKeep->fCont, 0, TMath::Min(nentries, upto-fLowerBound));
 
  731 void TClonesArray::Streamer(TBuffer &b)
 
  742       Version_t v = b.ReadVersion(&R__s, &R__c);
 
  744          const Int_t kOldBypassStreamer = BIT(14);
 
  745          if (TestBit(kOldBypassStreamer)) BypassStreamer();
 
  748          TObject::Streamer(b);
 
  754       Ssiz_t pos = s.Index(
";");
 
  757          s = s(pos+1, s.Length()-pos-1);
 
  760       TClass *cl = TClass::GetClass(classv);
 
  762          Error(
"Streamer", 
"expecting class %s but it was not found by TClass::GetClass\n",
 
  764          b.CheckByteCount(R__s, R__c,TClonesArray::IsA());
 
  770          nobjects = -nobjects;  
 
  775             fKeep  = 
new TObjArray(fSize);
 
  778       } 
else if (cl != fClass && classv == fClass->GetName()) {
 
  790       if (fKeep->GetSize() < nobjects)
 
  794       Int_t oldLast = fLast;
 
  798       if (CanBypassStreamer() && !b.TestBit(TBuffer::kCannotHandleMemberWiseStreaming)) {
 
  799          for (Int_t i = 0; i < nobjects; i++) {
 
  800             if (!fKeep->fCont[i]) {
 
  801                fKeep->fCont[i] = (TObject*)fClass->New();
 
  802             } 
else if (!fKeep->fCont[i]->TestBit(kNotDeleted)) {
 
  804                fClass->New(fKeep->fCont[i]);
 
  807             fCont[i] = fKeep->fCont[i];
 
  809          if (clv < 8 && classv == 
"TF1") {
 
  812             TClonesArray temp(
"ROOT::v5::TF1Data");
 
  813             temp.ExpandCreate(nobjects);
 
  814             b.ReadClones(&temp, nobjects, clv);
 
  816             if (gClonesArrayTF1Updater)
 
  817                gClonesArrayTF1Updater(nobjects, temp.GetObjectRef(
nullptr), this->GetObjectRef(
nullptr));
 
  818          } 
else if (clv <= 8 && clv > 3 && clv != 6 && classv == 
"TFormula") {
 
  821             TClonesArray temp(
"ROOT::v5::TFormula");
 
  822             temp.ExpandCreate(nobjects);
 
  823             b.ReadClones(&temp, nobjects, clv);
 
  825             if (gClonesArrayTFormulaUpdater)
 
  826                gClonesArrayTFormulaUpdater(nobjects, temp.GetObjectRef(
nullptr), this->GetObjectRef(
nullptr));
 
  829             b.ReadClones(
this, nobjects, clv);
 
  832          for (Int_t i = 0; i < nobjects; i++) {
 
  835                if (!fKeep->fCont[i])
 
  836                   fKeep->fCont[i] = (TObject*)fClass->New();
 
  837                else if (!fKeep->fCont[i]->TestBit(kNotDeleted)) {
 
  839                   fClass->New(fKeep->fCont[i]);
 
  842                fCont[i] = fKeep->fCont[i];
 
  843                b.StreamObject(fKeep->fCont[i]);
 
  847       for (Int_t i = TMath::Max(nobjects,0); i < oldLast+1; ++i) fCont[i] = 0;
 
  849       b.CheckByteCount(R__s, R__c,TClonesArray::IsA());
 
  855       b.ForceWriteInfoClones(
this);
 
  862       Bool_t bypass = kFALSE;
 
  863       if (b.TestBit(TBuffer::kCannotHandleMemberWiseStreaming)) {
 
  864          bypass = CanBypassStreamer();
 
  865          BypassStreamer(kFALSE);
 
  868       R__c = b.WriteVersion(TClonesArray::IsA(), kTRUE);
 
  869       TObject::Streamer(b);
 
  871       s.Form(
"%s;%d", fClass->GetName(), fClass->GetClassVersion());
 
  873       nobjects = GetEntriesFast();
 
  876       if (CanBypassStreamer()) {
 
  877          b.WriteClones(
this,nobjects);
 
  879          for (Int_t i = 0; i < nobjects; i++) {
 
  886                b.StreamObject(fCont[i]);
 
  890       b.SetByteCount(R__c, kTRUE);
 
  906 TObject *&TClonesArray::operator[](Int_t idx)
 
  909       Error(
"operator[]", 
"out of bounds at %d in %lx", idx, (Long_t)
this);
 
  913       Error(
"operator[]", 
"invalid class specified in TClonesArray ctor");
 
  917       Expand(TMath::Max(idx+1, GrowBy(fSize)));
 
  919    if (!fKeep->fCont[idx]) {
 
  920       fKeep->fCont[idx] = (TObject*) TStorage::ObjectAlloc(fClass->Size());
 
  927       fKeep->fCont[idx]->fBits &= ~kNotDeleted;
 
  929    fCont[idx] = fKeep->fCont[idx];
 
  931    fLast = TMath::Max(idx, GetAbsLast());
 
  940 TObject *TClonesArray::operator[](Int_t idx)
 const 
  942    if (idx < 0 || idx >= fSize) {
 
  943       Error(
"operator[]", 
"out of bounds at %d in %lx", idx, (Long_t)
this);
 
  954 TObject *TClonesArray::New(Int_t idx)
 
  957       Error(
"New", 
"out of bounds at %d in %lx", idx, (Long_t)
this);
 
  961       Error(
"New", 
"invalid class specified in TClonesArray ctor");
 
  965    return (TObject *)fClass->New(
operator[](idx));
 
  978 void TClonesArray::AbsorbObjects(TClonesArray *tc)
 
  981    if (tc == 0 || tc == 
this || tc->GetEntriesFast() == 0) 
return;
 
  982    AbsorbObjects(tc, 0, tc->GetEntriesFast() - 1);
 
  991 void TClonesArray::AbsorbObjects(TClonesArray *tc, Int_t idx1, Int_t idx2)
 
  994    if (tc == 0 || tc == 
this || tc->GetEntriesFast() == 0) 
return;
 
  995    if (fClass != tc->fClass) {
 
  996       Error(
"AbsorbObjects", 
"cannot absorb objects when classes are different");
 
 1001       Error(
"AbsorbObjects", 
"range is not valid: idx1>idx2");
 
 1004    if (idx2 >= tc->GetEntriesFast()) {
 
 1005       Error(
"AbsorbObjects", 
"range is not valid: idx2 out of bounds");
 
 1010    Bool_t wasSorted = IsSorted() && tc->IsSorted() &&
 
 1011                       (Last() == 0 || Last()->Compare(tc->First()) == -1);
 
 1014    Int_t oldSize = GetEntriesFast();
 
 1015    Int_t newSize = oldSize + (idx2-idx1+1);
 
 1020    for (Int_t i = idx1; i <= idx2; i++) {
 
 1021       Int_t newindex = oldSize+i -idx1;
 
 1022       fCont[newindex] = tc->fCont[i];
 
 1023       R__ReleaseMemory(fClass,fKeep->fCont[newindex]);
 
 1024       (*fKeep)[newindex] = (*(tc->fKeep))[i];
 
 1026       (*(tc->fKeep))[i] = 0;
 
 1030    for (Int_t i = idx2+1; i < tc->GetEntriesFast(); i++) {
 
 1031       tc->fCont[i-(idx2-idx1+1)] = tc->fCont[i];
 
 1032       (*(tc->fKeep))[i-(idx2-idx1+1)] = (*(tc->fKeep))[i];
 
 1034       (*(tc->fKeep))[i] = 0;
 
 1036    tc->fLast = tc->GetEntriesFast() - 2 - (idx2 - idx1);
 
 1047 void TClonesArray::MultiSort(Int_t nTCs, TClonesArray** tcs, Int_t upto)
 
 1049    Int_t nentries = GetAbsLast()+1;
 
 1050    if (nentries <= 1 || fSorted) 
return;
 
 1051    Bool_t sortedCheck = kTRUE;
 
 1052    for (Int_t i = 0; i < fSize; i++) {
 
 1054          if (!fCont[i]->IsSortable()) {
 
 1055             Error(
"MultiSort", 
"objects in array are not sortable");
 
 1059       if (sortedCheck && i > 1) {
 
 1060          if (ObjCompare(fCont[i], fCont[i-1]) < 0) sortedCheck = kFALSE;
 
 1068    for (
int i = 0; i < nTCs; i++) {
 
 1069       if (tcs[i] == 
this) {
 
 1070          Error(
"MultiSort", 
"tcs[%d] = \"this\"", i);
 
 1073       if (tcs[i]->GetEntriesFast() != GetEntriesFast()) {
 
 1074          Error(
"MultiSort", 
"tcs[%d] has length %d != length of this (%d)",
 
 1075                i, tcs[i]->GetEntriesFast(), this->GetEntriesFast());
 
 1081    TObject*** b = 
new TObject**[nBs];
 
 1082    for (
int i = 0; i < nTCs; i++) {
 
 1083       b[2*i]   = tcs[i]->fCont;
 
 1084       b[2*i+1] = tcs[i]->fKeep->fCont;
 
 1086    b[nBs-1] = fKeep->fCont;
 
 1087    QSort(fCont, nBs, b, 0, TMath::Min(nentries, upto-fLowerBound));