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