Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TLeaf.h
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Rene Brun 12/01/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
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_TLeaf
13 #define ROOT_TLeaf
14 
15 
16 //////////////////////////////////////////////////////////////////////////
17 // //
18 // TLeaf //
19 // //
20 // A TTree object is a list of TBranch. //
21 // A TBranch object is a list of TLeaf. In most cases, the TBranch //
22 // will have one TLeaf. //
23 // A TLeaf describes the branch data types and holds the data. //
24 // //
25 // A few notes about the data held by the leaf. It can contain: //
26 // 1 a single object or primitive (e.g., one float), //
27 // 2 a fixed-number of objects (e.g., each entry has two floats). //
28 // The number of elements per entry is saved in `fLen`. //
29 // 3 a dynamic number of primitives. The number of objects in each //
30 // entry is saved in the `fLeafCount` branch. //
31 // //
32 // Note options (2) and (3) can combined - if fLeafCount says an entry //
33 // has 3 elements and fLen is 2, then there will be 6 objects in that //
34 // entry. //
35 // //
36 // Additionally, `fNdata` is transient and generated on read to //
37 // determine the necessary size of a buffer to hold event data; //
38 // depending on the call-site, it may be sized larger than the number //
39 // of elements //
40 // //
41 //////////////////////////////////////////////////////////////////////////
42 
43 
44 #include "TBranch.h"
45 
46 class TClonesArray;
47 class TBrowser;
48 
49 class TLeaf : public TNamed {
50 
51 private:
52 
53  virtual Int_t GetOffsetHeaderSize() const {return 0;}
54 
55 protected:
56 
57  using Counts_t = std::vector<Int_t>;
58  struct LeafCountValues {
59  Counts_t fValues;
60  Long64_t fStartEntry{-1}; ///<! entry number of corresponding to element 0 of the vector.
61  };
62 
63  Int_t fNdata; ///<! Number of elements in fAddress data buffer.
64  Int_t fLen; ///< Number of fixed length elements in the leaf's data.
65  Int_t fLenType; ///< Number of bytes for this data type
66  Int_t fOffset; ///< Offset in ClonesArray object (if one)
67  Bool_t fIsRange; ///< (=kTRUE if leaf has a range, kFALSE otherwise). This is equivalent to being a 'leafcount'. For a TLeafElement the range information is actually store in the TBranchElement.
68  Bool_t fIsUnsigned; ///< (=kTRUE if unsigned, kFALSE otherwise)
69  TLeaf *fLeafCount; ///< Pointer to Leaf count if variable length (we do not own the counter)
70  TBranch *fBranch; ///<! Pointer to supporting branch (we do not own the branch)
71  LeafCountValues *fLeafCountValues; ///<! Cache of collection/array sizes
72 
73  TLeaf(const TLeaf&);
74  TLeaf& operator=(const TLeaf&);
75 
76  template <typename T> struct GetValueHelper {
77  static T Exec(const TLeaf *leaf, Int_t i = 0) { return leaf->GetValue(i); }
78  };
79 
80  Int_t *GenerateOffsetArrayBase(Int_t base, Int_t events) const; // For leaves containing fixed-size objects (no
81  // polymorphism!), this will generate an appropriate
82  // offset array.
83 
84 
85 public:
86  enum EStatusBits {
87  kIndirectAddress = BIT(11), ///< Data member is a pointer to an array of basic types.
88  kNewValue = BIT(12) ///< Set if we own the value buffer and so must delete it ourselves.
89  };
90 
91  enum class DeserializeType {
92  kInvalid = 0, // Invalid deserialization information.
93  kDestructive, // Deserialization of this Leaf requires a separate output buffer.
94  kInPlace, // Deserialization can be done directly in the input buffer.
95  kZeroCopy, // In-memory and on-disk representation of this object are identical.
96  };
97 
98  TLeaf();
99  TLeaf(TBranch *parent, const char *name, const char *type);
100  virtual ~TLeaf();
101 
102  virtual void Browse(TBrowser *b);
103  virtual Bool_t CanGenerateOffsetArray() {return fLeafCount;} // overload and return true if this leaf can generate its own offset array.
104  virtual void Export(TClonesArray *, Int_t) {}
105  virtual void FillBasket(TBuffer &b);
106  virtual Int_t *GenerateOffsetArray(Int_t base, Int_t events) { return GenerateOffsetArrayBase(base, events); }
107  TBranch *GetBranch() const { return fBranch; }
108  virtual DeserializeType GetDeserializeType() const { return DeserializeType::kDestructive; }
109  /// If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has variable size,
110  /// return a pointer to the TLeaf that stores such size. Return a nullptr otherwise.
111  virtual TLeaf *GetLeafCount() const { return fLeafCount; }
112  virtual TLeaf *GetLeafCounter(Int_t &countval) const;
113 
114  virtual const Counts_t *GetLeafCountValues(Long64_t start, Long64_t len);
115 
116  virtual Int_t GetLen() const;
117  /// Return the fixed length of this leaf.
118  /// If the leaf stores a fixed-length array, this is the size of the array.
119  /// If the leaf stores a non-array or a variable-sized array, this method returns 1.
120  /// If the leaf stores an array with 2 or more dimensions, this method returns the total number of elements in the
121  /// dimensions with static length: for example for float[3][2][] it would return 6.
122  virtual Int_t GetLenStatic() const { return fLen; }
123  virtual Int_t GetLenType() const { return fLenType; }
124  virtual Int_t GetMaximum() const { return 0; }
125  virtual Int_t GetMinimum() const { return 0; }
126  virtual Int_t GetNdata() const { return fNdata; }
127  virtual Int_t GetOffset() const { return fOffset; }
128  virtual void *GetValuePointer() const { return 0; }
129  virtual const char *GetTypeName() const { return ""; }
130 
131  virtual Double_t GetValue(Int_t i = 0) const;
132  virtual Long64_t GetValueLong64(Int_t i = 0) const { return GetValue(i); } // overload only when it matters.
133  virtual LongDouble_t GetValueLongDouble(Int_t i = 0) const { return GetValue(i); } // overload only when it matters.
134  template <typename T> T GetTypedValue(Int_t i = 0) const { return GetValueHelper<T>::Exec(this, i); }
135 
136  virtual Bool_t IncludeRange(TLeaf *) { return kFALSE; } // overload to copy/set fMinimum and fMaximum to include/be wide than those of the parameter
137  virtual void Import(TClonesArray *, Int_t) {}
138  virtual Bool_t IsOnTerminalBranch() const { return kTRUE; }
139  virtual Bool_t IsRange() const { return fIsRange; }
140  virtual Bool_t IsUnsigned() const { return fIsUnsigned; }
141  virtual void PrintValue(Int_t i = 0) const;
142  virtual void ReadBasket(TBuffer &) {}
143  virtual void ReadBasketExport(TBuffer &, TClonesArray *, Int_t) {}
144  virtual bool ReadBasketFast(TBuffer&, Long64_t) { return false; } // Read contents of leaf into a user-provided buffer.
145  virtual bool ReadBasketSerialized(TBuffer&, Long64_t) { return false; } // Read contents of leaf into a user-provided buffer
146  virtual void ReadValue(std::istream & /*s*/, Char_t /*delim*/ = ' ') {
147  Error("ReadValue", "Not implemented!");
148  }
149  Int_t ResetAddress(void *add, Bool_t destructor = kFALSE);
150  virtual void SetAddress(void *add = 0);
151  virtual void SetBranch(TBranch *branch) { fBranch = branch; }
152  virtual void SetLeafCount(TLeaf *leaf);
153  virtual void SetLen(Int_t len = 1) { fLen = len; }
154  virtual void SetOffset(Int_t offset = 0) { fOffset = offset; }
155  virtual void SetRange(Bool_t range = kTRUE) { fIsRange = range; }
156  virtual void SetUnsigned() { fIsUnsigned = kTRUE; }
157 
158  ClassDef(TLeaf, 2); // Leaf: description of a Branch data type
159 };
160 
161 
162 template <> struct TLeaf::GetValueHelper<Long64_t> {
163  static Long64_t Exec(const TLeaf *leaf, Int_t i = 0) { return leaf->GetValueLong64(i); }
164 };
165 template <> struct TLeaf::GetValueHelper<ULong64_t> {
166  static ULong64_t Exec(const TLeaf *leaf, Int_t i = 0) { return (ULong64_t)leaf->GetValueLong64(i); }
167 };
168 template <> struct TLeaf::GetValueHelper<LongDouble_t> {
169  static LongDouble_t Exec(const TLeaf *leaf, Int_t i = 0) { return leaf->GetValueLongDouble(i); }
170 };
171 
172 
173 inline Double_t TLeaf::GetValue(Int_t /*i = 0*/) const { return 0.0; }
174 inline void TLeaf::PrintValue(Int_t /* i = 0*/) const {}
175 inline void TLeaf::SetAddress(void* /* add = 0 */) {}
176 
177 #endif