Skip to content

Commit 515c5c7

Browse files
committed
refactor inputsFromArgs; update concepts
1 parent 43223a4 commit 515c5c7

File tree

3 files changed

+86
-46
lines changed

3 files changed

+86
-46
lines changed

Framework/Core/include/Framework/ASoA.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ template <aod::is_aod_hash L, aod::is_aod_hash D, aod::is_origin_hash O, typenam
10091009
class Table;
10101010

10111011
template <typename T>
1012-
concept is_table = framework::specialization_of_template<soa::Table, T> || framework::base_of_template<soa::Table, T>;
1012+
concept is_table = framework::specialization_of_template<soa::Table, std::decay_t<T>> || framework::base_of_template<soa::Table, std::decay_t<T>>;
10131013

10141014
/// Similar to a pair but not a pair, to avoid
10151015
/// exposing the second type everywhere.
@@ -1232,7 +1232,7 @@ struct ArrowHelpers {
12321232

12331233
//! Helper to check if a type T is an iterator
12341234
template <typename T>
1235-
concept is_iterator = framework::base_of_template<TableIterator, T> || framework::specialization_of_template<TableIterator, T>;
1235+
concept is_iterator = framework::base_of_template<TableIterator, std::decay_t<T>> || framework::specialization_of_template<TableIterator, std::decay_t<T>>;
12361236

12371237
template <typename T>
12381238
concept with_originals = requires {

Framework/Core/include/Framework/AnalysisTask.h

Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -140,46 +140,82 @@ struct AnalysisDataProcessorBuilder {
140140
DataSpecUtils::updateInputList(inputs, InputSpec{o2::aod::label<R>(), o2::aod::origin<R>(), aod::description(o2::aod::signature<R>()), R.version, Lifetime::Timeframe, inputMetadata});
141141
}
142142

143-
template <typename R, typename C, typename... Args>
144-
static void inputsFromArgs(R (C::*)(Args...), const char* name, bool value, std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>& eInfos, std::vector<StringPair>& bk, std::vector<StringPair>& bku) requires(std::is_lvalue_reference_v<Args>&&...)
143+
/// helpers to append expression information for a single argument
144+
template <soa::is_table A>
145+
requires(!soa::is_filtered_table<std::decay_t<A>>)
146+
static void addExpression(int, uint32_t, std::vector<ExpressionInfo>&)
145147
{
146-
// update grouping cache
147-
if constexpr (soa::is_iterator<std::decay_t<framework::pack_element_t<0, framework::pack<Args...>>>>) {
148-
addGroupingCandidates<Args...>(bk, bku);
149-
}
148+
}
150149

151-
// populate input list and expression infos
152-
int ai = -1;
153-
constexpr auto hash = o2::framework::TypeIdHelpers::uniqueId<R (C::*)(Args...)>();
154-
([&name, &value, &eInfos, &inputs, &hash, &ai]() mutable {
150+
template <soa::is_filtered_table A>
151+
static void addExpression(int ai, uint32_t hash, std::vector<ExpressionInfo>& eInfos)
152+
{
153+
auto fields = soa::createFieldsFromColumns(typename std::decay_t<A>::persistent_columns_t{});
154+
eInfos.emplace_back(ai, hash, std::decay_t<A>::hashes(), std::make_shared<arrow::Schema>(fields));
155+
}
156+
157+
template <soa::is_iterator A>
158+
static void addExpression(int ai, uint32_t hash, std::vector<ExpressionInfo>& eInfos)
159+
{
160+
addExpression<typename std::decay_t<A>::parent_t>(ai, hash, eInfos);
161+
}
162+
163+
/// helpers to append InputSpec for a single argument
164+
template <soa::is_table A>
165+
static void addInput(const char* name, bool value, std::vector<InputSpec>& inputs)
166+
{
167+
[&name, &value, &inputs]<size_t N, std::array<soa::TableRef, N> refs, size_t... Is>(std::index_sequence<Is...>) mutable {
168+
(addOriginalRef<refs[Is]>(name, value, inputs), ...);
169+
}.template operator()<A::originals.size(), std::decay_t<A>::originals>(std::make_index_sequence<std::decay_t<A>::originals.size()>());
170+
}
171+
172+
template <soa::is_iterator A>
173+
static void addInput(const char* name, bool value, std::vector<InputSpec>& inputs)
174+
{
175+
addInput<typename std::decay_t<A>::parent_t>(name, value, inputs);
176+
}
177+
178+
/// helper to append the inputs and expression information for normalized arguments
179+
template <soa::is_table A, soa::is_table... As>
180+
static void addInputsAndExpressions(uint32_t hash, const char* name, bool value, std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>& eInfos)
181+
{
182+
int ai = 0;
183+
addExpression<std::decay_t<A>>(ai, hash, eInfos);
184+
addInput<std::decay_t<A>>(name, value, inputs);
185+
186+
([&ai, &hash, &eInfos, &name, &value, &inputs]() mutable {
155187
++ai;
156-
using T = std::decay_t<Args>;
157-
if constexpr (is_enumeration<T>) {
158-
std::vector<ConfigParamSpec> inputMetadata;
159-
// FIXME: for the moment we do not support begin, end and step.
160-
DataSpecUtils::updateInputList(inputs, InputSpec{"enumeration", "DPL", "ENUM", 0, Lifetime::Enumeration, inputMetadata});
161-
} else {
162-
// populate expression infos
163-
if constexpr (soa::is_filtered_table<T>) {
164-
auto fields = soa::createFieldsFromColumns(typename T::persistent_columns_t{});
165-
eInfos.emplace_back(ai, hash, T::hashes(), std::make_shared<arrow::Schema>(fields));
166-
} else if constexpr (soa::is_filtered_iterator<T>) {
167-
auto fields = soa::createFieldsFromColumns(typename T::parent_t::persistent_columns_t{});
168-
eInfos.emplace_back(ai, hash, T::parent_t::hashes(), std::make_shared<arrow::Schema>(fields));
169-
}
170-
// add inputs from the originals
171-
auto adder = [&name, &value, &inputs]<size_t N, std::array<soa::TableRef, N> refs, size_t... Is>(std::index_sequence<Is...>) mutable {
172-
(addOriginalRef<refs[Is]>(name, value, inputs), ...);
173-
};
174-
if constexpr (soa::is_table<T> || soa::is_filtered_table<T>) {
175-
adder.template operator()<T::originals.size(), T::originals>(std::make_index_sequence<T::originals.size()>());
176-
} else if constexpr (soa::is_iterator<T> || soa::is_filtered_iterator<T>) {
177-
adder.template operator()<T::parent_t::originals.size(), T::parent_t::originals>(std::make_index_sequence<T::parent_t::originals.size()>());
178-
}
179-
}
180-
return true;
181-
}() &&
182-
...);
188+
using T = std::decay_t<As>;
189+
addExpression<T>(ai, hash, eInfos);
190+
addInput<T>(name, value, inputs);
191+
}(), ...);
192+
}
193+
194+
/// helper to parse the process arguments
195+
/// 1. enumeration (must be a sole argument)
196+
template <typename R, typename C, is_enumeration A>
197+
static void inputsFromArgs(R (C::*)(A), const char* /*name*/, bool /*value*/, std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>&, std::vector<StringPair>&, std::vector<StringPair>&)
198+
{
199+
std::vector<ConfigParamSpec> inputMetadata;
200+
// FIXME: for the moment we do not support begin, end and step.
201+
DataSpecUtils::updateInputList(inputs, InputSpec{"enumeration", "DPL", "ENUM", 0, Lifetime::Enumeration, inputMetadata});
202+
}
203+
204+
/// 2. grouping case - 1st argument is an iterator
205+
template <typename R, typename C, soa::is_iterator A, soa::is_table... Args>
206+
static void inputsFromArgs(R (C::*)(A, Args...), const char* name, bool value, std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>& eInfos, std::vector<StringPair>& bk, std::vector<StringPair>& bku) requires(std::is_lvalue_reference_v<A> && (std::is_lvalue_reference_v<Args>&&...))
207+
{
208+
addGroupingCandidates<A, Args...>(bk, bku);
209+
constexpr auto hash = o2::framework::TypeIdHelpers::uniqueId<R (C::*)(Args...)>();
210+
addInputsAndExpressions<typename std::decay_t<A>::parent_t, Args...>(hash, name, value, inputs, eInfos);
211+
}
212+
213+
/// 3. generic case
214+
template <typename R, typename C, soa::is_table A, soa::is_table... Args>
215+
static void inputsFromArgs(R (C::*)(A, Args...), const char* name, bool value, std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>& eInfos, std::vector<StringPair>&, std::vector<StringPair>&) requires(std::is_lvalue_reference_v<A> && (std::is_lvalue_reference_v<Args>&&...))
216+
{
217+
constexpr auto hash = o2::framework::TypeIdHelpers::uniqueId<R (C::*)(Args...)>();
218+
addInputsAndExpressions<A, Args...>(hash, name, value, inputs, eInfos);
183219
}
184220

185221
template <soa::TableRef R>
@@ -498,19 +534,19 @@ DataProcessorSpec adaptAnalysisTask(ConfigContext const& ctx, Args&&... args)
498534
homogeneous_apply_refs([&inputs](auto& x) { return ConditionManager<std::decay_t<decltype(x)>>::appendCondition(inputs, x); }, *task.get());
499535

500536
/// parse process functions defined by corresponding configurables
501-
if constexpr (requires { AnalysisDataProcessorBuilder::inputsFromArgs(&T::process, "default", true, inputs, expressionInfos, bindingsKeys, bindingsKeysUnsorted); }) {
537+
if constexpr (requires { &T::process; }) {
502538
AnalysisDataProcessorBuilder::inputsFromArgs(&T::process, "default", true, inputs, expressionInfos, bindingsKeys, bindingsKeysUnsorted);
503539
}
504540
homogeneous_apply_refs(
505-
[name = name_str, &expressionInfos, &inputs, &bindingsKeys, &bindingsKeysUnsorted](auto& x) {
506-
using D = std::decay_t<decltype(x)>;
507-
if constexpr (base_of_template<ProcessConfigurable, D>) {
541+
overloaded {
542+
[name = name_str, &expressionInfos, &inputs, &bindingsKeys, &bindingsKeysUnsorted](framework::is_process_configurable auto& x) mutable {
508543
// this pushes (argumentIndex,processHash,schemaPtr,nullptr) into expressionInfos for arguments that are Filtered/filtered_iterators
509544
AnalysisDataProcessorBuilder::inputsFromArgs(x.process, (name + "/" + x.name).c_str(), x.value, inputs, expressionInfos, bindingsKeys, bindingsKeysUnsorted);
510545
return true;
511-
}
512-
return false;
513-
},
546+
},
547+
[](auto&){
548+
return false;
549+
}},
514550
*task.get());
515551

516552
// add preslice declarations to slicing cache definition

Framework/Core/include/Framework/Configurable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#ifndef O2_FRAMEWORK_CONFIGURABLE_H_
1212
#define O2_FRAMEWORK_CONFIGURABLE_H_
1313
#include "Framework/ConfigurableKinds.h"
14+
#include "Framework/Traits.h"
1415
#include <string>
1516
#include <vector>
1617
namespace o2::framework
@@ -95,6 +96,9 @@ struct ProcessConfigurable : Configurable<bool, ConfigParamKind::kProcessFlag> {
9596
(As...);
9697
};
9798

99+
template <typename T>
100+
concept is_process_configurable = base_of_template<ProcessConfigurable, T>;
101+
98102
#define PROCESS_SWITCH(_Class_, _Name_, _Help_, _Default_) \
99103
decltype(ProcessConfigurable{&_Class_ ::_Name_, #_Name_, _Default_, _Help_}) do##_Name_ = ProcessConfigurable{&_Class_ ::_Name_, #_Name_, _Default_, _Help_};
100104
#define PROCESS_SWITCH_FULL(_Class_, _Method_, _Name_, _Help_, _Default_) \

0 commit comments

Comments
 (0)