1414
1515#include " RColumnReaderBase.hxx"
1616#include < ROOT/RVec.hxx>
17+ #include " ROOT/RDF/Utils.hxx"
1718#include < Rtypes.h> // Long64_t, R__CLING_PTRCHECK
1819#include < TTreeReader.h>
1920#include < TTreeReaderValue.h>
2223#include < array>
2324#include < memory>
2425#include < string>
26+ #include < cstddef>
2527
2628namespace ROOT {
2729namespace Internal {
@@ -30,13 +32,13 @@ namespace RDF {
3032// / RTreeColumnReader specialization for TTree values read via TTreeReaderValues
3133template <typename T>
3234class R__CLING_PTRCHECK (off) RTreeColumnReader final : public ROOT::Detail::RDF::RColumnReaderBase {
33- std::unique_ptr<TTreeReaderValue<T> > fTreeValue ;
35+ std::unique_ptr<TTreeReaderUntypedValue > fTreeValue ;
3436
3537 void *GetImpl (Long64_t) final { return fTreeValue ->Get (); }
3638public:
3739 // / Construct the RTreeColumnReader. Actual initialization is performed lazily by the Init method.
3840 RTreeColumnReader (TTreeReader &r, const std::string &colName)
39- : fTreeValue (std::make_unique<TTreeReaderValue<T>> (r, colName.c_str ()))
41+ : fTreeValue (std::make_unique<TTreeReaderUntypedValue> (r, colName.c_str (), ROOT::Internal::RDF::TypeID2TypeName ( typeid (T) )))
4042 {
4143 }
4244};
@@ -59,10 +61,12 @@ public:
5961// / TTreeReaderArrays are used whenever the RDF column type is RVec<T>.
6062template <typename T>
6163class R__CLING_PTRCHECK (off) RTreeColumnReader<RVec<T>> final : public ROOT::Detail::RDF::RColumnReaderBase {
62- std::unique_ptr<TTreeReaderArray<T>> fTreeArray ;
64+ std::unique_ptr<TTreeReaderUntypedArray> fTreeArray ;
65+
66+ using Byte_t = std::byte;
6367
6468 // / We return a reference to this RVec to clients, to guarantee a stable address and contiguous memory layout.
65- RVec<T > fRVec ;
69+ RVec<Byte_t > fRVec ;
6670
6771 Long64_t fLastEntry = -1 ;
6872
@@ -86,11 +90,10 @@ class R__CLING_PTRCHECK(off) RTreeColumnReader<RVec<T>> final : public ROOT::Det
8690 // trigger loading of the contents of the TTreeReaderArray
8791 // the address of the first element in the reader array is not necessarily equal to
8892 // the address returned by the GetAddress method
89- auto readerArrayAddr = &readerArray.At (0 );
90- RVec<T> rvec (readerArrayAddr, readerArraySize);
93+ RVec<Byte_t> rvec (readerArray.At (0 ), readerArraySize);
9194 swap (fRVec , rvec);
9295 } else {
93- RVec<T > emptyVec{};
96+ RVec<Byte_t > emptyVec{};
9497 swap (fRVec , emptyVec);
9598 }
9699 } else {
@@ -107,10 +110,17 @@ class R__CLING_PTRCHECK(off) RTreeColumnReader<RVec<T>> final : public ROOT::Det
107110 (void )fCopyWarningPrinted ;
108111#endif
109112 if (readerArraySize > 0 ) {
110- RVec<T> rvec (readerArray.begin (), readerArray.end ());
111- swap (fRVec , rvec);
113+ // Array is not contiguous, make a full copy of it.
114+ fRVec = RVec<Byte_t>();
115+ fRVec .reserve (readerArraySize * sizeof (T));
116+ for (std::size_t i{0 }; i < readerArraySize; i++)
117+ {
118+ auto val = readerArray.At (i);
119+ std::copy (val, val + sizeof (T), std::back_inserter (fRVec ));
120+ }
121+ fRVec .resize (readerArraySize);
112122 } else {
113- RVec<T > emptyVec{};
123+ RVec<Byte_t > emptyVec{};
114124 swap (fRVec , emptyVec);
115125 }
116126 }
@@ -120,7 +130,7 @@ class R__CLING_PTRCHECK(off) RTreeColumnReader<RVec<T>> final : public ROOT::Det
120130
121131public:
122132 RTreeColumnReader (TTreeReader &r, const std::string &colName)
123- : fTreeArray (std::make_unique<TTreeReaderArray<T>> (r, colName. c_str ( )))
133+ : fTreeArray (std::make_unique<TTreeReaderUntypedArray> (r, colName, ROOT::Internal::RDF::TypeID2TypeName ( typeid (T) )))
124134 {
125135 }
126136};
@@ -131,10 +141,12 @@ public:
131141template <>
132142class R__CLING_PTRCHECK (off) RTreeColumnReader<RVec<bool >> final : public ROOT::Detail::RDF::RColumnReaderBase {
133143
134- std::unique_ptr<TTreeReaderArray<bool >> fTreeArray ;
144+ using Byte_t = std::byte;
145+
146+ std::unique_ptr<TTreeReaderUntypedArray> fTreeArray ;
135147
136148 // / We return a reference to this RVec to clients, to guarantee a stable address and contiguous memory layout
137- RVec<bool > fRVec ;
149+ RVec<Byte_t > fRVec ;
138150
139151 // We always copy the contents of TTreeReaderArray<bool> into an RVec<bool> (never take a view into the memory
140152 // buffer) because the underlying memory buffer might be the one of a std::vector<bool>, which is not a contiguous
@@ -146,19 +158,25 @@ class R__CLING_PTRCHECK(off) RTreeColumnReader<RVec<bool>> final : public ROOT::
146158 auto &readerArray = *fTreeArray ;
147159 const auto readerArraySize = readerArray.GetSize ();
148160 if (readerArraySize > 0 ) {
149- // always perform a copy
150- RVec<bool > rvec (readerArray.begin (), readerArray.end ());
151- swap (fRVec , rvec);
161+ // Always perform a copy
162+ fRVec = RVec<Byte_t>();
163+ fRVec .reserve (readerArraySize * sizeof (bool ));
164+ for (std::size_t i{0 }; i < readerArraySize; i++)
165+ {
166+ auto val = readerArray.At (i);
167+ std::copy (val, val + sizeof (bool ), std::back_inserter (fRVec ));
168+ }
169+ fRVec .resize (readerArraySize);
152170 } else {
153- RVec<bool > emptyVec{};
171+ RVec<Byte_t > emptyVec{};
154172 swap (fRVec , emptyVec);
155173 }
156174 return &fRVec ;
157175 }
158176
159177public:
160178 RTreeColumnReader (TTreeReader &r, const std::string &colName)
161- : fTreeArray (std::make_unique<TTreeReaderArray< bool >> (r, colName.c_str ()))
179+ : fTreeArray (std::make_unique<TTreeReaderUntypedArray> (r, colName.c_str (), ROOT::Internal::RDF::TypeID2TypeName ( typeid ( bool ) )))
162180 {
163181 }
164182};
@@ -168,32 +186,18 @@ public:
168186// / This specialization is used when the requested type for reading is std::array
169187template <typename T, std::size_t N>
170188class R__CLING_PTRCHECK (off) RTreeColumnReader<std::array<T, N>> final : public ROOT::Detail::RDF::RColumnReaderBase {
171- std::unique_ptr<TTreeReaderArray<T>> fTreeArray ;
172-
173- // / We return a reference to this RVec to clients, to guarantee a stable address and contiguous memory layout
174- RVec<T> fArray ;
189+ std::unique_ptr<TTreeReaderUntypedArray> fTreeArray ;
175190
176191 Long64_t fLastEntry = -1 ;
177192
178- void *GetImpl (Long64_t entry ) final
193+ void *GetImpl (Long64_t) final
179194 {
180- if (entry == fLastEntry )
181- return fArray .data ();
182-
183- // This is a non-owning view on the contents of the TTreeReaderArray
184- RVec<T> view{&fTreeArray ->At (0 ), fTreeArray ->GetSize ()};
185- swap (fArray , view);
186-
187- fLastEntry = entry;
188- // The data member of this class is an RVec, to avoid an extra copy
189- // but we need to return the array buffer as the reader expects
190- // a std::array
191- return fArray .data ();
195+ return fTreeArray ->At (0 );
192196 }
193197
194198public:
195199 RTreeColumnReader (TTreeReader &r, const std::string &colName)
196- : fTreeArray (std::make_unique<TTreeReaderArray<T>> (r, colName.c_str ()))
200+ : fTreeArray (std::make_unique<TTreeReaderUntypedArray> (r, colName.c_str (), ROOT::Internal::RDF::TypeID2TypeName ( typeid (T) )))
197201 {
198202 }
199203};
0 commit comments