// @(#)root/tree:$Id$
// Author Lukasz Janyst <ljanyst@cern.ch>  23/01/2008

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TBranchSTL                                                           //
//                                                                      //
// A Branch handling STL collection of pointers (vectors, lists, queues,//
// sets and multisets) while storing them in split mode                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


#include "TBranchSTL.h"
#include "TList.h"
#include "TBranchElement.h"
#include "TBasket.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"
#include <string>
#include <utility>

#include "TError.h"

ClassImp(TBranchSTL)

//------------------------------------------------------------------------------
TBranchSTL::TBranchSTL():
   fCollProxy( 0 ),
   fParent( 0 ),
   fIndArrayCl( 0 ),
   fClassVersion( 0 ),
   fClCheckSum( 0 ),
   fInfo( 0 ),
   fObject( 0 ),
   fID( -2 )
{
   // Default constructor.

   fIndArrayCl = TClass::GetClass( "TIndArray" );
   fBranchVector.reserve( 25 );
   fNleaves = 0;
   fReadLeaves = (ReadLeaves_t)&TBranchSTL::ReadLeavesImpl;
   fFillLeaves = (FillLeaves_t)&TBranchSTL::FillLeavesImpl;
}

//------------------------------------------------------------------------------
TBranchSTL::TBranchSTL( TTree *tree, const char *name,
                        TVirtualCollectionProxy *collProxy,
                        Int_t buffsize, Int_t splitlevel )
{
   // Normal constructor, called from TTree.

   fTree         = tree;
   fCollProxy    = collProxy;
   fBasketSize   = buffsize;
   fSplitLevel   = splitlevel;
   fContName     = collProxy->GetCollectionClass()->GetName();
   fClCheckSum   = 0;
   fClassVersion = 1;
   fID           = -2;
   fInfo         = 0;
   fMother = this;
   fParent = 0;
   fDirectory = fTree->GetDirectory();
   fFileName = "";
   SetName( name );
   fIndArrayCl = TClass::GetClass( "TIndArray" );
   fBranchVector.reserve( 25 );
   fNleaves = 0;
   fReadLeaves = (ReadLeaves_t)&TBranchSTL::ReadLeavesImpl;
   fFillLeaves = (FillLeaves_t)&TBranchSTL::FillLeavesImpl;

   //---------------------------------------------------------------------------
   // Allocate and initialize the basket control arrays
   //---------------------------------------------------------------------------
   fBasketBytes = new Int_t[fMaxBaskets];
   fBasketEntry = new Long64_t[fMaxBaskets];
   fBasketSeek = new Long64_t[fMaxBaskets];

   for (Int_t i = 0; i < fMaxBaskets; ++i) {
      fBasketBytes[i] = 0;
      fBasketEntry[i] = 0;
      fBasketSeek[i] = 0;
   }

}

//------------------------------------------------------------------------------
TBranchSTL::TBranchSTL( TBranch* parent, const char* name,
                        TVirtualCollectionProxy* collProxy,
                        Int_t buffsize, Int_t splitlevel,
                        TStreamerInfo* info, Int_t id )
{
   // Normal constructor, called from another branch.

   fTree         = parent->GetTree();
   fCollProxy    = collProxy;
   fBasketSize   = buffsize;
   fSplitLevel   = splitlevel;
   fContName     = collProxy->GetCollectionClass()->GetName();
   fClassName    = info->GetClass()->GetName();
   fClassVersion = info->GetClassVersion();
   fClCheckSum   = info->GetClass()->GetCheckSum();
   fInfo         = info;
   fID           = id;
   fMother = parent->GetMother();
   fParent = parent;
   fDirectory = fTree->GetDirectory();
   fFileName = "";
   fNleaves = 0;
   fReadLeaves = (ReadLeaves_t)&TBranchSTL::ReadLeavesImpl;
   fFillLeaves = (ReadLeaves_t)&TBranchSTL::FillLeavesImpl;

   SetName( name );
   fIndArrayCl = TClass::GetClass( "TIndArray" );
   fBranchVector.reserve( 25 );

   //---------------------------------------------------------------------------
   // Allocate and initialize the basket control arrays
   //---------------------------------------------------------------------------
   fBasketBytes = new Int_t[fMaxBaskets];
   fBasketEntry = new Long64_t[fMaxBaskets];
   fBasketSeek = new Long64_t[fMaxBaskets];

   for (Int_t i = 0; i < fMaxBaskets; ++i) {
      fBasketBytes[i] = 0;
      fBasketEntry[i] = 0;
      fBasketSeek[i] = 0;
   }

}

//------------------------------------------------------------------------------
TBranchSTL::~TBranchSTL()
{
   //destructor
   BranchMap_t::iterator brIter;
   for( brIter = fBranchMap.begin(); brIter != fBranchMap.end(); ++brIter ) {
      (*brIter).second.fPointers->clear();
      delete (*brIter).second.fPointers;
   }
}

//------------------------------------------------------------------------------
void TBranchSTL::Browse( TBrowser *b )
{
   //browse a STL branch
   Int_t nbranches = fBranches.GetEntriesFast();
   if (nbranches > 0) {
      TList persistentBranches;
      TBranch* branch=0;
      TIter iB(&fBranches);
      while( (branch = (TBranch*)iB()) )
         persistentBranches.Add(branch);
      persistentBranches.Browse( b );
   }
}

