Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTreeReaderArray.h
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Axel Naumann, 2010-08-02
3// Author: Vincenzo Eduardo Padulano CERN 02/2025
4
5/*************************************************************************
6 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_TTreeReaderArray
14#define ROOT_TTreeReaderArray
15
16#include "TTreeReaderValue.h"
17#include "TTreeReaderUtils.h"
18#include <type_traits>
19#include <cstddef>
20
21namespace ROOT {
22namespace Internal {
23
24/** \class TTreeReaderArrayBase
25Base class of TTreeReaderArray.
26*/
27
30 int fArrayNDims{}; // Number of dimensions of the n-dim array
31 int fArrayCumulativeLength{}; // Total length of the n-dim array as if it were flattened
32 int fTDataTypeCode{}; // A number representing the value type of the array, queried via TDataType.
33 std::array<int, 5> fArrayDims{}; // Length of each dimension of the n-dim array. Max 5 dimensions, aligned with
34 // TStreamerElement::fMaxIndex
35 };
36 StreamerElementArrayInfo FillStreamerElementArrayInfo(TStreamerElement *elem);
37
38public:
43
44 std::size_t GetSize() const { return fImpl ? fImpl->GetSize(GetProxy()) : 0; }
45 bool IsEmpty() const { return !GetSize(); }
46
47 EReadStatus GetReadStatus() const override { return fImpl ? fImpl->fReadStatus : kReadError; }
48
49 bool IsContiguous() const { return fImpl->IsContiguous(GetProxy()); }
50
51 /// Returns the `sizeof` of the collection value type. Returns 0 in case the value size could not be retrieved.
52 std::size_t GetValueSize() const { return fImpl ? fImpl->GetValueSize(GetProxy()) : 0; }
53
54protected:
55 void *UntypedAt(std::size_t idx) const { return fImpl->At(GetProxy(), idx); }
56 void CreateProxy() override;
61 StreamerElementArrayInfo &arrInfo);
62
63 std::unique_ptr<TVirtualCollectionReader> fImpl; // Common interface to collections
64
65 // FIXME: re-introduce once we have ClassDefInline!
66 // ClassDefOverride(TTreeReaderArrayBase, 0);//Accessor to member of an object stored in a collection
67};
68
71
72public:
73 TTreeReaderUntypedArray(TTreeReader &tr, std::string_view branchName, std::string_view innerTypeName)
74 : TTreeReaderArrayBase(&tr, branchName.data(), TDictionary::GetDictionary(innerTypeName.data())),
75 fArrayElementTypeName(innerTypeName)
76 {
77 }
78
79 std::byte *At(std::size_t idx) const { return reinterpret_cast<std::byte *>(UntypedAt(idx)); }
80
81protected:
82 const char *GetDerivedTypeName() const final { return fArrayElementTypeName.c_str(); }
83};
84
85} // namespace Internal
86} // namespace ROOT
87
88// clang-format off
89/**
90 * \class TTreeReaderArray
91 * \ingroup treeplayer
92 * \brief An interface for reading collections stored in ROOT columnar datasets
93 *
94 * The TTreeReaderArray is a type-safe tool to be used in association with a TTreeReader
95 * to access the collections stored in TTree, TNtuple and TChain datasets.
96 * In order to access values which are not collections, the TTreeReaderValue class can
97 * be used.
98 *
99 * See the documentation of TTreeReader for more details and examples.
100*/
101// clang-format on
102
103template <typename T>
105 // R__CLING_PTRCHECK is disabled because pointer / types are checked by CreateProxy().
106
107public:
108 /// Random access iterator to the elements of a TTreeReaderArray.
109 // The template parameter is there to allow distinguishing between the `const` and `non-const` cases.
110 template <typename ReaderArrayType>
112 public:
113 // iterators must define the following types
114 using iterator_category = std::random_access_iterator_tag;
115 using value_type = T;
116 using difference_type = std::ptrdiff_t;
117 using pointer = std::conditional_t<std::is_const<ReaderArrayType>::value, const T *, T *>;
118 using reference = std::conditional_t<std::is_const<ReaderArrayType>::value, const T &, T &>;
119
120 private:
121 TTreeReaderArray *fArray; ///< The array iterated over; nullptr if invalid/past-the-end.
122 std::size_t fIndex; ///< Current index in the array.
123 std::size_t fSize; ///< Size of the TTreeReaderArray
124 public:
125 /// Default ctor: constructs a past-the-end iterator
126 Iterator_t() : fArray(nullptr), fIndex(0u), fSize(0u) {}
127
128 /// Construct iterator
129 Iterator_t(std::size_t index, TTreeReaderArray *array)
130 : fArray(array), fIndex(index), fSize(fArray ? fArray->GetSize() : 0u)
131 {
132 if (fIndex >= fSize)
133 fArray = nullptr; // invalidate iterator
134 }
135
136 /// Construct iterator from a const TTreeReaderArray
137 Iterator_t(std::size_t index, const TTreeReaderArray *array)
139 {
140 }
141
142 Iterator_t(Iterator_t &&) = default;
143 Iterator_t(const Iterator_t &) = default;
145 Iterator_t &operator=(const Iterator_t &) = default;
146
148 {
149 R__ASSERT(fArray && "invalid iterator!");
150 return fArray->At(fIndex);
151 }
152
153 pointer operator->() const { return IsValid() ? &fArray->At(fIndex) : nullptr; }
154
155 bool operator==(const Iterator_t &other) const
156 {
157 // Follow C++14 requiring two past-the-end iterators to be equal.
158 if (!IsValid() && !other.IsValid())
159 return true;
160 return fArray == other.fArray && fIndex == other.fIndex;
161 }
162
163 bool operator!=(const Iterator_t &other) const { return !(*this == other); }
164
165 /// Pre-increment operator
167 {
168 if (IsValid())
169 ++fIndex;
170 if (fIndex >= fSize)
171 fArray = nullptr; // invalidate iterator
172 return *this;
173 }
174
175 /// Post-increment operator
177 {
178 auto ret = *this;
179 this->operator++();
180 return ret;
181 }
182
183 /// Pre-decrement operator
185 {
186 if (fIndex == 0u)
187 fArray = nullptr; // invalidate iterator
188 else
189 --fIndex;
190 return *this;
191 }
192
193 /// Post-decrement operator
195 {
196 auto ret = *this;
197 this->operator--();
198 return ret;
199 }
200
201 Iterator_t operator+(std::ptrdiff_t n) const { return Iterator_t(fIndex + n, fArray); }
202 friend auto operator+(std::ptrdiff_t n, const Iterator_t &it) -> decltype(it + n) { return it + n; }
203
204 Iterator_t operator-(std::ptrdiff_t n) const
205 {
206 const auto index = std::ptrdiff_t(fIndex);
207 const auto newIndex = index >= n ? index - n : std::numeric_limits<decltype(fIndex)>::max();
208 return Iterator_t(newIndex, fArray);
209 }
210
211 std::ptrdiff_t operator-(const Iterator_t &other) const { return fIndex - other.fIndex; }
212
213 Iterator_t &operator+=(std::ptrdiff_t n) { return (*this = *this + n); }
214
215 Iterator_t &operator-=(std::ptrdiff_t n) { return (*this = *this - n); }
216
217 bool operator<(const Iterator_t &other) const { return fIndex < other.fIndex; }
218 bool operator>(const Iterator_t &other) const { return fIndex > other.fIndex; }
219 bool operator<=(const Iterator_t &other) const { return !(*this > other); }
220 bool operator>=(const Iterator_t &other) const { return !(*this < other); }
221
222 reference operator[](std::size_t index) const { return *(*this + index); }
223
224 operator pointer() { return &fArray->At(fIndex); }
225
226 bool IsValid() const { return fArray != nullptr; }
227 };
228
231
232 /// Create an array reader of branch "branchname" for TTreeReader "tr".
234 : TTreeReaderArrayBase(&tr, branchname, TDictionary::GetDictionary(typeid(T)))
235 {
236 }
237
238 T &At(std::size_t idx) { return *static_cast<T *>(UntypedAt(idx)); }
239 const T &At(std::size_t idx) const { return *static_cast<T *>(UntypedAt(idx)); }
240 T &operator[](std::size_t idx) { return At(idx); }
241 const T &operator[](std::size_t idx) const { return At(idx); }
242
243 iterator begin() { return iterator(0u, this); }
244 iterator end() { return iterator(GetSize(), this); }
245 const_iterator begin() const { return cbegin(); }
246 const_iterator end() const { return cend(); }
247 const_iterator cbegin() const { return const_iterator(0u, this); }
248 const_iterator cend() const { return const_iterator(GetSize(), this); }
249
250protected:
251#define R__TTreeReaderArray_TypeString(T) #T
252 const char *GetDerivedTypeName() const override { return R__TTreeReaderArray_TypeString(T); }
253#undef R__TTreeReaderArray_TypeString
254 // FIXME: re-introduce once we have ClassDefTInline!
255 // ClassDefT(TTreeReaderArray, 0);//Accessor to member of an object stored in a collection
256};
257
258namespace cling {
259template <typename T>
260std::string printValue(TTreeReaderArray<T> *val)
261{
262 return printValue(static_cast<ROOT::Internal::TTreeReaderValueBase *>(val));
263}
264} // namespace cling
265
266#endif // ROOT_TTreeReaderArray
dim_t fSize
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
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
#define R__TTreeReaderArray_TypeString(T)
Base class of TTreeReaderArray.
void CreateProxy() override
Create the proxy object for our branch.
std::unique_ptr< TVirtualCollectionReader > fImpl
bool GetBranchAndLeaf(TBranch *&branch, TLeaf *&myLeaf, TDictionary *&branchActualType, bool suppressErrorsForMissingBranch=false)
Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
StreamerElementArrayInfo FillStreamerElementArrayInfo(TStreamerElement *elem)
TTreeReaderArrayBase(TTreeReader *reader, const char *branchname, TDictionary *dict)
void * UntypedAt(std::size_t idx) const
EReadStatus GetReadStatus() const override
std::size_t GetValueSize() const
Returns the sizeof of the collection value type. Returns 0 in case the value size could not be retrie...
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict, StreamerElementArrayInfo &arrInfo)
Access a branch's collection content (not the collection itself) through a proxy.
void SetImpl(TBranch *branch, TLeaf *myLeaf)
Create the TVirtualCollectionReader object for our branch.
std::byte * At(std::size_t idx) const
TTreeReaderUntypedArray(TTreeReader &tr, std::string_view branchName, std::string_view innerTypeName)
const char * GetDerivedTypeName() const final
Base class of TTreeReaderValue.
Detail::TBranchProxy * GetProxy() const
A TTree is a list of TBranches.
Definition TBranch.h:93
This class defines an abstract interface that must be implemented by all classes that contain diction...
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
Describe one element (data member) to be Streamed.
Basic string class.
Definition TString.h:138
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.
std::size_t fSize
Size of the TTreeReaderArray.
Iterator_t & operator-=(std::ptrdiff_t n)
Iterator_t & operator=(Iterator_t &&)=default
std::conditional_t< std::is_const< ReaderArrayType >::value, const T *, T * > pointer
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
std::conditional_t< std::is_const< ReaderArrayType >::value, const T &, T & > reference
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
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.
const char * GetDerivedTypeName() const override
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
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 columnar datasets such as TTree,...
Definition TTreeReader.h:46
const Int_t n
Definition legend1.C:16