34 ROOT::Internal::TVirtualCollectionReader::~TVirtualCollectionReader() {}
 
   37    using namespace ROOT::Internal;
 
   40    class TClonesReader: 
public TVirtualCollectionReader {
 
   43       TClonesArray* GetCA(ROOT::Detail::TBranchProxy* proxy) {
 
   45             fReadStatus = TTreeReaderValueBase::kReadError;
 
   46             Error(
"TClonesReader::GetCA()", 
"Read error in TBranchProxy.");
 
   49          fReadStatus = TTreeReaderValueBase::kReadSuccess;
 
   50          return (TClonesArray*) proxy->GetWhere();
 
   52       virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
 
   53          TClonesArray *myClonesArray = GetCA(proxy);
 
   55             return myClonesArray->GetEntries();
 
   59       virtual void* At(ROOT::Detail::TBranchProxy* proxy, 
size_t idx) {
 
   60          TClonesArray *myClonesArray = GetCA(proxy);
 
   62             return myClonesArray->UncheckedAt(idx);
 
   69    class TSTLReader final: 
public TVirtualCollectionReader {
 
   72       TVirtualCollectionProxy* GetCP(ROOT::Detail::TBranchProxy* proxy) {
 
   74             fReadStatus = TTreeReaderValueBase::kReadError;
 
   75             Error(
"TSTLReader::GetCP()", 
"Read error in TBranchProxy.");
 
   78          if (!proxy->GetWhere()) {
 
   79             Error(
"TSTLReader::GetCP()", 
"Logic error, proxy object not set in TBranchProxy.");
 
   82          fReadStatus = TTreeReaderValueBase::kReadSuccess;
 
   83          return (TVirtualCollectionProxy*) proxy->GetCollection();
 
   86       virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
 
   87          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
   88          if (!myCollectionProxy) 
return 0;
 
   89          return myCollectionProxy->Size();
 
   92       virtual void* At(ROOT::Detail::TBranchProxy* proxy, 
size_t idx) {
 
   93          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
   94          if (!myCollectionProxy) 
return 0;
 
   95          if (myCollectionProxy->HasPointers()){
 
   96             return *(
void**)myCollectionProxy->At(idx);
 
   99             return myCollectionProxy->At(idx);
 
  104    class TCollectionLessSTLReader final: 
public TVirtualCollectionReader {
 
  106       TVirtualCollectionProxy *fLocalCollection;
 
  108       TCollectionLessSTLReader(TVirtualCollectionProxy *proxy) : fLocalCollection(proxy) {}
 
  110       TVirtualCollectionProxy* GetCP(ROOT::Detail::TBranchProxy* proxy) {
 
  111          if (!proxy->Read()) {
 
  112             fReadStatus = TTreeReaderValueBase::kReadError;
 
  113             Error(
"TCollectionLessSTLReader::GetCP()", 
"Read error in TBranchProxy.");
 
  116          if (!proxy->GetWhere()) {
 
  117             Error(
"TCollectionLessSTLReader::GetCP()", 
"Logic error, proxy object not set in TBranchProxy.");
 
  120          fReadStatus = TTreeReaderValueBase::kReadSuccess;
 
  121          return fLocalCollection;
 
  124       virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
 
  125          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
  126          if (!myCollectionProxy) 
return 0;
 
  129          myCollectionProxy->PopProxy();
 
  130          myCollectionProxy->PushProxy(proxy->GetWhere());
 
  131          return myCollectionProxy->Size();
 
  134       virtual void* At(ROOT::Detail::TBranchProxy* proxy, 
size_t idx) {
 
  135          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
  136          if (!myCollectionProxy) 
return 0;
 
  140          myCollectionProxy->PopProxy();
 
  141          myCollectionProxy->PushProxy(proxy->GetWhere());
 
  142          if (myCollectionProxy->HasPointers()){
 
  143             return *(
void**)myCollectionProxy->At(idx);
 
  145             return myCollectionProxy->At(idx);
 
  153    class TObjectArrayReader: 
public TVirtualCollectionReader {
 
  155       Int_t fBasicTypeSize;
 
  157       TObjectArrayReader() : fBasicTypeSize(-1) { }
 
  158       ~TObjectArrayReader() {}
 
  159       TVirtualCollectionProxy* GetCP(ROOT::Detail::TBranchProxy* proxy) {
 
  161             fReadStatus = TTreeReaderValueBase::kReadError;
 
  162             Error(
"TObjectArrayReader::GetCP()", 
"Read error in TBranchProxy.");
 
  165          fReadStatus = TTreeReaderValueBase::kReadSuccess;
 
  166          return (TVirtualCollectionProxy*) proxy->GetCollection();
 
  168       virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
 
  169          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
  170          if (!myCollectionProxy) 
return 0;
 
  171          return myCollectionProxy->Size();
 
  173       virtual void* At(ROOT::Detail::TBranchProxy* proxy, 
size_t idx) {
 
  174          if (!proxy->Read()) 
return 0;
 
  177          void *array = (
void*)proxy->GetStart();
 
  179          if (fBasicTypeSize == -1){
 
  180             TClass *myClass = proxy->GetClass();
 
  182                Error(
"TObjectArrayReader::At()", 
"Cannot get class info from branch proxy.");
 
  185             objectSize = myClass->GetClassSize();
 
  188             objectSize = fBasicTypeSize;
 
  190          return (
void*)((Byte_t*)array + (objectSize * idx));
 
  193       void SetBasicTypeSize(Int_t size){
 
  194          fBasicTypeSize = size;
 
  198    template <
class BASE>
 
  199    class TUIntOrIntReader: 
public BASE {
 
  202       std::unique_ptr<TTreeReaderValueBase> fSizeReader;
 
  203       bool fIsUnsigned = 
false;
 
  207       TTreeReaderValue<T>& GetSizeReader() {
 
  208          return *
static_cast<TTreeReaderValue<T>*
>(fSizeReader.get());
 
  212       template <
class... ARGS>
 
  213       TUIntOrIntReader(TTreeReader *treeReader, 
const char *leafName,
 
  215          BASE(std::forward<ARGS>(args)...)
 
  217          if (TLeaf* sizeLeaf = treeReader->GetTree()->FindLeaf(leafName)) {
 
  218             fIsUnsigned = sizeLeaf->IsUnsigned();
 
  220                fSizeReader.reset(
new TTreeReaderValue<UInt_t>(*treeReader, leafName));
 
  222                fSizeReader.reset(
new TTreeReaderValue<Int_t>(*treeReader, leafName));
 
  227       size_t GetSize(ROOT::Detail::TBranchProxy* )
 override {
 
  229             return *GetSizeReader<UInt_t>();
 
  230          return *GetSizeReader<Int_t>();
 
  234    class TArrayParameterSizeReader: 
public TUIntOrIntReader<TObjectArrayReader> {
 
  236       TArrayParameterSizeReader(TTreeReader *treeReader, 
const char *branchName):
 
  237          TUIntOrIntReader<TObjectArrayReader>(treeReader, branchName) {}
 
  241    class TArrayFixedSizeReader : 
public TObjectArrayReader {
 
  246       TArrayFixedSizeReader(Int_t sizeArg) : fSize(sizeArg) {}
 
  248       virtual size_t GetSize(ROOT::Detail::TBranchProxy* ) { 
return fSize; }
 
  251    class TBasicTypeArrayReader final: 
public TVirtualCollectionReader {
 
  253       ~TBasicTypeArrayReader() {}
 
  255       TVirtualCollectionProxy* GetCP (ROOT::Detail::TBranchProxy *proxy) {
 
  257             fReadStatus = TTreeReaderValueBase::kReadError;
 
  258             Error(
"TBasicTypeArrayReader::GetCP()", 
"Read error in TBranchProxy.");
 
  261          fReadStatus = TTreeReaderValueBase::kReadSuccess;
 
  262          return (TVirtualCollectionProxy*) proxy->GetCollection();
 
  265       virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy){
 
  266          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
  267          if (!myCollectionProxy) 
return 0;
 
  268          return myCollectionProxy->Size();
 
  271       virtual void* At(ROOT::Detail::TBranchProxy* proxy, 
size_t idx){
 
  272          TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
 
  273          if (!myCollectionProxy) 
return 0;
 
  274          return (Byte_t*)myCollectionProxy->At(idx) + proxy->GetOffset();
 
  278    class TBasicTypeClonesReader final: 
public TClonesReader {
 
  282       TBasicTypeClonesReader(Int_t offsetArg) : fOffset(offsetArg) {}
 
  284       virtual void* At(ROOT::Detail::TBranchProxy* proxy, 
size_t idx){
 
  285          TClonesArray *myClonesArray = GetCA(proxy);
 
  286          if (!myClonesArray) 
return 0;
 
  287          return (Byte_t*)myClonesArray->At(idx) + fOffset;
 
  291    class TLeafReader : 
public TVirtualCollectionReader {
 
  293       TTreeReaderValueBase *fValueReader;
 
  296       TLeafReader(TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
 
  298       virtual size_t GetSize(ROOT::Detail::TBranchProxy* ){
 
  299          TLeaf *myLeaf = fValueReader->GetLeaf();
 
  300          return myLeaf ? myLeaf->GetLen() : 0; 
 
  303       virtual void* At(ROOT::Detail::TBranchProxy* , 
size_t idx){
 
  305          void *address = fValueReader->GetAddress();
 
  306          if (fElementSize == -1){
 
  307             TLeaf *myLeaf = fValueReader->GetLeaf();
 
  308             if (!myLeaf) 
return 0; 
 
  309             fElementSize = myLeaf->GetLenType();
 
  311          return (Byte_t*)address + (fElementSize * idx);
 
  316          fValueReader->ProxyRead();
 
  320    class TLeafParameterSizeReader: 
public TUIntOrIntReader<TLeafReader> {
 
  322       TLeafParameterSizeReader(TTreeReader *treeReader, 
const char *leafName,
 
  323                                TTreeReaderValueBase *valueReaderArg) :
 
  324          TUIntOrIntReader<TLeafReader>(treeReader, leafName, valueReaderArg) {}
 
  326       size_t GetSize(ROOT::Detail::TBranchProxy* proxy)
 override {
 
  328          return TUIntOrIntReader<TLeafReader>::GetSize(proxy);
 
  335 ClassImp(TTreeReaderArrayBase);
 
  340 void ROOT::Internal::TTreeReaderArrayBase::CreateProxy()
 
  346    fSetupStatus = kSetupInternalError; 
 
  348       Error(
"TTreeReaderArrayBase::CreateProxy()", 
"TTreeReader object not set / available for branch %s!",
 
  350       fSetupStatus = kSetupTreeDestructed;
 
  354       TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
 
  355       const char* brDataType = 
"{UNDETERMINED}";
 
  357          TDictionary* dictUnused = 0;
 
  358          brDataType = GetBranchDataType(br, dictUnused, fDict);
 
  360       Error(
"TTreeReaderArrayBase::CreateProxy()", 
"The template argument type T of %s accessing branch %s (which contains data of type %s) is not known to ROOT. You will need to create a dictionary for it.",
 
  361             GetDerivedTypeName(), fBranchName.Data(), brDataType);
 
  362       fSetupStatus = kSetupMissingDictionary;
 
  371    TDictionary* branchActualType = 0;
 
  372    TBranch* branch = 
nullptr;
 
  373    TLeaf *myLeaf = 
nullptr;
 
  374    if (!GetBranchAndLeaf(branch, myLeaf, branchActualType))
 
  378       Error(
"TTreeReaderArrayBase::CreateProxy()",
 
  379             "No dictionary for branch %s.", fBranchName.Data());
 
  383    TNamedBranchProxy* namedProxy = fTreeReader->FindProxy(fBranchName);
 
  385       if (namedProxy->GetContentDict() == fDict) {
 
  386          fSetupStatus = kSetupMatch;
 
  387          fProxy = namedProxy->GetProxy();
 
  388          SetImpl(branch, myLeaf);
 
  393       if (!namedProxy->GetContentDict()) {
 
  394          namedProxy->SetContentDict(fDict);
 
  395          fProxy = namedProxy->GetProxy();
 
  397             fSetupStatus = kSetupMatch;
 
  399          Error(
"TTreeReaderArrayBase::CreateProxy()",
 
  400                "Type ambiguity (want %s, have %s) for branch %s.",
 
  401                fDict->GetName(), namedProxy->GetContentDict()->GetName(), fBranchName.Data());
 
  407       bool isTopLevel = branch->GetMother() == branch;
 
  409          membername = strrchr(branch->GetName(), 
'.');
 
  410          if (membername.IsNull()) {
 
  411             membername = branch->GetName();
 
  414       auto director = fTreeReader->fDirector;
 
  416       if (branch->GetTree() != fTreeReader->GetTree()->GetTree()) {
 
  420          for(
auto fe : TRangeDynCast<TFriendElement>( fTreeReader->GetTree()->GetTree()->GetListOfFriends())) {
 
  421             if (branch->GetTree() == fe->GetTree()) {
 
  427             Error(
"TTreeReaderArrayBase::CreateProxy()", 
"The branch %s is contained in a Friend TTree that is not directly attached to the main.\n" 
  428                   "This is not yet supported by TTreeReader.",
 
  432          TFriendProxy *feproxy = 
nullptr;
 
  433          if ((
size_t)index < fTreeReader->fFriendProxies.size()) {
 
  434             feproxy = fTreeReader->fFriendProxies.at(index);
 
  437             feproxy = 
new ROOT::Internal::TFriendProxy(director, fTreeReader->GetTree(), index);
 
  438             fTreeReader->fFriendProxies.resize(index+1);
 
  439             fTreeReader->fFriendProxies.at(index) = feproxy;
 
  441          director = feproxy->GetDirector();
 
  443       namedProxy = 
new TNamedBranchProxy(director, branch, fBranchName, membername);
 
  444       fTreeReader->AddProxy(namedProxy);
 
  445       fProxy = namedProxy->GetProxy();
 
  447          fSetupStatus = kSetupMatch;
 
  449          fSetupStatus = kSetupMismatch;
 
  453       TString branchActualTypeName;
 
  454       const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
 
  455       if (nonCollTypeName) {
 
  456          Error(
"TTreeReaderArrayBase::CreateContentProxy()", 
"The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
 
  457                fBranchName.Data(), nonCollTypeName, nonCollTypeName);
 
  458          if (fSetupStatus == kSetupInternalError)
 
  459             fSetupStatus = kSetupNotACollection;
 
  463       if (!branchActualType) {
 
  464          if (branchActualTypeName.IsNull()) {
 
  465             Error(
"TTreeReaderArrayBase::CreateContentProxy()", 
"Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
 
  468             Error(
"TTreeReaderArrayBase::CreateContentProxy()", 
"The branch %s contains data of type %s, which does not have a dictionary.",
 
  469                   fBranchName.Data(), branchActualTypeName.Data());
 
  470             if (fSetupStatus == kSetupInternalError)
 
  471                fSetupStatus = kSetupMissingDictionary;
 
  477       if (fDict != branchActualType) {
 
  478          Error(
"TTreeReaderArrayBase::CreateContentProxy()", 
"The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
 
  479                fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
 
  480          if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
 
  481             fSetupStatus = kSetupMismatch;
 
  484          if (!namedProxy->GetContentDict()) {
 
  485             namedProxy->SetContentDict(fDict);
 
  493    SetImpl(branch, myLeaf);
 
  499 bool ROOT::Internal::TTreeReaderArrayBase::GetBranchAndLeaf(TBranch* &branch, TLeaf* &myLeaf,
 
  500                                                             TDictionary* &branchActualType) {
 
  502    branch = fTreeReader->GetTree()->GetBranch(fBranchName);
 
  506    if (!fBranchName.Contains(
".")) {
 
  507       Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()", 
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
 
  508       fSetupStatus = kSetupMissingBranch;
 
  513    TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
 
  514    TString leafName (fBranchName(leafNameExpression));
 
  515    TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
 
  516    branch = fTreeReader->GetTree()->GetBranch(branchName);
 
  518       Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()", 
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
 
  519       fSetupStatus = kSetupMissingBranch;
 
  524    myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
 
  526       Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()", 
"The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
 
  527       fSetupStatus = kSetupMissingBranch;
 
  532    TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
 
  534       Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()", 
"Failed to get the dictionary for %s.", myLeaf->GetTypeName());
 
  535       fSetupStatus = kSetupMissingDictionary;
 
  540    if (tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
 
  542       branchActualType = fDict;
 
  544       fBranchName = branchName;
 
  545       fLeafName = leafName(1, leafName.Length());
 
  546       fHaveLeaf = (fLeafName.Length() > 0);
 
  547       fSetupStatus = kSetupMatchLeaf;
 
  550       Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()", 
"Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
 
  552       fSetupStatus = kSetupMismatch;
 
  564 void ROOT::Internal::TTreeReaderArrayBase::SetImpl(TBranch* branch, TLeaf* myLeaf)
 
  577       if (!myLeaf->GetLeafCount()){
 
  578          fImpl = std::make_unique<TLeafReader>(
this);
 
  581          TString leafFullName = myLeaf->GetBranch()->GetName();
 
  583          leafFullName += myLeaf->GetLeafCount()->GetName();
 
  584          fImpl = std::make_unique<TLeafParameterSizeReader>(fTreeReader, leafFullName.Data(), 
this);
 
  586       fSetupStatus = kSetupMatchLeaf;
 
  588    else if (branch->IsA() == TBranchElement::Class()) {
 
  589       TBranchElement* branchElement = ((TBranchElement*)branch);
 
  591       TStreamerInfo *streamerInfo = branchElement->GetInfo();
 
  592       Int_t 
id = branchElement->GetID();
 
  596          TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(
id);
 
  600          if (fSetupStatus == kSetupInternalError)
 
  601             fSetupStatus = kSetupMatch;
 
  602          if (element->IsA() == TStreamerSTL::Class()){
 
  603             fImpl = std::make_unique<TSTLReader>();
 
  605          else if (element->IsA() == TStreamerObject::Class()){
 
  608             if (element->GetClass() == TClonesArray::Class()){
 
  609                fImpl = std::make_unique<TClonesReader>();
 
  611             else if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
 
  612                fImpl = std::make_unique<TBasicTypeArrayReader>();
 
  614             else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
 
  616                fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
 
  619                fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
 
  622          else if (element->IsA() == TStreamerLoop::Class()) {
 
  623             fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
 
  625          else if (element->IsA() == TStreamerBasicType::Class()){
 
  626             if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
 
  627                fImpl = std::make_unique<TBasicTypeArrayReader>();
 
  629             else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
 
  630                fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
 
  633                fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
 
  634                ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
 
  637          else if (element->IsA() == TStreamerBasicPointer::Class()) {
 
  638             fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
 
  639             ((TArrayParameterSizeReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
 
  641          else if (element->IsA() == TStreamerBase::Class()){
 
  642             fImpl = std::make_unique<TClonesReader>();
 
  644             Error(
"TTreeReaderArrayBase::SetImpl()",
 
  645                   "Cannot read branch %s: unhandled streamer element type %s",
 
  646                   fBranchName.Data(), element->IsA()->GetName());
 
  647             fSetupStatus = kSetupInternalError;
 
  651          if (branchElement->GetClass()->GetCollectionProxy()){
 
  652             fImpl = std::make_unique<TCollectionLessSTLReader>(branchElement->GetClass()->GetCollectionProxy());
 
  655    } 
else if (branch->IsA() == TBranch::Class()) {
 
  656       auto topLeaf = branch->GetLeaf(branch->GetName());
 
  658          Error(
"TTreeReaderArrayBase::SetImpl", 
"Failed to get the top leaf from the branch");
 
  659          fSetupStatus = kSetupMissingBranch;
 
  663       auto sizeLeaf = topLeaf->GetLeafCount();
 
  664       if (fSetupStatus == kSetupInternalError)
 
  665          fSetupStatus = kSetupMatch;
 
  667          fImpl = std::make_unique<TArrayFixedSizeReader>(topLeaf->GetLenStatic());
 
  670          fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, sizeLeaf->GetName());
 
  672       ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
 
  673    } 
else if (branch->IsA() == TBranchClones::Class()) {
 
  674       Error(
"TTreeReaderArrayBase::SetImpl", 
"Support for branches of type TBranchClones not implemented");
 
  675       fSetupStatus = kSetupInternalError;
 
  676    } 
else if (branch->IsA() == TBranchObject::Class()) {
 
  677       Error(
"TTreeReaderArrayBase::SetImpl", 
"Support for branches of type TBranchObject not implemented");
 
  678       fSetupStatus = kSetupInternalError;
 
  679    } 
else if (branch->IsA() == TBranchSTL::Class()) {
 
  680       Error(
"TTreeReaderArrayBase::SetImpl", 
"Support for branches of type TBranchSTL not implemented");
 
  681       fImpl = std::make_unique<TSTLReader>();
 
  682       fSetupStatus = kSetupInternalError;
 
  683    } 
else if (branch->IsA() == TBranchRef::Class()) {
 
  684       Error(
"TTreeReaderArrayBase::SetImpl", 
"Support for branches of type TBranchRef not implemented");
 
  685       fSetupStatus = kSetupInternalError;
 
  699 const char* ROOT::Internal::TTreeReaderArrayBase::GetBranchContentDataType(TBranch* branch,
 
  700                                                                  TString& contentTypeName,
 
  704    contentTypeName = 
"";
 
  705    if (branch->IsA() == TBranchElement::Class()) {
 
  706       TBranchElement* brElement = (TBranchElement*)branch;
 
  707       if (brElement->GetType() == 4
 
  708           || brElement->GetType() == 3) {
 
  709          TVirtualCollectionProxy* collProxy = brElement->GetCollectionProxy();
 
  711             TClass *myClass = collProxy->GetValueClass();
 
  713                Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"Could not get value class.");
 
  716             dict = TDictionary::GetDictionary(myClass->GetName());
 
  717             if (!dict) dict = TDataType::GetDataType(collProxy->GetType());
 
  722             if (brElement->GetType() == 3) {
 
  723                contentTypeName = brElement->GetClonesName();
 
  724                dict = TDictionary::GetDictionary(brElement->GetClonesName());
 
  728             TClassEdit::TSplitType splitType(brElement->GetClassName());
 
  729             int isSTLCont = splitType.IsSTLCont();
 
  731                Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"Cannot determine STL collection type of %s stored in branch %s", brElement->GetClassName(), branch->GetName());
 
  732                return brElement->GetClassName();
 
  734             bool isMap = isSTLCont == ROOT::kSTLmap
 
  735                || isSTLCont == ROOT::kSTLmultimap;
 
  736             if (isMap) contentTypeName = 
"std::pair< ";
 
  737             contentTypeName += splitType.fElements[1];
 
  739                contentTypeName += splitType.fElements[2];
 
  740                contentTypeName += 
" >";
 
  745       } 
else if (brElement->GetType() == 31
 
  746                  || brElement->GetType() == 41) {
 
  749          EDataType dtData = kOther_t;
 
  750          int ExpectedTypeRet = brElement->GetExpectedType(clData, dtData);
 
  751          if (ExpectedTypeRet == 0) {
 
  754                dict = TDataType::GetDataType(dtData);
 
  757                Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
 
  758                      branch->GetName(), (int)dtData);
 
  759                contentTypeName = TDataType::GetTypeName(dtData);
 
  763          } 
else if (ExpectedTypeRet == 1) {
 
  764             int brID = brElement->GetID();
 
  767                Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
 
  768                      branch->GetName(), brElement->GetClassName());
 
  769                contentTypeName = brElement->GetClassName();
 
  774             TStreamerElement* element =
 
  775                (TStreamerElement*) brElement->GetInfo()->GetElement(brID);
 
  776             contentTypeName = element->GetTypeName();
 
  782          return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
 
  784       else if (brElement->GetType() == TBranchElement::kLeafNode){
 
  785          TStreamerInfo *streamerInfo = brElement->GetInfo();
 
  786          Int_t 
id = brElement->GetID();
 
  789             TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(
id);
 
  791             if (element->IsA() == TStreamerSTL::Class()){
 
  792                TClass *myClass = brElement->GetCurrentClass();
 
  794                   Error(
"TTreeReaderArrayBase::GetBranchDataType()", 
"Could not get class from branch element.");
 
  797                TVirtualCollectionProxy *myCollectionProxy = myClass->GetCollectionProxy();
 
  798                if (!myCollectionProxy){
 
  799                   Error(
"TTreeReaderArrayBase::GetBranchDataType()", 
"Could not get collection proxy from STL class");
 
  803                dict = myCollectionProxy->GetValueClass();
 
  805                if (!dict) dict = TDataType::GetDataType(myCollectionProxy->GetType());
 
  807                   Error(
"TTreeReaderArrayBase::GetBranchDataType()", 
"Could not get valueClass from collectionProxy.");
 
  810                contentTypeName = dict->GetName();
 
  813             else if (element->IsA() == TStreamerObject::Class() && !strcmp(element->GetTypeName(), 
"TClonesArray")){
 
  814                if (!fProxy->Setup() || !fProxy->Read()){
 
  815                   Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"Failed to get type from proxy, unable to check type");
 
  816                   contentTypeName = 
"UNKNOWN";
 
  818                   return contentTypeName;
 
  820                TClonesArray *myArray = (TClonesArray*)fProxy->GetWhere();
 
  821                dict = myArray->GetClass();
 
  822                contentTypeName = dict->GetName();
 
  826                dict = brElement->GetCurrentClass();
 
  828                   TDictionary *myDataType = TDictionary::GetDictionary(brElement->GetTypeName());
 
  829                   dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
 
  831                contentTypeName = brElement->GetTypeName();
 
  835          if (brElement->GetCurrentClass() == TClonesArray::Class()){
 
  836             contentTypeName = 
"TClonesArray";
 
  837             Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"Not able to check type correctness, ignoring check");
 
  839             fSetupStatus = kSetupNoCheck;
 
  841          else if (!dict && (branch->GetSplitLevel() == 0 || brElement->GetClass()->GetCollectionProxy())){
 
  843             dict = brElement->GetClass()->GetCollectionProxy()->GetValueClass();
 
  845             if (!dict) dict = TDataType::GetDataType(brElement->GetClass()->GetCollectionProxy()->GetType());
 
  846             if (dict) contentTypeName = dict->GetName();
 
  850             dict = brElement->GetClass();
 
  851             contentTypeName = dict->GetName();
 
  858    } 
else if (branch->IsA() == TBranch::Class()
 
  859               || branch->IsA() == TBranchObject::Class()
 
  860               || branch->IsA() == TBranchSTL::Class()) {
 
  861       const char* dataTypeName = branch->GetClassName();
 
  862       if ((!dataTypeName || !dataTypeName[0])
 
  863           && branch->IsA() == TBranch::Class()) {
 
  864          auto myLeaf = branch->GetLeaf(branch->GetName());
 
  866             auto myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
 
  867             if (myDataType && myDataType->IsA() == TDataType::Class()){
 
  868                auto typeEnumConstant = EDataType(((TDataType*)myDataType)->GetType());
 
  871                if (typeEnumConstant == kDouble32_t) typeEnumConstant = kDouble_t;
 
  872                else if (typeEnumConstant == kFloat16_t) typeEnumConstant = kFloat_t;
 
  873                dict = TDataType::GetDataType(typeEnumConstant);
 
  874                contentTypeName = myLeaf->GetTypeName();
 
  880          Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"The branch %s was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderArray:", branch->GetName());
 
  881          TIter iLeaves(branch->GetListOfLeaves());
 
  883          while ((leaf = (TLeaf*) iLeaves())) {
 
  884             Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"   %s.%s", branch->GetName(), leaf->GetName());
 
  888       if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
 
  889       if (branch->IsA() == TBranchSTL::Class()){
 
  890          Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"Not able to check type correctness, ignoring check");
 
  892          fSetupStatus = kSetupNoCheck;
 
  896    } 
else if (branch->IsA() == TBranchClones::Class()) {
 
  897       dict = TClonesArray::Class();
 
  898       return "TClonesArray";
 
  899    } 
else if (branch->IsA() == TBranchRef::Class()) {
 
  901       Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
 
  904       Error(
"TTreeReaderArrayBase::GetBranchContentDataType()", 
"The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());