//------------------------------------------------------------------------------
Int_t TBranchSTL::Fill()
{
   //---------------------------------------------------------------------------
   // Cleanup after revious fill
   //---------------------------------------------------------------------------
   BranchMap_t::iterator brIter;
   for( brIter = fBranchMap.begin(); brIter != fBranchMap.end(); ++brIter )
      (*brIter).second.fPointers->clear();

   //---------------------------------------------------------------------------
   // Check if we're dealing with the null pointer here
   //---------------------------------------------------------------------------
   if( fAddress != fObject ) {
      //------------------------------------------------------------------------
      // We have received a zero pointer - treat it as an empty collection
      //------------------------------------------------------------------------
      if( fObject == 0 ) {
         Int_t bytes      = 0;
         Int_t totalBytes = 0;

         //---------------------------------------------------------------------
         // Store the indices
         //---------------------------------------------------------------------
         fInd.SetNumItems( 0 );
         bytes = TBranch::Fill();

         if( bytes < 0 ) {
            Error( "Fill", "The IO error while writing the indices!");
            return -1;
         }
         totalBytes += bytes;

         //---------------------------------------------------------------------
         // Store the branches
         //---------------------------------------------------------------------
         for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
            TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
            bytes = br->Fill();
            if( bytes < 0 ) {
               Error( "Fill", "The IO error while writing the branch %s!", br->GetName() );
               return -1;
            }
            totalBytes += bytes;
         }
         return totalBytes;
      }
   }

   //---------------------------------------------------------------------------
   // Set upt the collection proxy
   //---------------------------------------------------------------------------
   TVirtualCollectionProxy::TPushPop helper( fCollProxy, fObject );
   UInt_t size = fCollProxy->Size();

   //---------------------------------------------------------------------------
   // Set up the container of indices
   //---------------------------------------------------------------------------
   if( fInd.GetCapacity() < size )
      fInd.ClearAndResize( size );

   fInd.SetNumItems( size );

   //---------------------------------------------------------------------------
   // Loop over the elements and create branches as needed
   //---------------------------------------------------------------------------
   TClass*               cl         = fCollProxy->GetValueClass();
   TClass*               actClass   = 0;
   TClass*               vectClass  = 0;
   char*                 element    = 0;
   std::vector<void*>*   elPointers = 0;
   TBranchElement*       elBranch   = 0;
   UInt_t                elOffset   = 0;
   UChar_t               maxID      = fBranches.GetEntriesFast()+1;
   UChar_t               elID;
   ElementBranchHelper_t bHelper;
   Int_t                 totalBytes = 0;
   Int_t                 bytes      = 0;
   TString               brName;

   for( UInt_t i = 0; i < size; ++i ) {
      //------------------------------------------------------------------------
      // Determine the actual class of current element
      //------------------------------------------------------------------------
      element = *(char**)fCollProxy->At( i );
      if( !element ) {
         fInd.At(i) = 0;
         continue;
      }

      // coverity[dereference] since this is a TBranchSTL by definition the collection contains pointers to objects.
      actClass = cl->GetActualClass( element );
      brIter = fBranchMap.find( actClass );

      //------------------------------------------------------------------------
      // The branch was not found - create a new one
      //------------------------------------------------------------------------
      if( brIter == fBranchMap.end() ) {
         //---------------------------------------------------------------------
         // Find the dictionary for vector of pointers to this class
         //---------------------------------------------------------------------
         std::string vectClName("vector<");
         vectClName += actClass->GetName() + std::string("*>");
         vectClass = TClass::GetClass( vectClName.c_str() );
         if( !vectClass ) {
            Warning( "Fill", "Unable to find dictionary for class %s", vectClName.c_str() );
            continue;
         }

         //---------------------------------------------------------------------
         // Create the vector of pointers to objects of this type and new branch
         // for it
         //---------------------------------------------------------------------
         elPointers = new std::vector<void*>();//vectClass->GetCollectionProxy()->New();
         if (fName.Length() && fName[fName.Length()-1]=='.') {
            // The top level branch already has a trailing dot.
            brName.Form( "%s%s", GetName(), actClass->GetName() );
         } else {
            brName.Form( "%s.%s", GetName(), actClass->GetName() );
         }
         elBranch   = new TBranchElement( this, brName,
                                          vectClass->GetCollectionProxy(),
                                          fBasketSize, fSplitLevel-1  );
         elID = maxID++;
         elBranch->SetFirstEntry( fEntryNumber );


         fBranches.Add( elBranch );

         bHelper.fId         = elID;
         bHelper.fBranch     = elBranch;
         bHelper.fPointers   = elPointers;
         bHelper.fBaseOffset = actClass->GetBaseClassOffset( cl );

         // This copies the value of fPointes into the vector and transfers
         // its ownership to the vector.  It will be deleted in ~TBranch.
         brIter = fBranchMap.insert(std::make_pair(actClass, bHelper ) ).first;
         elBranch->SetAddress( &((*brIter).second.fPointers) );
      }
      //------------------------------------------------------------------------
      // The branch for this type already exists - set up the pointers
      //------------------------------------------------------------------------
      else {
         elPointers = (*brIter).second.fPointers;
         elBranch   = (*brIter).second.fBranch;
         elID       = (*brIter).second.fId;
         elOffset   = (*brIter).second.fBaseOffset;
      }

      //-------------------------------------------------------------------------
      // Add the element to the appropriate vector
      //-------------------------------------------------------------------------
      elPointers->push_back( element + elOffset );
      fInd.At(i) = elID;
   }

   //----------------------------------------------------------------------------
   // Store the indices
   //----------------------------------------------------------------------------
   bytes = TBranch::Fill();
   if( bytes < 0 ) {
      Error( "Fill", "The IO error while writing the indices!");
      return -1;
   }
   totalBytes += bytes;

   //----------------------------------------------------------------------------
   // Fill the branches
   //----------------------------------------------------------------------------
   for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
      TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
      bytes = br->Fill();
      if( bytes < 0 ) {
         Error( "Fill", "The IO error while writing the branch %s!", br->GetName() );
         return -1;
      }
      totalBytes += bytes;
   }

   return totalBytes;
}

