Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TBranchProxy.h
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Philippe Canal 01/06/2004
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, 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 #ifndef ROOT_TBranchProxy
13 #define ROOT_TBranchProxy
14 
15 #include "TBranchProxyDirector.h"
16 #include "TTree.h"
17 #include "TBranch.h"
18 #include "TLeaf.h"
19 #include "TClonesArray.h"
20 #include "TString.h"
21 #include "Riostream.h"
22 #include "TError.h"
24 #include "TNotifyLink.h"
25 
26 #include <list>
27 #include <algorithm>
28 
29 class TBranch;
30 class TStreamerElement;
31 
32 // Note we could protect the arrays more by introducing a class TArrayWrapper<class T> which somehow knows
33 // its internal dimensions and check for them ...
34 // template <class T> TArrayWrapper {
35 // public:
36 // TArrayWrapper(void *where, int dim1);
37 // const T operator[](int i) {
38 // if (i>=dim1) return 0;
39 // return where[i];
40 // };
41 // };
42 // 2D array would actually be a wrapper of a wrapper i.e. has a method TArrayWrapper<T> operator[](int i);
43 
44 namespace ROOT {
45 namespace Internal {
46  //_______________________________________________
47  // String builder to be used in the constructors.
48  class TBranchProxyHelper {
49  public:
50  TString fName;
51  TBranchProxyHelper(const char *left,const char *right = 0) :
52  fName() {
53  if (left) {
54  fName = left;
55  if (left[0]&&right && fName[fName.Length()-1]!='.') fName += ".";
56  }
57  if (right) {
58  fName += right;
59  }
60  }
61  operator const char*() { return fName.Data(); };
62  };
63 
64  class TTreeReaderValueBase;
65 } // namespace Internal
66 
67 
68 namespace Detail {
69  class TBranchProxy {
70  protected:
71  Internal::TBranchProxyDirector *fDirector; // contain pointer to TTree and entry to be read
72 
73  Bool_t fInitialized : 1;
74  const Bool_t fIsMember : 1; // true if we proxy an unsplit data member
75  Bool_t fIsClone : 1; // true if we proxy the inside of a TClonesArray
76  Bool_t fIsaPointer : 1; // true if we proxy a data member of pointer type
77  Bool_t fHasLeafCount : 1;// true if we proxy a variable size leaf of a leaflist
78 
79  const TString fBranchName; // name of the branch to read
80  TBranchProxy *fParent; // Proxy to a parent object
81 
82  const TString fDataMember; // name of the (eventual) data member being proxied
83 
84 
85  TString fClassName; // class name of the object pointed to by the branch
86  TClass *fClass; // class name of the object pointed to by the branch
87  TStreamerElement *fElement;
88  Int_t fMemberOffset;
89  Int_t fOffset; // Offset inside the object
90  Int_t fArrayLength; // Number of element if the data is an array
91 
92  TBranch *fBranch; // branch to read
93  union {
94  TBranch *fBranchCount; // eventual auxiliary branch (for example holding the size)
95  TLeaf *fLeafCount; // eventual auxiliary leaf (for example holding the size)
96  };
97 
98  TNotifyLink<TBranchProxy> fNotify; // Callback object used by the TChain to update this proxy
99 
100  Long64_t fRead; // Last entry read
101 
102  void *fWhere; // memory location of the data
103  TVirtualCollectionProxy *fCollection; // Handle to the collection containing the data chunk.
104 
105  public:
106  virtual void Print();
107 
108  TBranchProxy();
109  TBranchProxy(Internal::TBranchProxyDirector* boss, const char* top, const char* name = 0);
110  TBranchProxy(Internal::TBranchProxyDirector* boss, const char *top, const char *name, const char *membername);
111  TBranchProxy(Internal::TBranchProxyDirector* boss, TBranchProxy *parent, const char* membername, const char* top = 0, const char* name = 0);
112  TBranchProxy(Internal::TBranchProxyDirector* boss, TBranch* branch, const char* membername);
113  TBranchProxy(Internal::TBranchProxyDirector* boss, const char* branchname, TBranch* branch, const char* membername);
114  virtual ~TBranchProxy();
115 
116  TBranchProxy* GetProxy() { return this; }
117  const char* GetBranchName() const { return fBranchName; }
118 
119  void Reset();
120 
121  Bool_t Notify() {
122  fRead = -1;
123  return Setup();
124  }
125 
126  Bool_t Setup();
127 
128  Bool_t IsInitialized() {
129  return fInitialized;
130  // return fLastTree && fCurrentTreeNumber == fDirector->GetTree()->GetTreeNumber() && fLastTree == fDirector->GetTree();
131  }
132 
133  Bool_t IsaPointer() const {
134  return fIsaPointer;
135  }
136 
137  Bool_t Read() {
138  if (R__unlikely(fDirector==0)) return false;
139 
140  auto treeEntry = fDirector->GetReadEntry();
141  if (treeEntry != fRead) {
142  if (!IsInitialized()) {
143  if (!Setup()) {
144  ::Error("TBranchProxy::Read","%s",Form("Unable to initialize %s\n",fBranchName.Data()));
145  return kFALSE;
146  }
147  }
148  Bool_t result = kTRUE;
149  if (fParent) {
150  result = fParent->Read();
151  } else {
152  if (fBranchCount) {
153  result &= (-1 != fBranchCount->GetEntry(treeEntry));
154  }
155  result &= (-1 != fBranch->GetEntry(treeEntry));
156  }
157  fRead = treeEntry;
158  if (R__unlikely(fCollection)) {
159  fCollection->PopProxy(); // works even if no proxy env object was set.
160  if (IsaPointer()) {
161  fCollection->PushProxy( *(void**)fWhere );
162  } else {
163  fCollection->PushProxy( fWhere );
164  }
165  }
166  return result;
167  } else {
168  return IsInitialized();
169  }
170  }
171 
172 private:
173  friend class ROOT::Internal::TTreeReaderValueBase;
174 
175  enum class EReadType {
176  kDefault,
177  kNoDirector,
178  kReadParentNoCollection,
179  kReadParentCollectionNoPointer,
180  kReadParentCollectionPointer,
181  kReadNoParentNoBranchCountCollectionPointer,
182  kReadNoParentNoBranchCountCollectionNoPointer,
183  kReadNoParentNoBranchCountNoCollection,
184  kReadNoParentBranchCountCollectionPointer,
185  kReadNoParentBranchCountCollectionNoPointer,
186  kReadNoParentBranchCountNoCollection
187  };
188 
189  EReadType GetReadType() {
190  if (fParent) {
191  if (!fCollection) {
192  return EReadType::kReadParentNoCollection;
193  } else {
194  if (IsaPointer()) {
195  return EReadType::kReadParentCollectionPointer;
196  } else {
197  return EReadType::kReadParentCollectionNoPointer;
198  }
199  }
200  } else {
201  if (fBranchCount) {
202  if (fCollection) {
203  if (IsaPointer()) {
204  return EReadType::kReadNoParentBranchCountCollectionPointer;
205  } else {
206  return EReadType::kReadNoParentBranchCountCollectionNoPointer;
207  }
208  } else {
209  return EReadType::kReadNoParentBranchCountNoCollection;
210  }
211 
212  } else {
213  if (fCollection) {
214  if (IsaPointer()) {
215  return EReadType::kReadNoParentNoBranchCountCollectionPointer;
216  } else {
217  return EReadType::kReadNoParentNoBranchCountCollectionNoPointer;
218  }
219  } else {
220  return EReadType::kReadNoParentNoBranchCountNoCollection;
221  }
222  }
223  }
224  return EReadType::kDefault;
225  }
226 
227  Bool_t ReadNoDirector() {
228  return false;
229  }
230 
231  Bool_t ReadParentNoCollection() {
232  auto treeEntry = fDirector->GetReadEntry();
233  if (treeEntry != fRead) {
234  const Bool_t result = fParent->Read();
235  fRead = treeEntry;
236  return result;
237  } else {
238  return IsInitialized();
239  }
240  }
241 
242  Bool_t ReadParentCollectionNoPointer() {
243  auto treeEntry = fDirector->GetReadEntry();
244  if (treeEntry != fRead) {
245  const Bool_t result = fParent->Read();
246  fRead = treeEntry;
247  fCollection->PopProxy(); // works even if no proxy env object was set.
248  fCollection->PushProxy( fWhere );
249  return result;
250  } else {
251  return IsInitialized();
252  }
253  }
254 
255  Bool_t ReadParentCollectionPointer() {
256  auto treeEntry = fDirector->GetReadEntry();
257  if (treeEntry != fRead) {
258  const Bool_t result = fParent->Read();
259  fRead = treeEntry;
260  fCollection->PopProxy(); // works even if no proxy env object was set.
261  fCollection->PushProxy( *(void**)fWhere );
262  return result;
263  } else {
264  return IsInitialized();
265  }
266  }
267 
268  Bool_t ReadNoParentNoBranchCountCollectionPointer() {
269  auto treeEntry = fDirector->GetReadEntry();
270  if (treeEntry != fRead) {
271  Bool_t result = (-1 != fBranch->GetEntry(treeEntry));
272  fRead = treeEntry;
273  fCollection->PopProxy(); // works even if no proxy env object was set.
274  fCollection->PushProxy( *(void**)fWhere );
275  return result;
276  } else {
277  return IsInitialized();
278  }
279  }
280 
281  Bool_t ReadNoParentNoBranchCountCollectionNoPointer() {
282  auto treeEntry = fDirector->GetReadEntry();
283  if (treeEntry != fRead) {
284  Bool_t result = (-1 != fBranch->GetEntry(treeEntry));
285  fRead = treeEntry;
286  fCollection->PopProxy(); // works even if no proxy env object was set.
287  fCollection->PushProxy( fWhere );
288  return result;
289  } else {
290  return IsInitialized();
291  }
292  }
293 
294  Bool_t ReadNoParentNoBranchCountNoCollection() {
295  auto treeEntry = fDirector->GetReadEntry();
296  if (treeEntry != fRead) {
297  Bool_t result = (-1 != fBranch->GetEntry(treeEntry));
298  fRead = treeEntry;
299  return result;
300  } else {
301  return IsInitialized();
302  }
303  }
304 
305  Bool_t ReadNoParentBranchCountCollectionPointer() {
306  auto treeEntry = fDirector->GetReadEntry();
307  if (treeEntry != fRead) {
308  Bool_t result = (-1 != fBranchCount->GetEntry(treeEntry));
309  result &= (-1 != fBranch->GetEntry(treeEntry));
310  fRead = treeEntry;
311  fCollection->PopProxy(); // works even if no proxy env object was set.
312  fCollection->PushProxy( *(void**)fWhere );
313  return result;
314  } else {
315  return IsInitialized();
316  }
317  }
318 
319  Bool_t ReadNoParentBranchCountCollectionNoPointer() {
320  auto treeEntry = fDirector->GetReadEntry();
321  if (treeEntry != fRead) {
322  Bool_t result = (-1 != fBranchCount->GetEntry(treeEntry));
323  result &= (-1 != fBranch->GetEntry(treeEntry));
324  fRead = treeEntry;
325  fCollection->PopProxy(); // works even if no proxy env object was set.
326  fCollection->PushProxy( fWhere );
327  return result;
328  } else {
329  return IsInitialized();
330  }
331  }
332 
333  Bool_t ReadNoParentBranchCountNoCollection() {
334  auto treeEntry = fDirector->GetReadEntry();
335  if (treeEntry != fRead) {
336  Bool_t result = (-1 != fBranchCount->GetEntry(treeEntry));
337  result &= (-1 != fBranch->GetEntry(treeEntry));
338  fRead = treeEntry;
339  return result;
340  } else {
341  return IsInitialized();
342  }
343  }
344 
345 public:
346 
347  Bool_t ReadEntries() {
348  if (R__unlikely(fDirector==0)) return false;
349 
350  auto treeEntry = fDirector->GetReadEntry();
351  if (treeEntry != fRead) {
352  if (!IsInitialized()) {
353  if (!Setup()) {
354  ::Error("TBranchProxy::ReadEntries","%s",Form("Unable to initialize %s\n",fBranchName.Data()));
355  return false;
356  }
357  }
358  if (fParent) fParent->ReadEntries();
359  else {
360  if (fBranchCount) {
361  fBranchCount->TBranch::GetEntry(treeEntry);
362  }
363  fBranch->TBranch::GetEntry(treeEntry);
364  }
365  // NO - we only read the entries, not the contained objects!
366  // fRead = treeEntry;
367  }
368  return IsInitialized();
369  }
370 
371  virtual Int_t GetEntries() {
372  if (!ReadEntries()) return 0;
373  if (!fHasLeafCount) {
374  return *(Int_t*)fLeafCount->GetValuePointer();
375  } else {
376  return 1;
377  }
378  }
379 
380  virtual Int_t GetArrayLength() {
381  return fArrayLength;
382  }
383 
384  TClass *GetClass() {
385  if (fDirector==0) return 0;
386 
387  if (fDirector->GetReadEntry() != fRead) {
388  if (!IsInitialized()) {
389  if (!Setup()) {
390  return 0;
391  }
392  }
393  }
394  return fClass;
395  }
396 
397  void* GetWhere() const { return fWhere; } // intentionally non-virtual
398 
399  /// Return the address of the element number i. Returns `nullptr` for non-collections. It assumed that Setip() has
400  /// been called.
401  virtual void *GetAddressOfElement(UInt_t /*i*/) {
402  return nullptr;
403  }
404 
405  TVirtualCollectionProxy *GetCollection() { return fCollection; }
406 
407  // protected:
408  virtual void *GetStart(UInt_t /*i*/=0) {
409  // return the address of the start of the object being proxied. Assumes
410  // that Setup() has been called.
411 
412  if (fParent) {
413  fWhere = ((unsigned char*)fParent->GetStart()) + fMemberOffset;
414  }
415  if (IsaPointer()) {
416  if (fWhere) return *(void**)fWhere;
417  else return 0;
418  } else {
419  return fWhere;
420  }
421  }
422 
423  void *GetClaStart(UInt_t i=0) {
424  // return the address of the start of the object being proxied. Assumes
425  // that Setup() has been called. Assumes the object containing this data
426  // member is held in TClonesArray.
427 
428  char *location;
429 
430  if (fIsClone) {
431 
432  TClonesArray *tca;
433  tca = (TClonesArray*)GetStart();
434 
435  if (!tca || tca->GetLast()<(Int_t)i) return 0;
436 
437  location = (char*)tca->At(i);
438 
439  return location;
440 
441  } else if (fParent) {
442 
443  //tcaloc = ((unsigned char*)fParent->GetStart());
444  location = (char*)fParent->GetClaStart(i);
445 
446  } else {
447 
448  void *tcaloc;
449  tcaloc = fWhere;
450  TClonesArray *tca;
451  tca = (TClonesArray*)tcaloc;
452 
453  if (tca->GetLast()<(Int_t)i) return 0;
454 
455  location = (char*)tca->At(i);
456  }
457 
458  if (location) location += fOffset;
459  else return 0;
460 
461  if (IsaPointer()) {
462  return *(void**)(location);
463  } else {
464  return location;
465  }
466 
467  }
468 
469  void *GetStlStart(UInt_t i=0) {
470  // return the address of the start of the object being proxied. Assumes
471  // that Setup() has been called. Assumes the object containing this data
472  // member is held in STL Collection.
473 
474  char *location=0;
475 
476  if (fCollection) {
477 
478  if (fCollection->Size()<i) return 0;
479 
480  location = (char*)fCollection->At(i);
481 
482  // return location;
483 
484  } else if (fParent) {
485 
486  //tcaloc = ((unsigned char*)fParent->GetStart());
487  location = (char*)fParent->GetStlStart(i);
488 
489  } else {
490 
491  R__ASSERT(0);
492  //void *tcaloc;
493  //tcaloc = fWhere;
494  //TClonesArray *tca;
495  //tca = (TClonesArray*)tcaloc;
496 
497  //if (tca->GetLast()<i) return 0;
498 
499  //location = (char*)tca->At(i);
500  }
501 
502  if (location) location += fOffset;
503  else return 0;
504 
505  if (IsaPointer()) {
506  return *(void**)(location);
507  } else {
508  return location;
509  }
510 
511  }
512 
513  Int_t GetOffset() { return fOffset; }
514  };
515 } // namespace Detail
516 
517 namespace Internal {
518 
519  //____________________________________________________________________________________________
520  // Concrete Implementation of the branch proxy around the data members which are array of char
521  class TArrayCharProxy : public Detail::TBranchProxy {
522  public:
523  void Print() override {
524  TBranchProxy::Print();
525  std::cout << "fWhere " << fWhere << std::endl;
526  if (fWhere) std::cout << "value? " << *(unsigned char*)GetStart() << std::endl;
527  }
528 
529  using TBranchProxy::TBranchProxy;
530  TArrayCharProxy() = default; // work around bug in GCC < 7
531  ~TArrayCharProxy() override = default;
532 
533  void *GetAddressOfElement(UInt_t i) final {
534  if (!Read()) return nullptr;
535  unsigned char* str = (unsigned char*)GetStart();
536  return str + i;
537  }
538 
539  unsigned char At(UInt_t i) {
540  static unsigned char default_val = {};
541  if (unsigned char* elAddr = (unsigned char*)GetAddressOfElement(i)) {
542  // should add out-of bound test
543  return *elAddr;
544  }
545  return default_val;
546  }
547 
548  unsigned char operator [](Int_t i) {
549  return At(i);
550  }
551 
552  unsigned char operator [](UInt_t i) {
553  return At(i);
554  }
555 
556  operator const char*() {
557  if (!Read()) return "";
558  return (const char*)GetStart();
559  }
560 
561  const char* Data() {
562  if (!Read()) return "";
563  return (const char*)GetStart();
564  }
565 
566  const char* c_str() {
567  if (!Read()) return "";
568  return (const char*)GetStart();
569  }
570 
571  operator std::string() {
572  if (!Read()) return "";
573  return std::string((const char*)GetStart());
574  }
575 
576  };
577 
578  //_______________________________________________________
579  // Base class for the proxy around object in TClonesArray.
580  class TClaProxy : public Detail::TBranchProxy {
581  public:
582  void Print() override {
583  TBranchProxy::Print();
584  std::cout << "fWhere " << fWhere << std::endl;
585  if (fWhere) {
586  if (IsaPointer()) {
587  std::cout << "location " << *(TClonesArray**)fWhere << std::endl;
588  } else {
589  std::cout << "location " << fWhere << std::endl;
590  }
591  }
592  }
593 
594  using TBranchProxy::TBranchProxy;
595  TClaProxy() = default; // work around bug in GCC < 7
596  ~TClaProxy() override = default;
597 
598  const TClonesArray* GetPtr() {
599  if (!Read()) return 0;
600  return (TClonesArray*)GetStart();
601  }
602 
603  Int_t GetEntries() override {
604  if (!ReadEntries()) return 0;
605  TClonesArray *arr = (TClonesArray*)GetStart();
606  if (arr) return arr->GetEntries();
607  return 0;
608  }
609 
610  void *GetAddressOfElement(UInt_t i) final {
611  if (!Read()) return nullptr;
612  if (fWhere==0) return nullptr;
613  return GetClaStart(i);
614  }
615 
616  const TClonesArray* operator->() { return GetPtr(); }
617 
618  };
619 
620  //_______________________________________________
621  // Base class for the proxy around STL containers.
622  class TStlProxy : public Detail::TBranchProxy {
623  public:
624  void Print() override {
625  TBranchProxy::Print();
626  std::cout << "fWhere " << fWhere << std::endl;
627  if (fWhere) {
628  if (IsaPointer()) {
629  std::cout << "location " << *(TClonesArray**)fWhere << std::endl;
630  } else {
631  std::cout << "location " << fWhere << std::endl;
632  }
633  }
634  }
635 
636  using TBranchProxy::TBranchProxy;
637  TStlProxy() = default; // work around bug in GCC < 7
638  ~TStlProxy() override = default;
639 
640  const TVirtualCollectionProxy* GetPtr() {
641  if (!Read()) return 0;
642  return GetCollection();
643  }
644 
645  Int_t GetEntries() override {
646  if (!ReadEntries()) return 0;
647  return GetPtr()->Size();
648  }
649 
650  void *GetAddressOfElement(UInt_t i) final {
651  if (!Read()) return nullptr;
652  if (fWhere==0) return nullptr;
653  return GetStlStart(i);
654  }
655 
656  const TVirtualCollectionProxy* operator->() { return GetPtr(); }
657 
658  };
659 
660  //______________________________________
661  // Template of the proxy around objects.
662  template <class T>
663  class TImpProxy : public Detail::TBranchProxy {
664  public:
665  void Print() override {
666  TBranchProxy::Print();
667  std::cout << "fWhere " << fWhere << std::endl;
668  if (fWhere) std::cout << "value? " << *(T*)GetStart() << std::endl;
669  }
670 
671  using TBranchProxy::TBranchProxy;
672  TImpProxy() = default; // work around bug in GCC < 7
673  ~TImpProxy() override = default;
674 
675  operator T() {
676  if (!Read()) return 0;
677  return *(T*)GetStart();
678  }
679 
680  // For now explicitly disable copying into the value (i.e. the proxy is read-only).
681  TImpProxy(T) = delete;
682  TImpProxy &operator=(T) = delete;
683 
684  };
685 
686  //____________________________________________
687  // Helper template to be able to determine and
688  // use array dimentsions.
689  template <class T, int d = 0> struct TArrayType {
690  typedef T type_t;
691  typedef T array_t[d];
692  static constexpr int gSize = d;
693  };
694  //____________________________________________
695  // Helper class for proxy around multi dimension array
696  template <class T> struct TArrayType<T,0> {
697  typedef T type_t;
698  typedef T array_t;
699  static constexpr int gSize = 0;
700  };
701  //____________________________________________
702  // Helper class for proxy around multi dimension array
703  template <class T, int d> struct TMultiArrayType {
704  typedef typename T::type_t type_t;
705  typedef typename T::array_t array_t[d];
706  static constexpr int gSize = d;
707  };
708 
709  //____________________________________________
710  // Template for concrete implementation of proxy around array of T
711  template <class T>
712  class TArrayProxy : public Detail::TBranchProxy {
713  public:
714  using TBranchProxy::TBranchProxy;
715  TArrayProxy() = default; // work around bug in GCC < 7
716  ~TArrayProxy() override = default;
717 
718  typedef typename T::array_t array_t;
719  typedef typename T::type_t type_t;
720 
721  void Print() override {
722  TBranchProxy::Print();
723  std::cout << "fWhere " << GetWhere() << std::endl;
724  if (GetWhere()) std::cout << "value? " << *(type_t*)GetWhere() << std::endl;
725  }
726 
727  Int_t GetEntries() override {
728  return T::gSize;
729  }
730 
731  void *GetAddressOfElement(UInt_t i) final {
732  if (!Read()) return nullptr;
733  if (array_t *arr = (array_t*)((type_t*)(GetStart())))
734  return &arr[i];
735  return nullptr;
736  }
737 
738  const array_t &At(UInt_t i) {
739  static array_t default_val;
740  // should add out-of bound test
741  if (array_t *arr = (array_t*)GetAddressOfElement(i))
742  return *arr;
743  return default_val;
744  }
745 
746  const array_t &operator [](Int_t i) { return At(i); }
747  const array_t &operator [](UInt_t i) { return At(i); }
748  };
749 
750  //_____________________________________________________________________________________
751  // Template of the Concrete Implementation of the branch proxy around TClonesArray of T
752  template <class T>
753  class TClaImpProxy : public TClaProxy {
754  public:
755 
756  // void Print() override {
757  // TClaProxy::Print();
758  // }
759 
760  using TClaProxy::TClaProxy;
761  TClaImpProxy() = default; // work around bug in GCC < 7
762  ~TClaImpProxy() override = default;
763 
764  const T& At(UInt_t i) {
765  static T default_val;
766  if (void* addr = GetAddressOfElement(i))
767  return *(T*)addr;
768  return default_val;
769  }
770 
771  const T& operator [](Int_t i) { return At(i); }
772  const T& operator [](UInt_t i) { return At(i); }
773 
774  // For now explicitly disable copying into the value (i.e. the proxy is read-only).
775  TClaImpProxy(T) = delete;
776  TClaImpProxy &operator=(T) = delete;
777 
778  };
779 
780  //_________________________________________________________________________________________
781  // Template of the Concrete Implementation of the branch proxy around an stl container of T
782  template <class T>
783  class TStlImpProxy : public TStlProxy {
784  public:
785 
786  // void Print() override {
787  // TBranchProxy::Print();
788  // }
789 
790  using TStlProxy::TStlProxy;
791  TStlImpProxy() = default; // work around bug in GCC < 7
792  ~TStlImpProxy() override = default;
793 
794  const T& At(UInt_t i) {
795  static T default_val;
796  if (void* addr = GetAddressOfElement(i))
797  return *(T*)addr;
798  return default_val;
799  }
800 
801  const T& operator [](Int_t i) { return At(i); }
802  const T& operator [](UInt_t i) { return At(i); }
803 
804  // For now explicitly disable copying into the value (i.e. the proxy is read-only).
805  TStlImpProxy(T) = delete;
806  TStlImpProxy &operator=(T) = delete;
807 
808  };
809 
810  //_________________________________________________________________________________________________
811  // Template of the Concrete Implementation of the branch proxy around an TClonesArray of array of T
812  template <class T>
813  class TClaArrayProxy : public TClaProxy {
814  public:
815  typedef typename T::array_t array_t;
816  typedef typename T::type_t type_t;
817 
818  // void Print() override {
819  // TClaProxy::Print();
820  // }
821 
822  using TClaProxy::TClaProxy;
823  TClaArrayProxy() = default; // work around bug in GCC < 7
824  ~TClaArrayProxy() override = default;
825 
826  /* const */ array_t *At(UInt_t i) {
827  static array_t default_val;
828  if (array_t* ptr = (array_t*)GetAddressOfElement(i))
829  return ptr; // no de-ref!
830 
831  return &default_val;
832  }
833 
834  /* const */ array_t *operator [](Int_t i) { return At(i); }
835  /* const */ array_t *operator [](UInt_t i) { return At(i); }
836  };
837 
838 
839  //__________________________________________________________________________________________________
840  // Template of the Concrete Implementation of the branch proxy around an stl container of array of T
841  template <class T>
842  class TStlArrayProxy : public TStlProxy {
843  public:
844  typedef typename T::array_t array_t;
845  typedef typename T::type_t type_t;
846 
847  // void Print() override {
848  // TBranchProxy::Print();
849  // }
850 
851  using TStlProxy::TStlProxy;
852  TStlArrayProxy() = default; // work around bug in GCC < 7
853  ~TStlArrayProxy() override = default;
854 
855  /* const */ array_t *At(UInt_t i) {
856  static array_t default_val;
857  if (array_t* ptr = (array_t*)GetAddressOfElement(i))
858  return ptr; // no de-ref!
859  return &default_val;
860  }
861 
862  /* const */ array_t *operator [](Int_t i) { return At(i); }
863  /* const */ array_t *operator [](UInt_t i) { return At(i); }
864  };
865 
866  //TImpProxy<TObject> d;
867  typedef TImpProxy<Double_t> TDoubleProxy; // Concrete Implementation of the branch proxy around the data members which are double
868  typedef TImpProxy<Double32_t> TDouble32Proxy; // Concrete Implementation of the branch proxy around the data members which are double32
869  typedef TImpProxy<Float_t> TFloatProxy; // Concrete Implementation of the branch proxy around the data members which are float
870  typedef TImpProxy<Float16_t> TFloat16Proxy; // Concrete Implementation of the branch proxy around the data members which are float16
871  typedef TImpProxy<UInt_t> TUIntProxy; // Concrete Implementation of the branch proxy around the data members which are unsigned int
872  typedef TImpProxy<ULong_t> TULongProxy; // Concrete Implementation of the branch proxy around the data members which are unsigned long
873  typedef TImpProxy<ULong64_t> TULong64Proxy; // Concrete Implementation of the branch proxy around the data members which are unsigned long long
874  typedef TImpProxy<UShort_t> TUShortProxy; // Concrete Implementation of the branch proxy around the data members which are unsigned short
875  typedef TImpProxy<UChar_t> TUCharProxy; // Concrete Implementation of the branch proxy around the data members which are unsigned char
876  typedef TImpProxy<Int_t> TIntProxy; // Concrete Implementation of the branch proxy around the data members which are int
877  typedef TImpProxy<Long_t> TLongProxy; // Concrete Implementation of the branch proxy around the data members which are long
878  typedef TImpProxy<Long64_t> TLong64Proxy; // Concrete Implementation of the branch proxy around the data members which are long long
879  typedef TImpProxy<Short_t> TShortProxy; // Concrete Implementation of the branch proxy around the data members which are short
880  typedef TImpProxy<Char_t> TCharProxy; // Concrete Implementation of the branch proxy around the data members which are char
881  typedef TImpProxy<Bool_t> TBoolProxy; // Concrete Implementation of the branch proxy around the data members which are bool
882 
883  typedef TArrayProxy<TArrayType<Double_t> > TArrayDoubleProxy; // Concrete Implementation of the branch proxy around the data members which are array of double
884  typedef TArrayProxy<TArrayType<Double32_t> > TArrayDouble32Proxy; // Concrete Implementation of the branch proxy around the data members which are array of double32
885  typedef TArrayProxy<TArrayType<Float_t> > TArrayFloatProxy; // Concrete Implementation of the branch proxy around the data members which are array of float
886  typedef TArrayProxy<TArrayType<Float16_t> > TArrayFloat16Proxy; // Concrete Implementation of the branch proxy around the data members which are array of float16
887  typedef TArrayProxy<TArrayType<UInt_t> > TArrayUIntProxy; // Concrete Implementation of the branch proxy around the data members which are array of unsigned int
888  typedef TArrayProxy<TArrayType<ULong_t> > TArrayULongProxy; // Concrete Implementation of the branch proxy around the data members which are array of unsigned long
889  typedef TArrayProxy<TArrayType<ULong64_t> > TArrayULong64Proxy; // Concrete Implementation of the branch proxy around the data members which are array of unsigned long long
890  typedef TArrayProxy<TArrayType<UShort_t> > TArrayUShortProxy; // Concrete Implementation of the branch proxy around the data members which are array of unsigned short
891  typedef TArrayProxy<TArrayType<UChar_t> > TArrayUCharProxy; // Concrete Implementation of the branch proxy around the data members which are array of unsigned char
892  typedef TArrayProxy<TArrayType<Int_t> > TArrayIntProxy; // Concrete Implementation of the branch proxy around the data members which are array of int
893  typedef TArrayProxy<TArrayType<Long_t> > TArrayLongProxy; // Concrete Implementation of the branch proxy around the data members which are array of long
894  typedef TArrayProxy<TArrayType<Long64_t> > TArrayLong64Proxy; // Concrete Implementation of the branch proxy around the data members which are array of long long
895  typedef TArrayProxy<TArrayType<UShort_t> > TArrayShortProxy; // Concrete Implementation of the branch proxy around the data members which are array of short
896  //specialized ! typedef TArrayProxy<TArrayType<Char_t> > TArrayCharProxy; // Concrete Implementation of the branch proxy around the data members which are array of char
897  typedef TArrayProxy<TArrayType<Bool_t> > TArrayBoolProxy; // Concrete Implementation of the branch proxy around the data members which are array of bool
898 
899  typedef TClaImpProxy<Double_t> TClaDoubleProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are double
900  typedef TClaImpProxy<Double32_t> TClaDouble32Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are double32
901  typedef TClaImpProxy<Float_t> TClaFloatProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are float
902  typedef TClaImpProxy<Float16_t> TClaFloat16Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are float16
903  typedef TClaImpProxy<UInt_t> TClaUIntProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are unsigned int
904  typedef TClaImpProxy<ULong_t> TClaULongProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are unsigned long
905  typedef TClaImpProxy<ULong64_t> TClaULong64Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are unsigned long long
906  typedef TClaImpProxy<UShort_t> TClaUShortProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are unsigned short
907  typedef TClaImpProxy<UChar_t> TClaUCharProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are unsigned char
908  typedef TClaImpProxy<Int_t> TClaIntProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are int
909  typedef TClaImpProxy<Long_t> TClaLongProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are long
910  typedef TClaImpProxy<Long64_t> TClaLong64Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are long long
911  typedef TClaImpProxy<Short_t> TClaShortProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are short
912  typedef TClaImpProxy<Char_t> TClaCharProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are char
913  typedef TClaImpProxy<Bool_t> TClaBoolProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are bool
914 
915  typedef TClaArrayProxy<TArrayType<Double_t> > TClaArrayDoubleProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of double
916  typedef TClaArrayProxy<TArrayType<Double32_t> > TClaArrayDouble32Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of double32
917  typedef TClaArrayProxy<TArrayType<Float_t> > TClaArrayFloatProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of float
918  typedef TClaArrayProxy<TArrayType<Float16_t> > TClaArrayFloat16Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of float16
919  typedef TClaArrayProxy<TArrayType<UInt_t> > TClaArrayUIntProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of unsigned int
920  typedef TClaArrayProxy<TArrayType<ULong_t> > TClaArrayULongProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of unsigned long
921  typedef TClaArrayProxy<TArrayType<ULong64_t> > TClaArrayULong64Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of unsigned long long
922  typedef TClaArrayProxy<TArrayType<UShort_t> > TClaArrayUShortProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of unsigned short
923  typedef TClaArrayProxy<TArrayType<UChar_t> > TClaArrayUCharProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of nsigned char
924  typedef TClaArrayProxy<TArrayType<Int_t> > TClaArrayIntProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of int
925  typedef TClaArrayProxy<TArrayType<Long_t> > TClaArrayLongProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of long
926  typedef TClaArrayProxy<TArrayType<Long64_t> > TClaArrayLong64Proxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of long long
927  typedef TClaArrayProxy<TArrayType<UShort_t> > TClaArrayShortProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of short
928  typedef TClaArrayProxy<TArrayType<Char_t> > TClaArrayCharProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of char
929  typedef TClaArrayProxy<TArrayType<Bool_t> > TClaArrayBoolProxy; // Concrete Implementation of the branch proxy around the data members of object in TClonesArray which are array of bool
930  //specialized ! typedef TClaArrayProxy<TArrayType<Char_t> > TClaArrayCharProxy;
931 
932  typedef TStlImpProxy<Double_t> TStlDoubleProxy; // Concrete Implementation of the branch proxy around an stl container of double
933  typedef TStlImpProxy<Double32_t> TStlDouble32Proxy; // Concrete Implementation of the branch proxy around an stl container of double32
934  typedef TStlImpProxy<Float_t> TStlFloatProxy; // Concrete Implementation of the branch proxy around an stl container of float
935  typedef TStlImpProxy<Float16_t> TStlFloat16Proxy; // Concrete Implementation of the branch proxy around an stl container of float16_t
936  typedef TStlImpProxy<UInt_t> TStlUIntProxy; // Concrete Implementation of the branch proxy around an stl container of unsigned int
937  typedef TStlImpProxy<ULong_t> TStlULongProxy; // Concrete Implementation of the branch proxy around an stl container of unsigned long
938  typedef TStlImpProxy<ULong64_t> TStlULong64Proxy; // Concrete Implementation of the branch proxy around an stl container of unsigned long long
939  typedef TStlImpProxy<UShort_t> TStlUShortProxy; // Concrete Implementation of the branch proxy around an stl container of unsigned short
940  typedef TStlImpProxy<UChar_t> TStlUCharProxy; // Concrete Implementation of the branch proxy around an stl container of unsigned char
941  typedef TStlImpProxy<Int_t> TStlIntProxy; // Concrete Implementation of the branch proxy around an stl container of int
942  typedef TStlImpProxy<Long_t> TStlLongProxy; // Concrete Implementation of the branch proxy around an stl container of long
943  typedef TStlImpProxy<Long64_t> TStlLong64Proxy; // Concrete Implementation of the branch proxy around an stl container of long long
944  typedef TStlImpProxy<Short_t> TStlShortProxy; // Concrete Implementation of the branch proxy around an stl container of short
945  typedef TStlImpProxy<Char_t> TStlCharProxy; // Concrete Implementation of the branch proxy around an stl container of char
946  typedef TStlImpProxy<Bool_t> TStlBoolProxy; // Concrete Implementation of the branch proxy around an stl container of bool
947 
948  typedef TStlArrayProxy<TArrayType<Double_t> > TStlArrayDoubleProxy; // Concrete Implementation of the branch proxy around an stl container of double
949  typedef TStlArrayProxy<TArrayType<Double32_t> > TStlArrayDouble32Proxy; // Concrete Implementation of the branch proxy around an stl container of double32
950  typedef TStlArrayProxy<TArrayType<Float_t> > TStlArrayFloatProxy; // Concrete Implementation of the branch proxy around an stl container of float
951  typedef TStlArrayProxy<TArrayType<Float16_t> > TStlArrayFloat16Proxy; // Concrete Implementation of the branch proxy around an stl container of float16_t
952  typedef TStlArrayProxy<TArrayType<UInt_t> > TStlArrayUIntProxy; // Concrete Implementation of the branch proxy around an stl container of unsigned int
953  typedef TStlArrayProxy<TArrayType<ULong_t> > TStlArrayULongProxy; // Concrete Implementation of the branch proxy around an stl container of usigned long
954  typedef TStlArrayProxy<TArrayType<ULong64_t> > TStlArrayULong64Proxy; // Concrete Implementation of the branch proxy around an stl contained of unsigned long long
955  typedef TStlArrayProxy<TArrayType<UShort_t> > TStlArrayUShortProxy; // Concrete Implementation of the branch proxy around an stl container of unisgned short
956  typedef TStlArrayProxy<TArrayType<UChar_t> > TStlArrayUCharProxy; // Concrete Implementation of the branch proxy around an stl container of unsingned char
957  typedef TStlArrayProxy<TArrayType<Int_t> > TStlArrayIntProxy; // Concrete Implementation of the branch proxy around an stl container of int
958  typedef TStlArrayProxy<TArrayType<Long_t> > TStlArrayLongProxy; // Concrete Implementation of the branch proxy around an stl container of long
959  typedef TStlArrayProxy<TArrayType<Long64_t> > TStlArrayLong64Proxy; // Concrete Implementation of the branch proxy around an stl container of long long
960  typedef TStlArrayProxy<TArrayType<UShort_t> > TStlArrayShortProxy; // Concrete Implementation of the branch proxy around an stl container of UShort_t
961  typedef TStlArrayProxy<TArrayType<Char_t> > TStlArrayCharProxy; // Concrete Implementation of the branch proxy around an stl container of char
962  typedef TStlArrayProxy<TArrayType<Bool_t> > TStlArrayBoolProxy; // Concrete Implementation of the branch proxy around an stl container of bool
963 
964 } // namespace Internal
965 
966 // Reasonably backward compatible.
967 using Detail::TBranchProxy;
968 
969 } // namespace ROOT
970 
971 #endif
972