Logo ROOT   6.14/05
Reference Guide
TTreeReaderArray.h
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Axel Naumann, 2010-08-02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, 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_TTreeReaderArray
13 #define ROOT_TTreeReaderArray
14 
15 
16 ////////////////////////////////////////////////////////////////////////////
17 // //
18 // TTreeReaderArray //
19 // //
20 // A simple interface for reading data from trees or chains. //
21 // //
22 // //
23 ////////////////////////////////////////////////////////////////////////////
24 
25 #include "TTreeReaderValue.h"
26 #include "TTreeReaderUtils.h"
27 #include <type_traits>
28 
29 namespace ROOT {
30 namespace Internal {
31 
33  public:
34  TTreeReaderArrayBase(TTreeReader* reader, const char* branchname,
35  TDictionary* dict):
36  TTreeReaderValueBase(reader, branchname, dict), fImpl(0) {}
37 
38  std::size_t GetSize() const { return fImpl->GetSize(GetProxy()); }
39  Bool_t IsEmpty() const { return !GetSize(); }
40 
41  virtual EReadStatus GetReadStatus() const { return fImpl ? fImpl->fReadStatus : kReadError; }
42 
43  protected:
44  void *UntypedAt(std::size_t idx) const { return fImpl->At(GetProxy(), idx); }
45  virtual void CreateProxy();
46  bool GetBranchAndLeaf(TBranch* &branch, TLeaf* &myLeaf,
47  TDictionary* &branchActualType);
48  void SetImpl(TBranch* branch, TLeaf* myLeaf);
49  const char* GetBranchContentDataType(TBranch* branch,
50  TString& contentTypeName,
51  TDictionary* &dict);
52 
53  TVirtualCollectionReader* fImpl; // Common interface to collections
54 
55  // FIXME: re-introduce once we have ClassDefInline!
56  //ClassDef(TTreeReaderArrayBase, 0);//Accessor to member of an object stored in a collection
57  };
58 
59 } // namespace Internal
60 } // namespace ROOT
61 
62 template <typename T>
64 public:
65  /// Random access iterator to the elements of a TTreeReaderArray.
66  // The template parameter is there to allow distinguishing between the `const` and `non-const` cases.
67  template <typename ReaderArrayType>
68  class Iterator_t {
69  public:
70  // iterators must define the following types
71  using iterator_category = std::random_access_iterator_tag;
72  using value_type = T;
73  using difference_type = std::ptrdiff_t;
74  using pointer = typename std::conditional<std::is_const<ReaderArrayType>::value, const T *, T *>::type;
75  using reference = typename std::conditional<std::is_const<ReaderArrayType>::value, const T &, T &>::type;
76 
77  private:
78  TTreeReaderArray *fArray; ///< The array iterated over; nullptr if invalid/past-the-end.
79  std::size_t fIndex; ///< Current index in the array.
80  std::size_t fSize; ///< Size of the TTreeReaderArray
81  public:
82  /// Default ctor: constructs a past-the-end iterator
83  Iterator_t() : fArray(nullptr), fIndex(0u), fSize(0u) {}
84 
85  /// Construct iterator
86  Iterator_t(std::size_t index, TTreeReaderArray *array)
87  : fArray(array), fIndex(index), fSize(fArray ? fArray->GetSize() : 0u)
88  {
89  if (fIndex >= fSize)
90  fArray = nullptr; // invalidate iterator
91  }
92 
93  /// Construct iterator from a const TTreeReaderArray
94  Iterator_t(std::size_t index, const TTreeReaderArray *array)
95  : Iterator_t(index, const_cast<TTreeReaderArray *>(array)) {}
96 
97  Iterator_t(Iterator_t &&) = default;
98  Iterator_t(const Iterator_t &) = default;
99  Iterator_t &operator=(Iterator_t &&) = default;
100  Iterator_t &operator=(const Iterator_t &) = default;
101 
103  {
104  R__ASSERT(fArray && "invalid iterator!");
105  return fArray->At(fIndex);
106  }
107 
108  pointer operator->() const { return IsValid() ? &fArray->At(fIndex) : nullptr; }
109 
110  bool operator==(const Iterator_t &other) const
111  {
112  // Follow C++14 requiring two past-the-end iterators to be equal.
113  if (!IsValid() && !other.IsValid())
114  return true;
115  return fArray == other.fArray && fIndex == other.fIndex;
116  }
117 
118  bool operator!=(const Iterator_t &other) const { return !(*this == other); }
119 
120  /// Pre-increment operator
122  {
123  if (IsValid())
124  ++fIndex;
125  if (fIndex >= fSize)
126  fArray = nullptr; // invalidate iterator
127  return *this;
128  }
129 
130  /// Post-increment operator
132  {
133  auto ret = *this;
134  this->operator++();
135  return ret;
136  }
137 
138  /// Pre-decrement operator
140  {
141  if (fIndex == 0u)
142  fArray = nullptr; // invalidate iterator
143  else
144  --fIndex;
145  return *this;
146  }
147 
148  /// Post-decrement operator
150  {
151  auto ret = *this;
152  this->operator--();
153  return ret;
154  }
155 
156  Iterator_t operator+(std::ptrdiff_t n) const { return Iterator_t(fIndex + n, fArray); }
157  friend auto operator+(std::ptrdiff_t n, const Iterator_t &it) -> decltype(it + n) { return it + n; }
158 
159  Iterator_t operator-(std::ptrdiff_t n) const
160  {
161  const auto index = std::ptrdiff_t(fIndex);
162  const auto newIndex = index >= n ? index - n : std::numeric_limits<decltype(fIndex)>::max();
163  return Iterator_t(newIndex, fArray);
164  }
165 
166  std::ptrdiff_t operator-(const Iterator_t &other) const { return fIndex - other.fIndex; }
167 
168  Iterator_t &operator+=(std::ptrdiff_t n) { return (*this = *this + n); }
169 
170  Iterator_t &operator-=(std::ptrdiff_t n) { return (*this = *this - n); }
171 
172  bool operator<(const Iterator_t &other) const { return fIndex < other.fIndex; }
173  bool operator>(const Iterator_t &other) const { return fIndex > other.fIndex; }
174  bool operator<=(const Iterator_t &other) const { return !(*this > other); }
175  bool operator>=(const Iterator_t &other) const { return !(*this < other); }
176 
177  reference operator[](std::size_t index) const { return *(*this + index); }
178 
179  operator pointer() { return &fArray->At(fIndex); }
180 
181  bool IsValid() const { return fArray != nullptr; }
182  };
183 
184  using iterator = Iterator_t<TTreeReaderArray<T>>;
185  using const_iterator = Iterator_t<const TTreeReaderArray<T>>;
186 
187  /// Create an array reader of branch "branchname" for TTreeReader "tr".
188  TTreeReaderArray(TTreeReader &tr, const char *branchname)
189  : TTreeReaderArrayBase(&tr, branchname, TDictionary::GetDictionary(typeid(T))) {}
190 
191  T &At(std::size_t idx) { return *static_cast<T *>(UntypedAt(idx)); }
192  const T &At(std::size_t idx) const { return *static_cast<T *>(UntypedAt(idx)); }
193  T &operator[](std::size_t idx) { return At(idx); }
194  const T &operator[](std::size_t idx) const { return At(idx); }
195 
196  iterator begin() { return iterator(0u, this); }
197  iterator end() { return iterator(GetSize(), this); }
198  const_iterator begin() const { return cbegin(); }
199  const_iterator end() const { return cend(); }
200  const_iterator cbegin() const { return const_iterator(0u, this); }
201  const_iterator cend() const { return const_iterator(GetSize(), this); }
202 
203 protected:
204 #define R__TTreeReaderArray_TypeString(T) #T
205  virtual const char *GetDerivedTypeName() const { return R__TTreeReaderArray_TypeString(T); }
206 #undef R__TTreeReaderArray_TypeString
207  // FIXME: re-introduce once we have ClassDefTInline!
208  // ClassDefT(TTreeReaderArray, 0);//Accessor to member of an object stored in a collection
209 };
210 
211 #endif // ROOT_TTreeReaderArray
const_iterator begin() const
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:32
TTreeReaderArray(TTreeReader &tr, const char *branchname)
Create an array reader of branch "branchname" for TTreeReader "tr".
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict)
Access a branch&#39;s collection content (not the collection itself) through a proxy. ...
Iterator_t operator+(std::ptrdiff_t n) const
reference operator[](std::size_t index) const
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:43
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
double T(double x)
Definition: ChebyshevPol.h:34
typename std::conditional< std::is_const< ReaderArrayType >::value, const T &, T & >::type reference
bool operator>(const Iterator_t &other) const
Iterator_t operator++(int)
Post-increment operator.
Iterator_t operator-(std::ptrdiff_t n) const
virtual void CreateProxy()
Create the proxy object for our branch.
#define R__ASSERT(e)
Definition: TError.h:96
Basic string class.
Definition: TString.h:131
bool Bool_t
Definition: RtypesCore.h:59
T & At(std::size_t idx)
Iterator_t & operator--()
Pre-decrement operator.
std::random_access_iterator_tag iterator_category
Iterator_t & operator+=(std::ptrdiff_t n)
TTreeReaderArray * fArray
The array iterated over; nullptr if invalid/past-the-end.
Detail::TBranchProxy * GetProxy() const
bool operator<=(const Iterator_t &other) const
TTreeReaderArrayBase(TTreeReader *reader, const char *branchname, TDictionary *dict)
T & operator[](std::size_t idx)
Iterator_t(std::size_t index, TTreeReaderArray *array)
Construct iterator.
TTreeReaderValueBase & operator=(const TTreeReaderValueBase &)
Copy-assign.
virtual const char * GetDerivedTypeName() const
TTreeReaderValueBase::EReadStatus fReadStatus
Iterator_t(std::size_t index, const TTreeReaderArray *array)
Construct iterator from a const TTreeReaderArray.
bool GetBranchAndLeaf(TBranch *&branch, TLeaf *&myLeaf, TDictionary *&branchActualType)
Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
const T & At(std::size_t idx) const
typename std::conditional< std::is_const< ReaderArrayType >::value, const T *, T * >::type pointer
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:158
bool operator!=(const Iterator_t &other) const
bool operator>=(const Iterator_t &other) const
Iterator_t()
Default ctor: constructs a past-the-end iterator.
std::size_t fSize
Size of the TTreeReaderArray.
const T & operator[](std::size_t idx) const
Iterator_t operator--(int)
Post-decrement operator.
std::ptrdiff_t operator-(const Iterator_t &other) const
virtual EReadStatus GetReadStatus() const
void * UntypedAt(std::size_t idx) const
Extracts array data from a TTree.
std::size_t fIndex
Current index in the array.
Random access iterator to the elements of a TTreeReaderArray.
int type
Definition: TGX11.cxx:120
Iterator_t & operator++()
Pre-increment operator.
#define R__TTreeReaderArray_TypeString(T)
const_iterator cbegin() const
Iterator_t & operator-=(std::ptrdiff_t n)
const_iterator end() const
TVirtualCollectionReader * fImpl
bool operator==(const Iterator_t &other) const
Iterator_t< TTreeReaderArray< Int_t > > iterator
virtual void * At(Detail::TBranchProxy *, size_t)=0
friend auto operator+(std::ptrdiff_t n, const Iterator_t &it) -> decltype(it+n)
A TTree is a list of TBranches.
Definition: TBranch.h:62
bool operator<(const Iterator_t &other) const
const Int_t n
Definition: legend1.C:16
Iterator_t< const TTreeReaderArray< Int_t > > const_iterator
void SetImpl(TBranch *branch, TLeaf *myLeaf)
Create the TVirtualCollectionReader object for our branch.
const_iterator cend() const
virtual size_t GetSize(Detail::TBranchProxy *)=0