//------------------------------------------------------------------------------
Int_t TBranchSTL::GetEntry( Long64_t entry, Int_t getall )
{
   //---------------------------------------------------------------------------
   // Check if we should be doing this at all
   //---------------------------------------------------------------------------
   if( TestBit( kDoNotProcess ) && !getall )
      return 0;

   if ( (entry < fFirstEntry) || (entry >= fEntryNumber) )
      return 0;

   if( !fAddress )
      return 0;

   //---------------------------------------------------------------------------
   // Set up the collection proxy
   //---------------------------------------------------------------------------
   if( !fCollProxy ) {
      TClass *cl = TClass::GetClass( fContName );

      if( !cl ) {
         Error( "GetEntry", "Dictionary class not found for: %s", fContName.Data() );
         return -1;
      }

      fCollProxy = cl->GetCollectionProxy();
      if( !fCollProxy ) {
         Error( "GetEntry", "No collection proxy!"  );
         return -1;
      }
   }

   //---------------------------------------------------------------------------
   // Get the indices
   //---------------------------------------------------------------------------
   Int_t totalBytes = 0;
   Int_t bytes = TBranch::GetEntry( entry, getall );
   totalBytes += bytes;

   if( bytes == 0 )
      return 0;

   if( bytes < 0 ) {
      Error( "GetEntry", "IO error! Unable to get the indices!"  );
      return -1;
   }

   Int_t size = fInd.GetNumItems();

   //---------------------------------------------------------------------------
   // Set up vector pointers
   //---------------------------------------------------------------------------
   UInt_t nBranches = fBranches.GetEntriesFast();
   TClass*               elClass   = fCollProxy->GetValueClass();
   TClass*               tmpClass  = 0;

   if( fBranchVector.size() < nBranches )
      fBranchVector.resize( nBranches );

   //---------------------------------------------------------------------------
   // Create the object
   //---------------------------------------------------------------------------
   if( fAddress != fObject ) {
      *((void **)fAddress) = fCollProxy->New();
      fObject = *(char**)fAddress;
   }
   TVirtualCollectionProxy::TPushPop helper( fCollProxy, fObject );
   void* env = fCollProxy->Allocate( size, kTRUE );

   //---------------------------------------------------------------------------
   // Process entries
   //---------------------------------------------------------------------------
   UChar_t             index      = 0;
   void**              element    = 0;
   std::vector<void*>* elemVect   = 0;
   TBranchElement*     elemBranch = 0;

   for( Int_t i = 0; i < size; ++i ) {
      element = (void**)fCollProxy->At(i);
      index   = fInd.At(i);

      //------------------------------------------------------------------------
      // The case of zero pointers
      //------------------------------------------------------------------------
      if( index == 0 ) {
         *element = 0;
         continue;
      }

      //-------------------------------------------------------------------------
      // Index out of range!
      //------------------------------------------------------------------------
      if( index > nBranches ) {
         Error( "GetEntry", "Index %d out of range, unable to find the branch, setting pointer to 0",
                index );
         *element = 0;
         continue;
      }

      //------------------------------------------------------------------------
      // Load unloaded branch
      //------------------------------------------------------------------------
      index--;
      elemVect = fBranchVector[index].fPointers;
      if( !elemVect ) {
         elemBranch = (TBranchElement *)fBranches.UncheckedAt(index);
         elemBranch->SetAddress( &(fBranchVector[index].fPointers) );

         bytes = elemBranch->GetEntry( entry, getall );

         if( bytes == 0 ) {
            Error( "GetEntry", "No entry for index %d, setting pointer to 0", index );
            *element = 0;
            fBranchVector[index].fPosition++;
            continue;
         }

         if( bytes <= 0 ) {
            Error( "GetEntry", "I/O error while getting entry for index %d, setting pointer to 0", index );
            *element = 0;
            fBranchVector[index].fPosition++;
            continue;
         }
         totalBytes += bytes;
         elemVect = fBranchVector[index].fPointers;

         //---------------------------------------------------------------------
         // Calculate the base class offset
         //---------------------------------------------------------------------
         TVirtualCollectionProxy *proxy = elemBranch->GetCollectionProxy();
         if (!proxy) {
            proxy =  TClass::GetClass(elemBranch->GetClassName())->GetCollectionProxy();
         }
         if (proxy) {
            tmpClass = proxy->GetValueClass();
            if (tmpClass && elClass) {
               fBranchVector[index].fBaseOffset = tmpClass->GetBaseClassOffset( elClass );
               fBranchVector[index].fPosition = 0;
            } else {
               Error("GetEntry","Missing TClass for %s (%s)",elemBranch->GetName(),elemBranch->GetClassName());
            }
         } else {
            Error("GetEntry","Missing CollectionProxy for %s (%s)",elemBranch->GetName(),elemBranch->GetClassName());
         }
      }

      //------------------------------------------------------------------------
      // Set up the element
      //------------------------------------------------------------------------
      *element =  ((char*)(*elemVect)[fBranchVector[index].fPosition++])
        - fBranchVector[index].fBaseOffset;

   }

   fCollProxy->Commit(env);

   //---------------------------------------------------------------------------
   // Cleanup
   //---------------------------------------------------------------------------
   for( UInt_t i = 0; i < fBranchVector.size(); ++i ) {
      delete fBranchVector[i].fPointers;
      fBranchVector[i].fPointers = 0;
   }

   return totalBytes;
}


//______________________________________________________________________________
Int_t TBranchSTL::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
{
   // Fill expectedClass and expectedType with information on the data type of the
   // object/values contained in this branch (and thus the type of pointers
   // expected to be passed to Set[Branch]Address
   // return 0 in case of success and > 0 in case of failure.

   expectedClass = 0;
   expectedType = kOther_t;

   if (fID < 0) {
      expectedClass = TClass::GetClass( fContName );
   } else {
      // Case of an object data member.  Here we allow for the
      // variable name to be ommitted.  Eg, for Event.root with split
      // level 1 or above  Draw("GetXaxis") is the same as Draw("fH.GetXaxis()")
      TStreamerElement* element = GetInfo()->GetElement(fID);
      if (element) {
         expectedClass = element->GetClassPointer();
         if (!expectedClass) {
            Error("GetExpectedType", "TBranchSTL did not find the TClass for %s", element->GetTypeNameBasic());
            return 1;
         }
      } else {
         Error("GetExpectedType", "Did not find the type for %s",GetName());
         return 2;
      }
   }
   return 0;
}

