11#ifndef ROOT_RCOLUMNVALUE
12#define ROOT_RCOLUMNVALUE
26#include <initializer_list>
69 using TreeReader_t =
typename std::conditional<MustUseRVec_t::value, TTreeReaderArray<ColumnValue_t>,
78 unsigned int fSlot = std::numeric_limits<unsigned int>::max();
100 bool fCopyWarningPrinted =
false;
107 fCustomColumn = customColumn;
110 const auto diffTypes = (0 != strcmp(customColumn->
GetTypeId().name(),
typeid(
T).name()));
111 auto inheritedType = [&](){
113 return colTClass && colTClass->InheritsFrom(TClass::GetClass<T>());
116 if (diffTypes && !inheritedType()) {
119 std::string errMsg =
"RColumnValue: type specified for column \"" +
120 customColumn->
GetName() +
"\" is ";
122 errMsg +=
typeid(
T).
name();
123 errMsg +=
" (extracted from type info)";
127 errMsg +=
" but temporary column has type ";
128 if (colTypeName.empty()) {
131 errMsg +=
" (extracted from type info)";
133 errMsg += colTypeName;
135 throw std::runtime_error(errMsg);
139 fColumnKind = EColumnKind::kDataSource;
140 fDSValuePtr =
static_cast<T **
>(customColumn->
GetValuePtr(slot));
142 fColumnKind = EColumnKind::kCustomColumn;
143 fCustomValuePtr =
static_cast<T *
>(customColumn->
GetValuePtr(slot));
150 fColumnKind = EColumnKind::kTree;
151 fTreeReader = std::make_unique<TreeReader_t>(*
r, bn.c_str());
158 template <typename U = T, typename std::enable_if<!RColumnValue<U>::MustUseRVec_t::value,
int>
::type = 0>
161 if (fColumnKind == EColumnKind::kTree) {
162 return *(fTreeReader->Get());
164 fCustomColumn->
Update(fSlot, entry);
165 return fColumnKind == EColumnKind::kCustomColumn ? *fCustomValuePtr : **fDSValuePtr;
172 template <
typename U =
T,
173 typename std::enable_if<RColumnValue<U>::MustUseRVec_t::value && !std::is_same<U, RVec<bool>>::value,
177 if (fColumnKind == EColumnKind::kTree) {
178 auto &readerArray = *fTreeReader;
185 const auto arrSize = readerArray.GetSize();
188 fStorageType = EStorageType::kContiguous;
189 for (
auto i = 0u; i < arrSize - 1; ++i) {
190 if ((
char *)&readerArray[i + 1] - (
char *)&readerArray[i] !=
sizeof(
typename U::value_type)) {
191 fStorageType = EStorageType::kSparse;
197 const auto readerArraySize = readerArray.GetSize();
198 if (EStorageType::kContiguous == fStorageType ||
200 if (readerArraySize > 0) {
204 auto readerArrayAddr = &readerArray.At(0);
205 T rvec(readerArrayAddr, readerArraySize);
214 if (!fCopyWarningPrinted) {
216 "Branch %s hangs from a non-split branch. A copy is being performed in order "
217 "to properly read the content.",
218 readerArray.GetBranchName());
219 fCopyWarningPrinted =
true;
222 (
void)fCopyWarningPrinted;
224 if (readerArraySize > 0) {
225 T rvec(readerArray.begin(), readerArray.end());
235 fCustomColumn->
Update(fSlot, entry);
236 return fColumnKind == EColumnKind::kCustomColumn ? *fCustomValuePtr : **fDSValuePtr;
245 template <
typename U =
T,
246 typename std::enable_if<RColumnValue<U>::MustUseRVec_t::value && std::is_same<U, RVec<bool>>::value,
250 if (fColumnKind == EColumnKind::kTree) {
251 auto &readerArray = *fTreeReader;
252 const auto readerArraySize = readerArray.GetSize();
253 if (readerArraySize > 0) {
255 T rvec(readerArray.begin(), readerArray.end());
264 fCustomColumn->
Update(fSlot, entry);
265 return fColumnKind == EColumnKind::kCustomColumn ? *fCustomValuePtr : **fDSValuePtr;
279 if (EColumnKind::kTree == fColumnKind) {
288#if __cplusplus < 201703L
289extern template class RColumnValue<int>;
290extern template class RColumnValue<unsigned int>;
291extern template class RColumnValue<char>;
292extern template class RColumnValue<unsigned char>;
293extern template class RColumnValue<float>;
294extern template class RColumnValue<double>;
295extern template class RColumnValue<Long64_t>;
296extern template class RColumnValue<ULong64_t>;
297extern template class RColumnValue<std::vector<int>>;
298extern template class RColumnValue<std::vector<unsigned int>>;
299extern template class RColumnValue<std::vector<char>>;
300extern template class RColumnValue<std::vector<unsigned char>>;
301extern template class RColumnValue<std::vector<float>>;
302extern template class RColumnValue<std::vector<double>>;
303extern template class RColumnValue<std::vector<Long64_t>>;
304extern template class RColumnValue<std::vector<ULong64_t>>;
311template <
typename... BranchTypes>
313 using type = std::tuple<RColumnValue<BranchTypes>...>;
316template <
typename BranchType>
320template <
typename ValueTuple, std::size_t...
S>
324 std::initializer_list<int> expander{(std::get<S>(values).Reset(), 0)...};
void Warning(const char *location, const char *msgfmt,...)
typedef void((*Func_t)())
virtual void Update(unsigned int slot, Long64_t entry)=0
virtual void * GetValuePtr(unsigned int slot)=0
std::string GetName() const
virtual const std::type_info & GetTypeId() const =0
bool IsDataSourceColumn() const
Helper class that updates and returns TTree branches as well as RDataFrame temporary columns.
T * fCustomValuePtr
Non-owning ptrs to the value of a custom column.
T ** fDSValuePtr
Non-owning ptrs to the value of a data-source column.
IsRVec_t< T > MustUseRVec_t
void MakeProxy(TTreeReader *r, const std::string &bn)
std::unique_ptr< TreeReader_t > fTreeReader
Owning ptrs to a TTreeReaderValue or TTreeReaderArray. Only used for Tree columns.
typename std::conditional< MustUseRVec_t::value, TakeFirstParameter_t< T >, T >::type ColumnValue_t
EColumnKind
RColumnValue has a slightly different behaviour whether the column comes from a TTreeReader,...
T & Get(Long64_t entry)
This overload is used to return scalar quantities (i.e. types that are not read into a RVec)
typename std::conditional< MustUseRVec_t::value, TTreeReaderArray< ColumnValue_t >, TTreeReaderValue< ColumnValue_t > >::type TreeReader_t
EStorageType
Enumerator for the different properties of the branch storage in memory.
void SetTmpColumn(unsigned int slot, RCustomColumnBase *customColumn)
RCustomColumnBase * fCustomColumn
Non-owning ptrs to the node responsible for the custom column. Needed when querying custom values.
RVec< ColumnValue_t > fRVec
If MustUseRVec, i.e. we are reading an array, we return a reference to this RVec to clients.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
An interface for reading values stored in ROOT columnar datasets.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
std::string TypeID2TypeName(const std::type_info &id)
Returns the name of a type starting from its type_info An empty string is returned in case of failure...
void ResetRDFValueTuple(std::vector< RTypeErasedColumnValue > &values, std::index_sequence< S... >, ROOT::TypeTraits::TypeList< ColTypes... >)
This overload is specialized to act on RTypeErasedColumnValues instead of RColumnValues.
typename TRDFValueTuple< BranchType >::type RDFValueTuple_t
RooArgSet S(const RooAbsArg &v1)
std::tuple< RColumnValue< BranchTypes >... > type
Lightweight storage for a collection of types.