Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTreeReaderArray.cxx
Go to the documentation of this file.
1// @(#)root/treeplayer:$Id$
2// Author: Axel Naumann, 2011-09-28
3
4/*************************************************************************
5 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TTreeReaderArray.h"
13
14#include "TBranchClones.h"
15#include "TBranchElement.h"
16#include "TBranchRef.h"
17#include "TBranchSTL.h"
18#include "TBranchObject.h"
20#include "TClassEdit.h"
21#include "TEnum.h"
22#include "TFriendElement.h"
23#include "TFriendProxy.h"
24#include "TLeaf.h"
25#include "TList.h"
26#include "TROOT.h"
27#include "TStreamerInfo.h"
28#include "TStreamerElement.h"
29#include "TTreeReader.h"
30#include "TGenCollectionProxy.h"
31#include "TRegexp.h"
32
33#include <memory>
34
35// pin vtable
37
38namespace {
39 using namespace ROOT::Internal;
40
41 // Reader interface for clones arrays
42 class TClonesReader: public TVirtualCollectionReader {
43 public:
44 ~TClonesReader() override {}
46 if (!proxy->Read()){
48 Error("TClonesReader::GetCA()", "Read error in TBranchProxy.");
49 return nullptr;
50 }
52 return (TClonesArray*) proxy->GetWhere();
53 }
54 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
55 TClonesArray *myClonesArray = GetCA(proxy);
56 if (myClonesArray){
57 return myClonesArray->GetEntries();
58 }
59 else return 0;
60 }
61 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
62 TClonesArray *myClonesArray = GetCA(proxy);
63 if (myClonesArray){
64 return myClonesArray->UncheckedAt(idx);
65 }
66 else return nullptr;
67 }
68 };
69
70 // Reader interface for STL
71 class TSTLReader final: public TVirtualCollectionReader {
72 public:
73 ~TSTLReader() override {}
75 if (!proxy->Read()) {
77 Error("TSTLReader::GetCP()", "Read error in TBranchProxy.");
78 return nullptr;
79 }
80 if (!proxy->GetWhere()) {
81 Error("TSTLReader::GetCP()", "Logic error, proxy object not set in TBranchProxy.");
82 return nullptr;
83 }
85 return (TVirtualCollectionProxy*) proxy->GetCollection();
86 }
87
88 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
89 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
90 if (!myCollectionProxy) return 0;
91 return myCollectionProxy->Size();
92 }
93
94 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
95 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
96 if (!myCollectionProxy) return nullptr;
97 if (myCollectionProxy->HasPointers()){
98 return *(void**)myCollectionProxy->At(idx);
99 }
100 else {
101 return myCollectionProxy->At(idx);
102 }
103 }
104 };
105
106 class TCollectionLessSTLReader final: public TVirtualCollectionReader {
107 private:
108 TVirtualCollectionProxy *fLocalCollection;
109 public:
110 TCollectionLessSTLReader(TVirtualCollectionProxy *proxy) : fLocalCollection(proxy) {}
111
113 if (!proxy->Read()) {
115 Error("TCollectionLessSTLReader::GetCP()", "Read error in TBranchProxy.");
116 return nullptr;
117 }
118 if (!proxy->GetWhere()) {
119 Error("TCollectionLessSTLReader::GetCP()", "Logic error, proxy object not set in TBranchProxy.");
120 return nullptr;
121 }
123 return fLocalCollection;
124 }
125
126 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
127 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
128 if (!myCollectionProxy) return 0;
129 /// In the case of std::vector<bool> `PushProxy` also creates a temporary bool variable the address of which
130 /// is returned from these calls.
131 myCollectionProxy->PopProxy();
132 myCollectionProxy->PushProxy(proxy->GetWhere());
133 return myCollectionProxy->Size();
134 }
135
136 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
137 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
138 if (!myCollectionProxy) return nullptr;
139 // Here we do not use a RAII but we empty the proxy to then fill it.
140 // This is done because we are returning a pointer and we need to keep
141 // alive the memory it points to.
142 myCollectionProxy->PopProxy();
143 myCollectionProxy->PushProxy(proxy->GetWhere());
144 if (myCollectionProxy->HasPointers()){
145 return *(void**)myCollectionProxy->At(idx);
146 } else {
147 return myCollectionProxy->At(idx);
148 }
149 }
150 };
151
152
153 // Reader interface for leaf list
154 // SEE TTreeProxyGenerator.cxx:1319: '//We have a top level raw type'
155 class TObjectArrayReader: public TVirtualCollectionReader {
156 private:
157 Int_t fBasicTypeSize;
158 public:
159 TObjectArrayReader() : fBasicTypeSize(-1) { }
160 ~TObjectArrayReader() override {}
162 if (!proxy->Read()){
164 Error("TObjectArrayReader::GetCP()", "Read error in TBranchProxy.");
165 return nullptr;
166 }
168 return (TVirtualCollectionProxy*) proxy->GetCollection();
169 }
170 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
171 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
172 if (!myCollectionProxy) return 0;
173 return myCollectionProxy->Size();
174 }
175 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
176 if (!proxy->Read()) return nullptr;
177
178 Int_t objectSize;
179 void *array = (void*)proxy->GetStart();
180
181 if (fBasicTypeSize == -1){
182 TClass *myClass = proxy->GetClass();
183 if (!myClass){
184 Error("TObjectArrayReader::At()", "Cannot get class info from branch proxy.");
185 return nullptr;
186 }
187 objectSize = myClass->GetClassSize();
188 }
189 else {
190 objectSize = fBasicTypeSize;
191 }
192 return (void*)((Byte_t*)array + (objectSize * idx));
193 }
194
195 void SetBasicTypeSize(Int_t size){
196 fBasicTypeSize = size;
197 }
198 };
199
200 template <class BASE>
201 class TDynamicArrayReader : public BASE {
202
203 // TVirtualSizeReaderImpl and TSizeReaderImpl type-erase the reading of the size leaf.
204 class TVirtualSizeReaderImpl {
205 public:
206 virtual ~TVirtualSizeReaderImpl() = default;
207 virtual size_t GetSize() = 0;
208 };
209
210 template <typename T>
211 class TSizeReaderImpl final : public TVirtualSizeReaderImpl {
212 TTreeReaderValue<T> fSizeReader;
213
214 public:
215 TSizeReaderImpl(TTreeReader &r, const char *leafName) : fSizeReader(r, leafName) {}
216 size_t GetSize() final { return *fSizeReader; }
217 };
218
219 std::unique_ptr<TVirtualSizeReaderImpl> fSizeReader;
220
221 public:
222 template <class... ARGS>
223 TDynamicArrayReader(TTreeReader *treeReader, const char *leafName, ARGS &&...args)
224 : BASE(std::forward<ARGS>(args)...)
225 {
226 std::string foundLeafName = leafName;
227 TLeaf* sizeLeaf = treeReader->GetTree()->FindLeaf(foundLeafName.c_str());
228
229 if (!sizeLeaf) {
230 // leafName might be "top.currentParent.N". But "N" might really be "top.N"!
231 // Strip parents until we find the leaf.
232 std::string leafNameNoParent = leafName;
233 std::string parent;
234 auto posLastDot = leafNameNoParent.rfind('.');
235 if (posLastDot != leafNameNoParent.npos) {
236 parent = leafNameNoParent.substr(0, posLastDot);
237 leafNameNoParent.erase(0, posLastDot + 1);
238 }
239
240 do {
241 if (!sizeLeaf && !parent.empty()) {
242 auto posLastDotParent = parent.rfind('.');
243 if (posLastDotParent != parent.npos)
244 parent = parent.substr(0, posLastDot);
245 else
246 parent.clear();
247 }
248
249 foundLeafName = parent;
250 if (!parent.empty())
251 foundLeafName += ".";
252 foundLeafName += leafNameNoParent;
253 sizeLeaf = treeReader->GetTree()->FindLeaf(foundLeafName.c_str());
254 } while (!sizeLeaf && !parent.empty());
255 }
256
257 if (!sizeLeaf) {
258 Error("TDynamicArrayReader ", "Cannot find leaf count for %s or any parent branch!", leafName);
259 return;
260 }
261
262 const std::string leafType = sizeLeaf->GetTypeName();
263 if (leafType == "Int_t") {
264 fSizeReader.reset(new TSizeReaderImpl<Int_t>(*treeReader, foundLeafName.c_str()));
265 } else if (leafType == "UInt_t") {
266 fSizeReader.reset(new TSizeReaderImpl<UInt_t>(*treeReader, foundLeafName.c_str()));
267 } else if (leafType == "Short_t") {
268 fSizeReader.reset(new TSizeReaderImpl<Short_t>(*treeReader, foundLeafName.c_str()));
269 } else if (leafType == "UShort_t") {
270 fSizeReader.reset(new TSizeReaderImpl<UShort_t>(*treeReader, foundLeafName.c_str()));
271 } else if (leafType == "Long_t") {
272 fSizeReader.reset(new TSizeReaderImpl<Long_t>(*treeReader, foundLeafName.c_str()));
273 } else if (leafType == "ULong_t") {
274 fSizeReader.reset(new TSizeReaderImpl<ULong_t>(*treeReader, foundLeafName.c_str()));
275 } else if (leafType == "Long64_t") {
276 fSizeReader.reset(new TSizeReaderImpl<Long64_t>(*treeReader, foundLeafName.c_str()));
277 } else if (leafType == "ULong64_t") {
278 fSizeReader.reset(new TSizeReaderImpl<ULong64_t>(*treeReader, foundLeafName.c_str()));
279 } else {
280 Error("TDynamicArrayReader ",
281 "Unsupported size type for leaf %s. Supported types are int, short int, long int, long long int and "
282 "their unsigned counterparts.",
283 leafName);
284 }
285 }
286
287 size_t GetSize(ROOT::Detail::TBranchProxy * /*proxy*/) override { return fSizeReader->GetSize(); }
288 };
289
290 class TArrayParameterSizeReader : public TDynamicArrayReader<TObjectArrayReader> {
291 public:
292 TArrayParameterSizeReader(TTreeReader *treeReader, const char *branchName)
293 : TDynamicArrayReader<TObjectArrayReader>(treeReader, branchName)
294 {
295 }
296 };
297
298 // Reader interface for fixed size arrays
299 class TArrayFixedSizeReader : public TObjectArrayReader {
300 private:
301 Int_t fSize;
302
303 public:
304 TArrayFixedSizeReader(Int_t sizeArg) : fSize(sizeArg) {}
305
306 size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/) override { return fSize; }
307 };
308
309 class TBasicTypeArrayReader final: public TVirtualCollectionReader {
310 public:
311 ~TBasicTypeArrayReader() override {}
312
314 if (!proxy->Read()){
316 Error("TBasicTypeArrayReader::GetCP()", "Read error in TBranchProxy.");
317 return nullptr;
318 }
320 return (TVirtualCollectionProxy*) proxy->GetCollection();
321 }
322
323 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override{
324 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
325 if (!myCollectionProxy) return 0;
326 return myCollectionProxy->Size();
327 }
328
329 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override{
330 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
331 if (!myCollectionProxy) return nullptr;
332 return (Byte_t*)myCollectionProxy->At(idx) + proxy->GetOffset();
333 }
334 };
335
336 class TBasicTypeClonesReader final: public TClonesReader {
337 private:
338 Int_t fOffset;
339 public:
340 TBasicTypeClonesReader(Int_t offsetArg) : fOffset(offsetArg) {}
341
342 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override{
343 TClonesArray *myClonesArray = GetCA(proxy);
344 if (!myClonesArray) return nullptr;
345 return (Byte_t*)myClonesArray->At(idx) + fOffset;
346 }
347 };
348
349 class TLeafReader : public TVirtualCollectionReader {
350 private:
351 TTreeReaderValueBase *fValueReader;
352 Int_t fElementSize;
353 public:
354 TLeafReader(TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
355
356 size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/) override{
357 TLeaf *myLeaf = fValueReader->GetLeaf();
358 return myLeaf ? myLeaf->GetLen() : 0; // Error will be printed by GetLeaf
359 }
360
361 void* At(ROOT::Detail::TBranchProxy* /*proxy*/, size_t idx) override{
362 ProxyRead();
363 void *address = fValueReader->GetAddress();
364 if (fElementSize == -1){
365 TLeaf *myLeaf = fValueReader->GetLeaf();
366 if (!myLeaf) return nullptr; // Error will be printed by GetLeaf
367 fElementSize = myLeaf->GetLenType();
368 }
369 return (Byte_t*)address + (fElementSize * idx);
370 }
371
372 protected:
373 void ProxyRead(){
374 fValueReader->ProxyRead();
375 }
376 };
377
378 class TLeafParameterSizeReader : public TDynamicArrayReader<TLeafReader> {
379 public:
380 TLeafParameterSizeReader(TTreeReader *treeReader, const char *leafName, TTreeReaderValueBase *valueReaderArg)
381 : TDynamicArrayReader<TLeafReader>(treeReader, leafName, valueReaderArg)
382 {
383 }
384
385 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
386 ProxyRead();
387 return TDynamicArrayReader<TLeafReader>::GetSize(proxy);
388 }
389 };
390}
391
392
393
395
396////////////////////////////////////////////////////////////////////////////////
397/// Create the proxy object for our branch.
398
400{
401 if (fProxy) {
402 return;
403 }
404
405 fSetupStatus = kSetupInternalError; // Fallback; set to something concrete below.
406 if (!fTreeReader) {
407 Error("TTreeReaderArrayBase::CreateProxy()", "TTreeReader object not set / available for branch %s!",
408 fBranchName.Data());
409 fSetupStatus = kSetupTreeDestructed;
410 return;
411 }
412 if (!fDict) {
413 TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
414 const char* brDataType = "{UNDETERMINED}";
415 if (br) {
416 TDictionary* dictUnused = nullptr;
417 brDataType = GetBranchDataType(br, dictUnused, fDict);
418 }
419 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.",
420 GetDerivedTypeName(), fBranchName.Data(), brDataType);
421 fSetupStatus = kSetupMissingDictionary;
422 return;
423 }
424
425 // Access a branch's collection content (not the collection itself)
426 // through a proxy.
427 // Search for the branchname, determine what it contains, and wire the
428 // TBranchProxy representing it to us so we can access its data.
429
430 TDictionary* branchActualType = nullptr;
431 TBranch* branch = nullptr;
432 TLeaf *myLeaf = nullptr;
433 if (!GetBranchAndLeaf(branch, myLeaf, branchActualType))
434 return;
435
436 if (!fDict) {
437 Error("TTreeReaderArrayBase::CreateProxy()",
438 "No dictionary for branch %s.", fBranchName.Data());
439 return;
440 }
441
442 TNamedBranchProxy* namedProxy = fTreeReader->FindProxy(fBranchName);
443 if (namedProxy) {
444 if (namedProxy->GetContentDict() == fDict) {
445 fSetupStatus = kSetupMatch;
446 fProxy = namedProxy->GetProxy();
447 SetImpl(branch, myLeaf);
448 return;
449 }
450
451 // Update named proxy's dictionary
452 if (!namedProxy->GetContentDict()) {
453 namedProxy->SetContentDict(fDict);
454 fProxy = namedProxy->GetProxy();
455 if (fProxy)
456 fSetupStatus = kSetupMatch;
457 } else {
458 Error("TTreeReaderArrayBase::CreateProxy()",
459 "Type ambiguity (want %s, have %s) for branch %s.",
460 fDict->GetName(), namedProxy->GetContentDict()->GetName(), fBranchName.Data());
461 }
462 }
463 else {
464 TString membername;
465
466 bool isTopLevel = branch->GetMother() == branch;
467 if (!isTopLevel) {
468 membername = strrchr(branch->GetName(), '.');
469 if (membername.IsNull()) {
470 membername = branch->GetName();
471 }
472 }
473 auto director = fTreeReader->fDirector;
474 // Determine if the branch is actually in a Friend TTree and if so which.
475 if (branch->GetTree() != fTreeReader->GetTree()->GetTree()) {
476 // It is in a friend, let's find the 'index' in the list of friend ...
477 int index = -1;
478 int current = 0;
479 for(auto fe : TRangeDynCast<TFriendElement>( fTreeReader->GetTree()->GetTree()->GetListOfFriends())) {
480 if (branch->GetTree() == fe->GetTree()) {
481 index = current;
482 }
483 ++current;
484 }
485 if (index == -1) {
486 Error("TTreeReaderArrayBase::CreateProxy()", "The branch %s is contained in a Friend TTree that is not directly attached to the main.\n"
487 "This is not yet supported by TTreeReader.",
488 fBranchName.Data());
489 return;
490 }
491 TFriendProxy *feproxy = nullptr;
492 if ((size_t)index < fTreeReader->fFriendProxies.size()) {
493 feproxy = fTreeReader->fFriendProxies.at(index);
494 }
495 if (!feproxy) {
496 feproxy = new ROOT::Internal::TFriendProxy(director, fTreeReader->GetTree(), index);
497 fTreeReader->fFriendProxies.resize(index+1);
498 fTreeReader->fFriendProxies.at(index) = feproxy;
499 }
500 director = feproxy->GetDirector();
501 }
502 namedProxy = new TNamedBranchProxy(director, branch, fBranchName, membername);
503 fTreeReader->AddProxy(namedProxy);
504 fProxy = namedProxy->GetProxy();
505 if (fProxy)
506 fSetupStatus = kSetupMatch;
507 else
508 fSetupStatus = kSetupMismatch;
509 }
510
511 if (!myLeaf){
512 TString branchActualTypeName;
513 const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
514 if (nonCollTypeName) {
515 Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
516 fBranchName.Data(), nonCollTypeName, nonCollTypeName);
517 if (fSetupStatus == kSetupInternalError)
518 fSetupStatus = kSetupNotACollection;
519 fProxy = nullptr;
520 return;
521 }
522 if (!branchActualType) {
523 if (branchActualTypeName.IsNull()) {
524 Error("TTreeReaderArrayBase::CreateContentProxy()", "Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
525 fBranchName.Data());
526 } else {
527 Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
528 fBranchName.Data(), branchActualTypeName.Data());
529 if (fSetupStatus == kSetupInternalError)
530 fSetupStatus = kSetupMissingDictionary;
531 }
532 fProxy = nullptr;
533 return;
534 }
535
536 auto matchingDataType = [](TDictionary *left, TDictionary *right) -> bool {
537 if (left == right)
538 return true;
539 if (!left || !right)
540 return false;
541 auto left_datatype = dynamic_cast<TDataType *>(left);
542 auto right_datatype = dynamic_cast<TDataType *>(right);
543 auto left_enum = dynamic_cast<TEnum*>(left);
544 auto right_enum = dynamic_cast<TEnum*>(right);
545
546 if ((left_datatype && left_datatype->GetType() == kInt_t && right_enum)
547 || (right_datatype && right_datatype->GetType() == kInt_t && left_enum))
548 return true;
549 if (!left_datatype || !right_datatype)
550 return false;
551 auto l = left_datatype->GetType();
552 auto r = right_datatype->GetType();
553 if ( l > 0 && l == r)
554 return true;
555 else
556 return ( (l == kDouble32_t && r == kDouble_t)
557 || (l == kDouble_t && r == kDouble32_t)
558 || (l == kFloat16_t && r == kFloat_t)
559 || (l == kFloat_t && r == kFloat16_t));
560 };
561
562 if (! matchingDataType(fDict, branchActualType)) {
563 Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
564 fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
565 if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
566 fSetupStatus = kSetupMismatch;
567
568 // Update named proxy's dictionary
569 if (!namedProxy->GetContentDict()) {
570 namedProxy->SetContentDict(fDict);
571 }
572
573 // fProxy = 0;
574 // return;
575 }
576 }
577
578 SetImpl(branch, myLeaf);
579}
580
581////////////////////////////////////////////////////////////////////////////////
582/// Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
583
585 TDictionary* &branchActualType) {
586 myLeaf = nullptr;
587 branch = fTreeReader->GetTree()->GetBranch(fBranchName);
588 if (branch)
589 return true;
590
591 if (!fBranchName.Contains(".")) {
592 Error("TTreeReaderArrayBase::GetBranchAndLeaf()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
593 fSetupStatus = kSetupMissingBranch;
594 fProxy = nullptr;
595 return false;
596 }
597
598 TRegexp leafNameExpression ("\\.[a-zA-Z0-9_]+$");
599 TString leafName (fBranchName(leafNameExpression));
600 TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
601 branch = fTreeReader->GetTree()->GetBranch(branchName);
602 if (!branch){
603 Error("TTreeReaderArrayBase::GetBranchAndLeaf()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
604 fSetupStatus = kSetupMissingBranch;
605 fProxy = nullptr;
606 return false;
607 }
608
609 myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
610 if (!myLeaf){
611 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());
612 fSetupStatus = kSetupMissingBranch;
613 fProxy = nullptr;
614 return false;
615 }
616
618 if (!tempDict){
619 Error("TTreeReaderArrayBase::GetBranchAndLeaf()", "Failed to get the dictionary for %s.", myLeaf->GetTypeName());
620 fSetupStatus = kSetupMissingDictionary;
621 fProxy = nullptr;
622 return false;
623 }
624
625 if (tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
626 //fLeafOffset = myLeaf->GetOffset() / 4;
627 branchActualType = fDict;
628 fLeaf = myLeaf;
629 fBranchName = branchName;
630 fLeafName = leafName(1, leafName.Length());
631 fHaveLeaf = (fLeafName.Length() > 0);
632 fSetupStatus = kSetupMatchLeaf;
633 }
634 else {
635 Error("TTreeReaderArrayBase::GetBranchAndLeaf()", "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
636 fProxy = nullptr;
637 fSetupStatus = kSetupMismatch;
638 return false;
639 }
640 return true;
641}
642
643
644
645
646////////////////////////////////////////////////////////////////////////////////
647/// Create the TVirtualCollectionReader object for our branch.
648
650{
651 if (fImpl)
652 return;
653
654 // Access a branch's collection content (not the collection itself)
655 // through a proxy.
656 // Search for the branchname, determine what it contains, and wire the
657 // TBranchProxy representing it to us so we can access its data.
658 // A proxy for branch must not have been created before (i.e. check
659 // fProxies before calling this function!)
660
661 if (myLeaf){
662 if (!myLeaf->GetLeafCount()){
663 fImpl = std::make_unique<TLeafReader>(this);
664 }
665 else {
666 TString leafFullName = myLeaf->GetBranch()->GetName();
667 leafFullName += ".";
668 leafFullName += myLeaf->GetLeafCount()->GetName();
669 fImpl = std::make_unique<TLeafParameterSizeReader>(fTreeReader, leafFullName.Data(), this);
670 }
671 fSetupStatus = kSetupMatchLeaf;
672 }
673 else if (branch->IsA() == TBranchElement::Class()) {
674 TBranchElement* branchElement = ((TBranchElement*)branch);
675
676 TStreamerInfo *streamerInfo = branchElement->GetInfo();
677 Int_t id = branchElement->GetID();
678
679 if (id >= 0){ // Not root node?
680 // Int_t offset = streamerInfo->GetOffsets()[id];
681 TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
682 // bool isPointer = element->IsaPointer();
683 // TClass *classPointer = element->GetClassPointer();
684
685 if (fSetupStatus == kSetupInternalError)
686 fSetupStatus = kSetupMatch;
687 if (element->IsA() == TStreamerSTL::Class()) {
688 if (branchElement->GetType() == 31) {
689 Error("TTreeReaderArrayBase::SetImpl",
690 "STL Collection nested in a TClonesArray not yet supported");
691 fSetupStatus = kSetupInternalError;
692 return;
693 }
694 fImpl = std::make_unique<TSTLReader>();
695 }
696 else if (element->IsA() == TStreamerObject::Class()){
697 //fImpl = new TObjectArrayReader(); // BArray[12]
698
699 if (element->GetClass() == TClonesArray::Class()){
700 fImpl = std::make_unique<TClonesReader>();
701 }
702 else if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
703 fImpl = std::make_unique<TBasicTypeArrayReader>();
704 }
705 else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
706 // TBasicTypeClonesReader should work for object
707 fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
708 }
709 else {
710 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
711 }
712 }
713 else if (element->IsA() == TStreamerLoop::Class()) {
714 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
715 }
716 else if (element->IsA() == TStreamerBasicType::Class()){
717 if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
718 fImpl = std::make_unique<TBasicTypeArrayReader>();
719 }
720 else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
721 fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
722 }
723 else if (fDict->IsA() == TEnum::Class()) {
724 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
725 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(sizeof(Int_t));
726 } else {
727 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
728 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
729 }
730 }
731 else if (element->IsA() == TStreamerBasicPointer::Class()) {
732 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
733 ((TArrayParameterSizeReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
734 }
735 else if (element->IsA() == TStreamerBase::Class()){
736 fImpl = std::make_unique<TClonesReader>();
737 } else {
738 Error("TTreeReaderArrayBase::SetImpl()",
739 "Cannot read branch %s: unhandled streamer element type %s",
740 fBranchName.Data(), element->IsA()->GetName());
741 fSetupStatus = kSetupInternalError;
742 }
743 }
744 else { // We are at root node?
745 if (branchElement->GetClass()->GetCollectionProxy()){
746 fImpl = std::make_unique<TCollectionLessSTLReader>(branchElement->GetClass()->GetCollectionProxy());
747 }
748 }
749 } else if (branch->IsA() == TBranch::Class()) {
750 auto topLeaf = branch->GetLeaf(branch->GetName());
751 if (!topLeaf) {
752 Error("TTreeReaderArrayBase::SetImpl", "Failed to get the top leaf from the branch");
753 fSetupStatus = kSetupMissingBranch;
754 return;
755 }
756 // We could have used GetLeafCounter, but it does not work well with Double32_t and Float16_t: ROOT-10149
757 auto sizeLeaf = topLeaf->GetLeafCount();
758 if (fSetupStatus == kSetupInternalError)
759 fSetupStatus = kSetupMatch;
760 if (!sizeLeaf) {
761 fImpl = std::make_unique<TArrayFixedSizeReader>(topLeaf->GetLenStatic());
762 }
763 else {
764 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, sizeLeaf->GetName());
765 }
766 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
767 } else if (branch->IsA() == TBranchClones::Class()) {
768 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchClones not implemented");
769 fSetupStatus = kSetupInternalError;
770 } else if (branch->IsA() == TBranchObject::Class()) {
771 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchObject not implemented");
772 fSetupStatus = kSetupInternalError;
773 } else if (branch->IsA() == TBranchSTL::Class()) {
774 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchSTL not implemented");
775 fImpl = std::make_unique<TSTLReader>();
776 fSetupStatus = kSetupInternalError;
777 } else if (branch->IsA() == TBranchRef::Class()) {
778 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchRef not implemented");
779 fSetupStatus = kSetupInternalError;
780 }
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Access a branch's collection content (not the collection itself)
785/// through a proxy.
786/// Retrieve the type of data contained in the collection stored by branch;
787/// put its dictionary into dict, If there is no dictionary, put its type
788/// name into contentTypeName.
789/// The contentTypeName is set to NULL if the branch does not
790/// contain a collection; in that case, the type of the branch is returned.
791/// In all other cases, NULL is returned.
792
794 TString& contentTypeName,
795 TDictionary* &dict)
796{
797 dict = nullptr;
798 contentTypeName = "";
799 if (branch->IsA() == TBranchElement::Class()) {
800 TBranchElement* brElement = (TBranchElement*)branch;
801 if (brElement->GetType() == 4
802 || brElement->GetType() == 3) {
803 TVirtualCollectionProxy* collProxy = brElement->GetCollectionProxy();
804 if (collProxy) {
805 TClass *myClass = collProxy->GetValueClass();
806 if (!myClass){
807 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Could not get value class.");
808 return nullptr;
809 }
810 dict = TDictionary::GetDictionary(myClass->GetName());
811 if (!dict) dict = TDataType::GetDataType(collProxy->GetType());
812 }
813 if (!dict) {
814 // We don't know the dictionary, thus we need the content's type name.
815 // Determine it.
816 if (brElement->GetType() == 3) {
817 contentTypeName = brElement->GetClonesName();
818 dict = TDictionary::GetDictionary(brElement->GetClonesName());
819 return nullptr;
820 }
821 // STL:
822 TClassEdit::TSplitType splitType(brElement->GetClassName());
823 int isSTLCont = splitType.IsSTLCont();
824 if (!isSTLCont) {
825 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Cannot determine STL collection type of %s stored in branch %s", brElement->GetClassName(), branch->GetName());
826 return brElement->GetClassName();
827 }
828 bool isMap = isSTLCont == ROOT::kSTLmap
829 || isSTLCont == ROOT::kSTLmultimap;
830 if (isMap) contentTypeName = "std::pair< ";
831 contentTypeName += splitType.fElements[1];
832 if (isMap) {
833 contentTypeName += splitType.fElements[2];
834 contentTypeName += " >";
835 }
836 return nullptr;
837 }
838 return nullptr;
839 } else if (brElement->GetType() == 31
840 || brElement->GetType() == 41) {
841 // it's a member, extract from GetClass()'s streamer info
842 TClass* clData = nullptr;
843 EDataType dtData = kOther_t;
844 int ExpectedTypeRet = brElement->GetExpectedType(clData, dtData);
845 if (ExpectedTypeRet == 0) {
846 dict = clData;
847 if (!dict) {
848 if (dtData == kFloat16_t) {
849 dtData = kFloat_t;
850 }
851 if (dtData == kDouble32_t) {
852 dtData = kDouble_t;
853 }
854 dict = TDataType::GetDataType(dtData);
855 }
856 if (!dict) {
857 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
858 branch->GetName(), (int)dtData);
859 contentTypeName = TDataType::GetTypeName(dtData);
860 return nullptr;
861 }
862 return nullptr;
863 } else if (ExpectedTypeRet == 1) {
864 int brID = brElement->GetID();
865 if (brID == -1) {
866 // top
867 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
868 branch->GetName(), brElement->GetClassName());
869 contentTypeName = brElement->GetClassName();
870 return nullptr;
871 }
872 // Either the data type name doesn't have an EDataType entry
873 // or the streamer info doesn't have a TClass* attached.
874 TStreamerElement* element =
875 (TStreamerElement*) brElement->GetInfo()->GetElement(brID);
876 contentTypeName = element->GetTypeName();
877 return nullptr;
878 }
879 /* else (ExpectedTypeRet == 2)*/
880 // The streamer info entry cannot be found.
881 // TBranchElement::GetExpectedType() has already complained.
882 return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
883 }
884 else if (brElement->GetType() == TBranchElement::kLeafNode){
885 TStreamerInfo *streamerInfo = brElement->GetInfo();
886 Int_t id = brElement->GetID();
887
888 if (id >= 0){
889 TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
890
891 if (element->IsA() == TStreamerSTL::Class()){
892 TClass *myClass = brElement->GetCurrentClass();
893 if (!myClass){
894 Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get class from branch element.");
895 return nullptr;
896 }
897 TVirtualCollectionProxy *myCollectionProxy = myClass->GetCollectionProxy();
898 if (!myCollectionProxy){
899 Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get collection proxy from STL class");
900 return nullptr;
901 }
902 // Try getting the contained class
903 dict = myCollectionProxy->GetValueClass();
904 // If it fails, try to get the contained type as a primitive type
905 if (!dict) dict = TDataType::GetDataType(myCollectionProxy->GetType());
906 if (!dict){
907 Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get valueClass from collectionProxy.");
908 return nullptr;
909 }
910 contentTypeName = dict->GetName();
911 return nullptr;
912 }
913 else if (element->IsA() == TStreamerObject::Class() && !strcmp(element->GetTypeName(), "TClonesArray")){
914 if (!fProxy->Setup() || !fProxy->Read()){
915 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Failed to get type from proxy, unable to check type");
916 contentTypeName = "UNKNOWN";
917 dict = nullptr;
918 return contentTypeName;
919 }
920 TClonesArray *myArray = (TClonesArray*)fProxy->GetWhere();
921 dict = myArray->GetClass();
922 contentTypeName = dict->GetName();
923 return nullptr;
924 }
925 else {
926 dict = brElement->GetCurrentClass();
927 if (!dict) {
928 TDictionary *myDataType = TDictionary::GetDictionary(brElement->GetTypeName());
929 dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
930 }
931 contentTypeName = brElement->GetTypeName();
932 return nullptr;
933 }
934 }
935 if (brElement->GetCurrentClass() == TClonesArray::Class()){
936 contentTypeName = "TClonesArray";
937 Warning("TTreeReaderArrayBase::GetBranchContentDataType()", "Not able to check type correctness, ignoring check");
938 dict = fDict;
939 fSetupStatus = kSetupNoCheck;
940 }
941 else if (!dict && (branch->GetSplitLevel() == 0 || brElement->GetClass()->GetCollectionProxy())){
942 // Try getting the contained class
943 dict = brElement->GetClass()->GetCollectionProxy()->GetValueClass();
944 // If it fails, try to get the contained type as a primitive type
945 if (!dict) dict = TDataType::GetDataType(brElement->GetClass()->GetCollectionProxy()->GetType());
946 if (dict) contentTypeName = dict->GetName();
947 return nullptr;
948 }
949 else if (!dict){
950 dict = brElement->GetClass();
951 contentTypeName = dict->GetName();
952 return nullptr;
953 }
954
955 return nullptr;
956 }
957 return nullptr;
958 } else if (branch->IsA() == TBranch::Class()
959 || branch->IsA() == TBranchObject::Class()
960 || branch->IsA() == TBranchSTL::Class()) {
961 const char* dataTypeName = branch->GetClassName();
962 if ((!dataTypeName || !dataTypeName[0])
963 && branch->IsA() == TBranch::Class()) {
964 auto myLeaf = branch->GetLeaf(branch->GetName());
965 if (myLeaf){
966 auto myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
967 if (myDataType && myDataType->IsA() == TDataType::Class()){
968 auto typeEnumConstant = EDataType(((TDataType*)myDataType)->GetType());
969 // We need to consider Double32_t and Float16_t as dounle and float respectively
970 // since this is the type the user uses to instantiate the TTreeReaderArray template.
971 if (typeEnumConstant == kDouble32_t) typeEnumConstant = kDouble_t;
972 else if (typeEnumConstant == kFloat16_t) typeEnumConstant = kFloat_t;
973 dict = TDataType::GetDataType(typeEnumConstant);
974 contentTypeName = myLeaf->GetTypeName();
975 return nullptr;
976 }
977 }
978
979 // leaflist. Can't represent.
980 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());
981 TIter iLeaves(branch->GetListOfLeaves());
982 TLeaf* leaf = nullptr;
983 while ((leaf = (TLeaf*) iLeaves())) {
984 Error("TTreeReaderArrayBase::GetBranchContentDataType()", " %s.%s", branch->GetName(), leaf->GetName());
985 }
986 return nullptr;
987 }
988 if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
989 if (branch->IsA() == TBranchSTL::Class()){
990 Warning("TTreeReaderArrayBase::GetBranchContentDataType()", "Not able to check type correctness, ignoring check");
991 dict = fDict;
992 fSetupStatus = kSetupNoCheck;
993 return nullptr;
994 }
995 return dataTypeName;
996 } else if (branch->IsA() == TBranchClones::Class()) {
997 dict = TClonesArray::Class();
998 return "TClonesArray";
999 } else if (branch->IsA() == TBranchRef::Class()) {
1000 // Can't represent.
1001 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
1002 return nullptr;
1003 } else {
1004 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
1005 return nullptr;
1006 }
1007
1008 return nullptr;
1009}
dim_t fSize
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned char Byte_t
Definition RtypesCore.h:64
#define ClassImp(name)
Definition Rtypes.h:377
EDataType
Definition TDataType.h:28
@ kFloat_t
Definition TDataType.h:31
@ kInt_t
Definition TDataType.h:30
@ kDouble32_t
Definition TDataType.h:31
@ kDouble_t
Definition TDataType.h:31
@ kFloat16_t
Definition TDataType.h:33
@ kOther_t
Definition TDataType.h:32
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Base class for all the proxy object.
virtual void * GetStart(UInt_t=0)
TVirtualCollectionProxy * GetCollection()
TBranchProxyDirector * GetDirector()
const Detail::TBranchProxy * GetProxy() const
TDictionary * GetContentDict() const
void SetContentDict(TDictionary *dict)
Base class of TTreeReaderArray.
void CreateProxy() override
Create the proxy object for our branch.
bool GetBranchAndLeaf(TBranch *&branch, TLeaf *&myLeaf, TDictionary *&branchActualType)
Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
void SetImpl(TBranch *branch, TLeaf *myLeaf)
Create the TVirtualCollectionReader object for our branch.
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict)
Access a branch's collection content (not the collection itself) through a proxy.
Base class of TTreeReaderValue.
void * GetAddress()
Returns the memory address of the object being read.
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
static TClass * Class()
A Branch for the case of an object.
TBranchElement * GetBranchCount() const
static TClass * Class()
Int_t GetID() const
const char * GetClassName() const override
Return the name of the user class whose content is stored in this branch, if any.
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
TVirtualCollectionProxy * GetCollectionProxy()
Return the collection proxy describing the branch content, if any.
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
virtual const char * GetTypeName() const
Return type name of element in the branch.
virtual const char * GetClonesName() const
virtual TClass * GetClass() const
Int_t GetType() const
Int_t GetExpectedType(TClass *&clptr, EDataType &type) override
Fill expectedClass and expectedType with information on the data type of the object/values contained ...
static TClass * Class()
static TClass * Class()
static TClass * Class()
A TTree is a list of TBranches.
Definition TBranch.h:93
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition TBranch.cxx:2055
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
Definition TBranch.cxx:1324
TTree * GetTree() const
Definition TBranch.h:252
static TClass * Class()
Int_t GetSplitLevel() const
Definition TBranch.h:250
TClass * IsA() const override
Definition TBranch.h:295
TObjArray * GetListOfLeaves()
Definition TBranch.h:247
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition TBranch.cxx:2127
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2897
Int_t GetClassSize() const
Definition TClass.h:425
An array of clone (identical) objects.
TClass * GetClass() const
static TClass * Class()
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
static TClass * Class()
TString GetTypeName()
Get basic type of typedef, e,g.: "class TDirectory*" -> "TDirectory".
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
This class defines an abstract interface that must be implemented by all classes that contain diction...
TClass * IsA() const override
static TDictionary * GetDictionary(const char *name)
Retrieve the type (class, fundamental type, typedef etc) named "name".
The TEnum class implements the enum type.
Definition TEnum.h:33
static TClass * Class()
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
virtual Int_t GetLenType() const
Definition TLeaf.h:133
virtual const char * GetTypeName() const
Definition TLeaf.h:139
virtual Int_t GetLen() const
Return the number of effective elements of this leaf, for the current entry.
Definition TLeaf.cxx:404
virtual TLeaf * GetLeafCount() const
If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has vari...
Definition TLeaf.h:121
TBranch * GetBranch() const
Definition TLeaf.h:116
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
Regular expression class.
Definition TRegexp.h:31
static TClass * Class()
static TClass * Class()
static TClass * Class()
Int_t GetArrayLength() const
const char * GetTypeName() const
TClass * GetClass() const
TClass * IsA() const override
Int_t GetOffset() const
Describes a persistent version of a class.
TStreamerElement * GetElement(Int_t id) const override
TObjArray * GetElements() const override
static TClass * Class()
static TClass * Class()
static TClass * Class()
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
const char * Data() const
Definition TString.h:376
Bool_t IsNull() const
Definition TString.h:414
An interface for reading values stored in ROOT columnar datasets.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:44
TTree * GetTree() const
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5294
virtual TTree * GetTree() const
Definition TTree.h:517
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition TTree.cxx:4916
Defines a common interface to inspect/change the contents of an object that represents a collection.
virtual void PushProxy(void *objectstart)=0
Set the address of the container being proxied and keep track of the previous one.
virtual EDataType GetType() const =0
If the value type is a fundamental data type, return its type (see enumeration EDataType).
virtual void PopProxy()=0
Reset the address of the container being proxied to the previous container.
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
virtual void * At(UInt_t idx)=0
Return the address of the value at index idx
virtual UInt_t Size() const =0
Return the current number of elements in the container.
virtual Bool_t HasPointers() const =0
Return true if the content is of type 'pointer to'.
@ kSTLmap
Definition ESTLType.h:33
@ kSTLmultimap
Definition ESTLType.h:34
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
int IsSTLCont(int testAlloc=0) const
type : type name: vector<list<classA,allocator>,allocator> testAlloc: if true, we test allocator,...
std::vector< std::string > fElements
Definition TClassEdit.h:141
TLine l
Definition textangle.C:4
#define ARGS(alist)
Definition gifencode.c:10