//------------------------------------------------------------------------------
TStreamerInfo* TBranchSTL::GetInfo() const
{
   //---------------------------------------------------------------------------
   // Check if we don't have the streamer info
   //---------------------------------------------------------------------------
   if( !fInfo ) {
      //------------------------------------------------------------------------
      // Get the class info
      //------------------------------------------------------------------------
      TClass *cl = TClass::GetClass( fClassName );

      //------------------------------------------------------------------------
      // Get unoptimized streamer info
      //------------------------------------------------------------------------
      fInfo = (TStreamerInfo*)cl->GetStreamerInfo( fClassVersion );

      //------------------------------------------------------------------------
      // If the checksum is there and we're dealing with the foreign class
      //------------------------------------------------------------------------
      if( fClCheckSum && !cl->IsVersioned() ) {
         //---------------------------------------------------------------------
         // Loop over the infos
         //---------------------------------------------------------------------
         Int_t ninfos = cl->GetStreamerInfos()->GetEntriesFast() - 1;
         for( Int_t i = -1; i < ninfos; ++i ) {
            TVirtualStreamerInfo* info = (TVirtualStreamerInfo*) cl->GetStreamerInfos()->UncheckedAt(i);
            if( !info )
               continue;

            //------------------------------------------------------------------
            // If the checksum matches then retriev the info
            //------------------------------------------------------------------
            if( info->GetCheckSum() == fClCheckSum ) {
               fClassVersion = i;
               fInfo = (TStreamerInfo*)cl->GetStreamerInfo( fClassVersion );
            }
         }
      }
   }
   return fInfo;
}

//------------------------------------------------------------------------------
Bool_t TBranchSTL::IsFolder() const
{
   //branch declared folder if at least one entry

   if( fBranches.GetEntriesFast() >= 1 )
      return kTRUE;
   return kFALSE;
}

//------------------------------------------------------------------------------
void TBranchSTL::Print(const char *option) const
{
   // Print the branch parameters.

   if (strncmp(option,"debugAddress",strlen("debugAddress"))==0) {
      if (strlen(GetName())>24) Printf("%-24s\n%-24s ", GetName(),"");
      else Printf("%-24s ", GetName());

      TBranchElement *parent = dynamic_cast<TBranchElement*>(GetMother()->GetSubBranch(this));
      Int_t ind = parent ? parent->GetListOfBranches()->IndexOf(this) : -1;
      TVirtualStreamerInfo *info = GetInfo();
      Int_t *branchOffset = parent ? parent->GetBranchOffset() : 0;

      Printf("%-16s %2d SplitCollPtr %-16s %-16s %8x %-16s n/a\n",
             info ? info->GetName() : "StreamerInfo unvailable", fID,
             GetClassName(), fParent ? fParent->GetName() : "n/a",
             (branchOffset && parent && ind>=0) ? branchOffset[ind] : 0,
             fObject);
      for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
         TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
         br->Print("debugAddressSub");
      }
   } else if (strncmp(option,"debugInfo",strlen("debugInfo"))==0)  {
      Printf("Branch %s uses:\n",GetName());
      if (fID>=0) {
         GetInfo()->GetElement(fID)->ls();
      }
      for (Int_t i = 0; i < fBranches.GetEntriesFast(); ++i) {
         TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
         subbranch->Print("debugInfoSub");
      }
      return;
   } else {
      TBranch::Print(option);
      for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i ) {
         TBranch *br = (TBranch *)fBranches.UncheckedAt(i);
         br->Print(option);
      }
   }
}

//------------------------------------------------------------------------------
void TBranchSTL::ReadLeavesImpl( TBuffer& b )
{
   //TO BE DOCUMENTED

   b.ReadClassBuffer( fIndArrayCl, &fInd );
}

//------------------------------------------------------------------------------
void TBranchSTL::FillLeavesImpl( TBuffer& b )
{
   //TO BE DOCUMENTED

   b.WriteClassBuffer( fIndArrayCl, &fInd );
}

