11 #ifndef ROOT_RCUSTOMCOLUMN
12 #define ROOT_RCUSTOMCOLUMN
24 #include <type_traits>
33 using namespace ROOT::TypeTraits;
36 namespace CustomColExtraArgs {
39 struct SlotAndEntry{};
43 template <
typename F,
typename ExtraArgsTag = CustomColExtraArgs::None>
44 class RCustomColumn final :
public RCustomColumnBase {
46 using NoneTag = CustomColExtraArgs::None;
47 using SlotTag = CustomColExtraArgs::Slot;
48 using SlotAndEntryTag = CustomColExtraArgs::SlotAndEntry;
50 using FunParamTypes_t =
typename CallableTraits<F>::arg_types;
51 using ColumnTypesTmp_t =
52 RDFInternal::RemoveFirstParameterIf_t<std::is_same<ExtraArgsTag, SlotTag>::value, FunParamTypes_t>;
54 RDFInternal::RemoveFirstTwoParametersIf_t<std::is_same<ExtraArgsTag, SlotAndEntryTag>::value, ColumnTypesTmp_t>;
55 using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;
56 using ret_type =
typename CallableTraits<F>::ret_type;
58 using ValuesPerSlot_t =
59 typename std::conditional<std::is_same<ret_type, bool>::value, std::deque<ret_type>, std::vector<ret_type>>::type;
62 const ColumnNames_t fColumnNames;
63 ValuesPerSlot_t fLastResults;
65 std::vector<RDFInternal::RDFValueTuple_t<ColumnTypes_t>> fValues;
68 std::array<bool, ColumnTypes_t::list_size> fIsCustomColumn;
70 template <std::size_t... S,
typename... BranchTypes>
71 void UpdateHelper(
unsigned int slot, Long64_t entry, std::index_sequence<S...>, TypeList<BranchTypes...>, NoneTag)
73 fLastResults[slot] = fExpression(std::get<S>(fValues[slot]).Get(entry)...);
79 template <std::size_t... S,
typename... BranchTypes>
80 void UpdateHelper(
unsigned int slot, Long64_t entry, std::index_sequence<S...>, TypeList<BranchTypes...>, SlotTag)
82 fLastResults[slot] = fExpression(slot, std::get<S>(fValues[slot]).Get(entry)...);
88 template <std::size_t... S,
typename... BranchTypes>
90 UpdateHelper(
unsigned int slot, Long64_t entry, std::index_sequence<S...>, TypeList<BranchTypes...>, SlotAndEntryTag)
92 fLastResults[slot] = fExpression(slot, entry, std::get<S>(fValues[slot]).Get(entry)...);
99 RCustomColumn(RLoopManager *lm, std::string_view name, F &&expression,
const ColumnNames_t &columns,
100 unsigned int nSlots,
const RDFInternal::RBookedCustomColumns &customColumns,
bool isDSColumn =
false)
101 : RCustomColumnBase(lm, name, nSlots, isDSColumn, customColumns), fExpression(std::forward<F>(expression)),
102 fColumnNames(columns), fLastResults(fNSlots), fValues(fNSlots), fIsCustomColumn()
104 const auto nColumns = fColumnNames.size();
105 for (
auto i = 0u; i < nColumns; ++i)
106 fIsCustomColumn[i] = fCustomColumns.HasName(fColumnNames[i]);
109 RCustomColumn(
const RCustomColumn &) =
delete;
110 RCustomColumn &operator=(
const RCustomColumn &) =
delete;
112 void InitSlot(TTreeReader *r,
unsigned int slot)
final
114 if (!fIsInitialized[slot]) {
115 fIsInitialized[slot] =
true;
116 RDFInternal::InitRDFValues(slot, fValues[slot], r, fColumnNames, fCustomColumns, TypeInd_t(), fIsCustomColumn);
120 void *GetValuePtr(
unsigned int slot)
final {
return static_cast<void *
>(&fLastResults[slot]); }
122 void Update(
unsigned int slot, Long64_t entry)
final
124 if (entry != fLastCheckedEntry[slot]) {
126 UpdateHelper(slot, entry, TypeInd_t(), ColumnTypes_t(), ExtraArgsTag{});
127 fLastCheckedEntry[slot] = entry;
131 const std::type_info &GetTypeId()
const
133 return fIsDataSourceColumn ?
typeid(
typename std::remove_pointer<ret_type>::type) :
typeid(ret_type);
136 void ClearValueReaders(
unsigned int slot)
final
138 if (fIsInitialized[slot]) {
139 RDFInternal::ResetRDFValueTuple(fValues[slot], TypeInd_t());
140 fIsInitialized[slot] =
false;
149 #endif // ROOT_RCUSTOMCOLUMN