//------------------------------------------------------------------------------
void TBranchSTL::SetAddress( void* addr )
{
   //---------------------------------------------------------------------------
   // We are the top level branch
   //---------------------------------------------------------------------------
   if( fID < 0 ) {
      fAddress = (char*)addr;
      fObject  = *(char**)addr;
   }
   //---------------------------------------------------------------------------
   // We are a data member of some other class
   //---------------------------------------------------------------------------
   else {
      //------------------------------------------------------------------------
      // Get the appropriate streamer element
      //------------------------------------------------------------------------
      GetInfo();
      TStreamerElement *el = (TStreamerElement*)fInfo->GetElements()->At( fID );

      //------------------------------------------------------------------------
      // Set up the addresses
      //------------------------------------------------------------------------
      if( el->IsaPointer() ) {
         fAddress = (char*)addr+el->GetOffset();
         fObject  = *(char**)fAddress;
      } else {
         fAddress = (char*)addr+el->GetOffset();
         fObject  = (char*)addr+el->GetOffset();
      }
   }
}
 TBranchSTL.cxx:1
 TBranchSTL.cxx:2
 TBranchSTL.cxx:3
 TBranchSTL.cxx:4
 TBranchSTL.cxx:5
 TBranchSTL.cxx:6
 TBranchSTL.cxx:7
 TBranchSTL.cxx:8
 TBranchSTL.cxx:9
 TBranchSTL.cxx:10
 TBranchSTL.cxx:11
 TBranchSTL.cxx:12
 TBranchSTL.cxx:13
 TBranchSTL.cxx:14
 TBranchSTL.cxx:15
 TBranchSTL.cxx:16
 TBranchSTL.cxx:17
 TBranchSTL.cxx:18
 TBranchSTL.cxx:19
 TBranchSTL.cxx:20
 TBranchSTL.cxx:21
 TBranchSTL.cxx:22
 TBranchSTL.cxx:23
 TBranchSTL.cxx:24
 TBranchSTL.cxx:25
 TBranchSTL.cxx:26
 TBranchSTL.cxx:27
 TBranchSTL.cxx:28
 TBranchSTL.cxx:29
 TBranchSTL.cxx:30
 TBranchSTL.cxx:31
 TBranchSTL.cxx:32
 TBranchSTL.cxx:33
 TBranchSTL.cxx:34
 TBranchSTL.cxx:35
 TBranchSTL.cxx:36
 TBranchSTL.cxx:37
 TBranchSTL.cxx:38
 TBranchSTL.cxx:39
 TBranchSTL.cxx:40
 TBranchSTL.cxx:41
 TBranchSTL.cxx:42
 TBranchSTL.cxx:43
 TBranchSTL.cxx:44
 TBranchSTL.cxx:45
 TBranchSTL.cxx:46
 TBranchSTL.cxx:47
 TBranchSTL.cxx:48
 TBranchSTL.cxx:49
 TBranchSTL.cxx:50
 TBranchSTL.cxx:51
 TBranchSTL.cxx:52
 TBranchSTL.cxx:53
 TBranchSTL.cxx:54
 TBranchSTL.cxx:55
 TBranchSTL.cxx:56
 TBranchSTL.cxx:57
 TBranchSTL.cxx:58
 TBranchSTL.cxx:59
 TBranchSTL.cxx:60
 TBranchSTL.cxx:61
 TBranchSTL.cxx:62
 TBranchSTL.cxx:63
 TBranchSTL.cxx:64
 TBranchSTL.cxx:65
 TBranchSTL.cxx:66
 TBranchSTL.cxx:67
 TBranchSTL.cxx:68
 TBranchSTL.cxx:69
 TBranchSTL.cxx:70
 TBranchSTL.cxx:71
 TBranchSTL.cxx:72
 TBranchSTL.cxx:73
 TBranchSTL.cxx:74
 TBranchSTL.cxx:75
 TBranchSTL.cxx:76
 TBranchSTL.cxx:77
 TBranchSTL.cxx:78
 TBranchSTL.cxx:79
 TBranchSTL.cxx:80
 TBranchSTL.cxx:81
 TBranchSTL.cxx:82
 TBranchSTL.cxx:83
 TBranchSTL.cxx:84
 TBranchSTL.cxx:85
 TBranchSTL.cxx:86
 TBranchSTL.cxx:87
 TBranchSTL.cxx:88
 TBranchSTL.cxx:89
 TBranchSTL.cxx:90
 TBranchSTL.cxx:91
 TBranchSTL.cxx:92
 TBranchSTL.cxx:93
 TBranchSTL.cxx:94
 TBranchSTL.cxx:95
 TBranchSTL.cxx:96
 TBranchSTL.cxx:97
 TBranchSTL.cxx:98
 TBranchSTL.cxx:99
 TBranchSTL.cxx:100
 TBranchSTL.cxx:101
 TBranchSTL.cxx:102
 TBranchSTL.cxx:103
 TBranchSTL.cxx:104
 TBranchSTL.cxx:105
 TBranchSTL.cxx:106
 TBranchSTL.cxx:107
 TBranchSTL.cxx:108
 TBranchSTL.cxx:109
 TBranchSTL.cxx:110
 TBranchSTL.cxx:111
 TBranchSTL.cxx:112
 TBranchSTL.cxx:113
 TBranchSTL.cxx:114
 TBranchSTL.cxx:115
 TBranchSTL.cxx:116
 TBranchSTL.cxx:117
 TBranchSTL.cxx:118
 TBranchSTL.cxx:119
 TBranchSTL.cxx:120
 TBranchSTL.cxx:121
 TBranchSTL.cxx:122
 TBranchSTL.cxx:123
 TBranchSTL.cxx:124
 TBranchSTL.cxx:125
 TBranchSTL.cxx:126
 TBranchSTL.cxx:127
 TBranchSTL.cxx:128
 TBranchSTL.cxx:129
 TBranchSTL.cxx:130
 TBranchSTL.cxx:131
 TBranchSTL.cxx:132
 TBranchSTL.cxx:133
 TBranchSTL.cxx:134
 TBranchSTL.cxx:135
 TBranchSTL.cxx:136
 TBranchSTL.cxx:137
 TBranchSTL.cxx:138
 TBranchSTL.cxx:139
 TBranchSTL.cxx:140
 TBranchSTL.cxx:141
 TBranchSTL.cxx:142
 TBranchSTL.cxx:143
 TBranchSTL.cxx:144
 TBranchSTL.cxx:145
 TBranchSTL.cxx:146
 TBranchSTL.cxx:147
 TBranchSTL.cxx:148
 TBranchSTL.cxx:149
 TBranchSTL.cxx:150
 TBranchSTL.cxx:151
 TBranchSTL.cxx:152
 TBranchSTL.cxx:153
 TBranchSTL.cxx:154
 TBranchSTL.cxx:155
 TBranchSTL.cxx:156
 TBranchSTL.cxx:157
 TBranchSTL.cxx:158
 TBranchSTL.cxx:159
 TBranchSTL.cxx:160
 TBranchSTL.cxx:161
 TBranchSTL.cxx:162
 TBranchSTL.cxx:163
 TBranchSTL.cxx:164
 TBranchSTL.cxx:165
 TBranchSTL.cxx:166
 TBranchSTL.cxx:167
 TBranchSTL.cxx:168
 TBranchSTL.cxx:169
 TBranchSTL.cxx:170
 TBranchSTL.cxx:171
 TBranchSTL.cxx:172
 TBranchSTL.cxx:173
 TBranchSTL.cxx:174
 TBranchSTL.cxx:175
 TBranchSTL.cxx:176
 TBranchSTL.cxx:177
 TBranchSTL.cxx:178
 TBranchSTL.cxx:179
 TBranchSTL.cxx:180
 TBranchSTL.cxx:181
 TBranchSTL.cxx:182
 TBranchSTL.cxx:183
 TBranchSTL.cxx:184
 TBranchSTL.cxx:185
 TBranchSTL.cxx:186
 TBranchSTL.cxx:187
 TBranchSTL.cxx:188
 TBranchSTL.cxx:189
 TBranchSTL.cxx:190
 TBranchSTL.cxx:191
 TBranchSTL.cxx:192
 TBranchSTL.cxx:193
 TBranchSTL.cxx:194
 TBranchSTL.cxx:195
 TBranchSTL.cxx:196
 TBranchSTL.cxx:197
 TBranchSTL.cxx:198
 TBranchSTL.cxx:199
 TBranchSTL.cxx:200
 TBranchSTL.cxx:201
 TBranchSTL.cxx:202
 TBranchSTL.cxx:203
 TBranchSTL.cxx:204
 TBranchSTL.cxx:205
 TBranchSTL.cxx:206
 TBranchSTL.cxx:207
 TBranchSTL.cxx:208
 TBranchSTL.cxx:209
 TBranchSTL.cxx:210
 TBranchSTL.cxx:211
 TBranchSTL.cxx:212
 TBranchSTL.cxx:213
 TBranchSTL.cxx:214
 TBranchSTL.cxx:215
 TBranchSTL.cxx:216
 TBranchSTL.cxx:217
 TBranchSTL.cxx:218
 TBranchSTL.cxx:219
 TBranchSTL.cxx:220
 TBranchSTL.cxx:221
 TBranchSTL.cxx:222
 TBranchSTL.cxx:223
 TBranchSTL.cxx:224
 TBranchSTL.cxx:225
 TBranchSTL.cxx:226
 TBranchSTL.cxx:227
 TBranchSTL.cxx:228
 TBranchSTL.cxx:229
 TBranchSTL.cxx:230
 TBranchSTL.cxx:231
 TBranchSTL.cxx:232
 TBranchSTL.cxx:233
 TBranchSTL.cxx:234
 TBranchSTL.cxx:235
 TBranchSTL.cxx:236
 TBranchSTL.cxx:237
 TBranchSTL.cxx:238
 TBranchSTL.cxx:239
 TBranchSTL.cxx:240
 TBranchSTL.cxx:241
 TBranchSTL.cxx:242
 TBranchSTL.cxx:243
 TBranchSTL.cxx:244
 TBranchSTL.cxx:245
 TBranchSTL.cxx:246
 TBranchSTL.cxx:247
 TBranchSTL.cxx:248
 TBranchSTL.cxx:249
 TBranchSTL.cxx:250
 TBranchSTL.cxx:251
 TBranchSTL.cxx:252
 TBranchSTL.cxx:253
 TBranchSTL.cxx:254
 TBranchSTL.cxx:255
 TBranchSTL.cxx:256
 TBranchSTL.cxx:257
 TBranchSTL.cxx:258
 TBranchSTL.cxx:259
 TBranchSTL.cxx:260
 TBranchSTL.cxx:261
 TBranchSTL.cxx:262
 TBranchSTL.cxx:263
 TBranchSTL.cxx:264
 TBranchSTL.cxx:265
 TBranchSTL.cxx:266
 TBranchSTL.cxx:267
 TBranchSTL.cxx:268
 TBranchSTL.cxx:269
 TBranchSTL.cxx:270
 TBranchSTL.cxx:271
 TBranchSTL.cxx:272
 TBranchSTL.cxx:273
 TBranchSTL.cxx:274
 TBranchSTL.cxx:275
 TBranchSTL.cxx:276
 TBranchSTL.cxx:277
 TBranchSTL.cxx:278
 TBranchSTL.cxx:279
 TBranchSTL.cxx:280
 TBranchSTL.cxx:281
 TBranchSTL.cxx:282
 TBranchSTL.cxx:283
 TBranchSTL.cxx:284
 TBranchSTL.cxx:285
 TBranchSTL.cxx:286
 TBranchSTL.cxx:287
 TBranchSTL.cxx:288
 TBranchSTL.cxx:289
 TBranchSTL.cxx:290
 TBranchSTL.cxx:291
 TBranchSTL.cxx:292
 TBranchSTL.cxx:293
 TBranchSTL.cxx:294
 TBranchSTL.cxx:295
 TBranchSTL.cxx:296
 TBranchSTL.cxx:297
 TBranchSTL.cxx:298
 TBranchSTL.cxx:299
 TBranchSTL.cxx:300
 TBranchSTL.cxx:301
 TBranchSTL.cxx:302
 TBranchSTL.cxx:303
 TBranchSTL.cxx:304
 TBranchSTL.cxx:305
 TBranchSTL.cxx:306
 TBranchSTL.cxx:307
 TBranchSTL.cxx:308
 TBranchSTL.cxx:309
 TBranchSTL.cxx:310
 TBranchSTL.cxx:311
 TBranchSTL.cxx:312
 TBranchSTL.cxx:313
 TBranchSTL.cxx:314
 TBranchSTL.cxx:315
 TBranchSTL.cxx:316
 TBranchSTL.cxx:317
 TBranchSTL.cxx:318
 TBranchSTL.cxx:319
 TBranchSTL.cxx:320
 TBranchSTL.cxx:321
 TBranchSTL.cxx:322
 TBranchSTL.cxx:323
 TBranchSTL.cxx:324
 TBranchSTL.cxx:325
 TBranchSTL.cxx:326
 TBranchSTL.cxx:327
 TBranchSTL.cxx:328
 TBranchSTL.cxx:329
 TBranchSTL.cxx:330
 TBranchSTL.cxx:331
 TBranchSTL.cxx:332
 TBranchSTL.cxx:333
 TBranchSTL.cxx:334
 TBranchSTL.cxx:335
 TBranchSTL.cxx:336
 TBranchSTL.cxx:337
 TBranchSTL.cxx:338
 TBranchSTL.cxx:339
 TBranchSTL.cxx:340
 TBranchSTL.cxx:341
 TBranchSTL.cxx:342
 TBranchSTL.cxx:343
 TBranchSTL.cxx:344
 TBranchSTL.cxx:345
 TBranchSTL.cxx:346
 TBranchSTL.cxx:347
 TBranchSTL.cxx:348
 TBranchSTL.cxx:349
 TBranchSTL.cxx:350
 TBranchSTL.cxx:351
 TBranchSTL.cxx:352
 TBranchSTL.cxx:353
 TBranchSTL.cxx:354
 TBranchSTL.cxx:355
 TBranchSTL.cxx:356
 TBranchSTL.cxx:357
 TBranchSTL.cxx:358
 TBranchSTL.cxx:359
 TBranchSTL.cxx:360
 TBranchSTL.cxx:361
 TBranchSTL.cxx:362
 TBranchSTL.cxx:363
 TBranchSTL.cxx:364
 TBranchSTL.cxx:365
 TBranchSTL.cxx:366
 TBranchSTL.cxx:367
 TBranchSTL.cxx:368
 TBranchSTL.cxx:369
 TBranchSTL.cxx:370
 TBranchSTL.cxx:371
 TBranchSTL.cxx:372
 TBranchSTL.cxx:373
 TBranchSTL.cxx:374
 TBranchSTL.cxx:375
 TBranchSTL.cxx:376
 TBranchSTL.cxx:377
 TBranchSTL.cxx:378
 TBranchSTL.cxx:379
 TBranchSTL.cxx:380
 TBranchSTL.cxx:381
 TBranchSTL.cxx:382
 TBranchSTL.cxx:383
 TBranchSTL.cxx:384
 TBranchSTL.cxx:385
 TBranchSTL.cxx:386
 TBranchSTL.cxx:387
 TBranchSTL.cxx:388
 TBranchSTL.cxx:389
 TBranchSTL.cxx:390
 TBranchSTL.cxx:391
 TBranchSTL.cxx:392
 TBranchSTL.cxx:393
 TBranchSTL.cxx:394
 TBranchSTL.cxx:395
 TBranchSTL.cxx:396
 TBranchSTL.cxx:397
 TBranchSTL.cxx:398
 TBranchSTL.cxx:399
 TBranchSTL.cxx:400
 TBranchSTL.cxx:401
 TBranchSTL.cxx:402
 TBranchSTL.cxx:403
 TBranchSTL.cxx:404
 TBranchSTL.cxx:405
 TBranchSTL.cxx:406
 TBranchSTL.cxx:407
 TBranchSTL.cxx:408
 TBranchSTL.cxx:409
 TBranchSTL.cxx:410
 TBranchSTL.cxx:411
 TBranchSTL.cxx:412
 TBranchSTL.cxx:413
 TBranchSTL.cxx:414
 TBranchSTL.cxx:415
 TBranchSTL.cxx:416
 TBranchSTL.cxx:417
 TBranchSTL.cxx:418
 TBranchSTL.cxx:419
 TBranchSTL.cxx:420
 TBranchSTL.cxx:421
 TBranchSTL.cxx:422
 TBranchSTL.cxx:423
 TBranchSTL.cxx:424
 TBranchSTL.cxx:425
 TBranchSTL.cxx:426
 TBranchSTL.cxx:427
 TBranchSTL.cxx:428
 TBranchSTL.cxx:429
 TBranchSTL.cxx:430
 TBranchSTL.cxx:431
 TBranchSTL.cxx:432
 TBranchSTL.cxx:433
 TBranchSTL.cxx:434
 TBranchSTL.cxx:435
 TBranchSTL.cxx:436
 TBranchSTL.cxx:437
 TBranchSTL.cxx:438
 TBranchSTL.cxx:439
 TBranchSTL.cxx:440
 TBranchSTL.cxx:441
 TBranchSTL.cxx:442
 TBranchSTL.cxx:443
 TBranchSTL.cxx:444
 TBranchSTL.cxx:445
 TBranchSTL.cxx:446
 TBranchSTL.cxx:447
 TBranchSTL.cxx:448
 TBranchSTL.cxx:449
 TBranchSTL.cxx:450
 TBranchSTL.cxx:451
 TBranchSTL.cxx:452
 TBranchSTL.cxx:453
 TBranchSTL.cxx:454
 TBranchSTL.cxx:455
 TBranchSTL.cxx:456
 TBranchSTL.cxx:457
 TBranchSTL.cxx:458
 TBranchSTL.cxx:459
 TBranchSTL.cxx:460
 TBranchSTL.cxx:461
 TBranchSTL.cxx:462
 TBranchSTL.cxx:463
 TBranchSTL.cxx:464
 TBranchSTL.cxx:465
 TBranchSTL.cxx:466
 TBranchSTL.cxx:467
 TBranchSTL.cxx:468
 TBranchSTL.cxx:469
 TBranchSTL.cxx:470
 TBranchSTL.cxx:471
 TBranchSTL.cxx:472
 TBranchSTL.cxx:473
 TBranchSTL.cxx:474
 TBranchSTL.cxx:475
 TBranchSTL.cxx:476
 TBranchSTL.cxx:477
 TBranchSTL.cxx:478
 TBranchSTL.cxx:479
 TBranchSTL.cxx:480
 TBranchSTL.cxx:481
 TBranchSTL.cxx:482
 TBranchSTL.cxx:483
 TBranchSTL.cxx:484
 TBranchSTL.cxx:485
 TBranchSTL.cxx:486
 TBranchSTL.cxx:487
 TBranchSTL.cxx:488
 TBranchSTL.cxx:489
 TBranchSTL.cxx:490
 TBranchSTL.cxx:491
 TBranchSTL.cxx:492
 TBranchSTL.cxx:493
 TBranchSTL.cxx:494
 TBranchSTL.cxx:495
 TBranchSTL.cxx:496
 TBranchSTL.cxx:497
 TBranchSTL.cxx:498
 TBranchSTL.cxx:499
 TBranchSTL.cxx:500
 TBranchSTL.cxx:501
 TBranchSTL.cxx:502
 TBranchSTL.cxx:503
 TBranchSTL.cxx:504
 TBranchSTL.cxx:505
 TBranchSTL.cxx:506
 TBranchSTL.cxx:507
 TBranchSTL.cxx:508
 TBranchSTL.cxx:509
 TBranchSTL.cxx:510
 TBranchSTL.cxx:511
 TBranchSTL.cxx:512
 TBranchSTL.cxx:513
 TBranchSTL.cxx:514
 TBranchSTL.cxx:515
 TBranchSTL.cxx:516
 TBranchSTL.cxx:517
 TBranchSTL.cxx:518
 TBranchSTL.cxx:519
 TBranchSTL.cxx:520
 TBranchSTL.cxx:521
 TBranchSTL.cxx:522
 TBranchSTL.cxx:523
 TBranchSTL.cxx:524
 TBranchSTL.cxx:525
 TBranchSTL.cxx:526
 TBranchSTL.cxx:527
 TBranchSTL.cxx:528
 TBranchSTL.cxx:529
 TBranchSTL.cxx:530
 TBranchSTL.cxx:531
 TBranchSTL.cxx:532
 TBranchSTL.cxx:533
 TBranchSTL.cxx:534
 TBranchSTL.cxx:535
 TBranchSTL.cxx:536
 TBranchSTL.cxx:537
 TBranchSTL.cxx:538
 TBranchSTL.cxx:539
 TBranchSTL.cxx:540
 TBranchSTL.cxx:541
 TBranchSTL.cxx:542
 TBranchSTL.cxx:543
 TBranchSTL.cxx:544
 TBranchSTL.cxx:545
 TBranchSTL.cxx:546
 TBranchSTL.cxx:547
 TBranchSTL.cxx:548
 TBranchSTL.cxx:549
 TBranchSTL.cxx:550
 TBranchSTL.cxx:551
 TBranchSTL.cxx:552
 TBranchSTL.cxx:553
 TBranchSTL.cxx:554
 TBranchSTL.cxx:555
 TBranchSTL.cxx:556
 TBranchSTL.cxx:557
 TBranchSTL.cxx:558
 TBranchSTL.cxx:559
 TBranchSTL.cxx:560
 TBranchSTL.cxx:561
 TBranchSTL.cxx:562
 TBranchSTL.cxx:563
 TBranchSTL.cxx:564
 TBranchSTL.cxx:565
 TBranchSTL.cxx:566
 TBranchSTL.cxx:567
 TBranchSTL.cxx:568
 TBranchSTL.cxx:569
 TBranchSTL.cxx:570
 TBranchSTL.cxx:571
 TBranchSTL.cxx:572
 TBranchSTL.cxx:573
 TBranchSTL.cxx:574
 TBranchSTL.cxx:575
 TBranchSTL.cxx:576
 TBranchSTL.cxx:577
 TBranchSTL.cxx:578
 TBranchSTL.cxx:579
 TBranchSTL.cxx:580
 TBranchSTL.cxx:581
 TBranchSTL.cxx:582
 TBranchSTL.cxx:583
 TBranchSTL.cxx:584
 TBranchSTL.cxx:585
 TBranchSTL.cxx:586
 TBranchSTL.cxx:587
 TBranchSTL.cxx:588
 TBranchSTL.cxx:589
 TBranchSTL.cxx:590
 TBranchSTL.cxx:591
 TBranchSTL.cxx:592
 TBranchSTL.cxx:593
 TBranchSTL.cxx:594
 TBranchSTL.cxx:595
 TBranchSTL.cxx:596
 TBranchSTL.cxx:597
 TBranchSTL.cxx:598
 TBranchSTL.cxx:599
 TBranchSTL.cxx:600
 TBranchSTL.cxx:601
 TBranchSTL.cxx:602
 TBranchSTL.cxx:603
 TBranchSTL.cxx:604
 TBranchSTL.cxx:605
 TBranchSTL.cxx:606
 TBranchSTL.cxx:607
 TBranchSTL.cxx:608
 TBranchSTL.cxx:609
 TBranchSTL.cxx:610
 TBranchSTL.cxx:611
 TBranchSTL.cxx:612
 TBranchSTL.cxx:613
 TBranchSTL.cxx:614
 TBranchSTL.cxx:615
 TBranchSTL.cxx:616
 TBranchSTL.cxx:617
 TBranchSTL.cxx:618
 TBranchSTL.cxx:619
 TBranchSTL.cxx:620
 TBranchSTL.cxx:621
 TBranchSTL.cxx:622
 TBranchSTL.cxx:623
 TBranchSTL.cxx:624
 TBranchSTL.cxx:625
 TBranchSTL.cxx:626
 TBranchSTL.cxx:627
 TBranchSTL.cxx:628
 TBranchSTL.cxx:629
 TBranchSTL.cxx:630
 TBranchSTL.cxx:631
 TBranchSTL.cxx:632
 TBranchSTL.cxx:633
 TBranchSTL.cxx:634
 TBranchSTL.cxx:635
 TBranchSTL.cxx:636
 TBranchSTL.cxx:637
 TBranchSTL.cxx:638
 TBranchSTL.cxx:639
 TBranchSTL.cxx:640
 TBranchSTL.cxx:641
 TBranchSTL.cxx:642
 TBranchSTL.cxx:643
 TBranchSTL.cxx:644
 TBranchSTL.cxx:645
 TBranchSTL.cxx:646
 TBranchSTL.cxx:647
 TBranchSTL.cxx:648
 TBranchSTL.cxx:649
 TBranchSTL.cxx:650
 TBranchSTL.cxx:651
 TBranchSTL.cxx:652
 TBranchSTL.cxx:653
 TBranchSTL.cxx:654
 TBranchSTL.cxx:655
 TBranchSTL.cxx:656
 TBranchSTL.cxx:657
 TBranchSTL.cxx:658
 TBranchSTL.cxx:659
 TBranchSTL.cxx:660
 TBranchSTL.cxx:661
 TBranchSTL.cxx:662
 TBranchSTL.cxx:663
 TBranchSTL.cxx:664
 TBranchSTL.cxx:665
 TBranchSTL.cxx:666
 TBranchSTL.cxx:667
 TBranchSTL.cxx:668
 TBranchSTL.cxx:669
 TBranchSTL.cxx:670
 TBranchSTL.cxx:671
 TBranchSTL.cxx:672
 TBranchSTL.cxx:673
 TBranchSTL.cxx:674
 TBranchSTL.cxx:675
 TBranchSTL.cxx:676
 TBranchSTL.cxx:677
 TBranchSTL.cxx:678
 TBranchSTL.cxx:679
 TBranchSTL.cxx:680
 TBranchSTL.cxx:681
 TBranchSTL.cxx:682
 TBranchSTL.cxx:683
 TBranchSTL.cxx:684
 TBranchSTL.cxx:685