@@ -59,7 +59,7 @@ template <int64_t BEGIN, int64_t END, int64_t STEP>
5959static constexpr bool is_enumeration_v<Enumeration<BEGIN, END, STEP>> = true ;
6060
6161template <typename T>
62- concept is_enumeration = is_enumeration_v<T >;
62+ concept is_enumeration = is_enumeration_v<std:: decay_t <T> >;
6363
6464// Helper struct which builds a DataProcessorSpec from
6565// the contents of an AnalysisTask...
@@ -140,48 +140,84 @@ 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+ }
149+
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+ }
150177
151- // populate input list and expression infos
178+ // / helper to append the inputs and expression information for normalized arguments
179+ template <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+ {
152182 int ai = -1 ;
153- constexpr auto hash = o2::framework::TypeIdHelpers::uniqueId<R (C::*)(Args...)>();
154- ([&name, &value, &eInfos, &inputs, &hash, &ai]() mutable {
183+ ([&ai, &hash, &eInfos, &name, &value, &inputs]() mutable {
155184 ++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- }() &&
185+ using T = std::decay_t <As>;
186+ addExpression<T>(ai, hash, eInfos);
187+ addInput<T>(name, value, inputs);
188+ }(),
182189 ...);
183190 }
184191
192+ // / helper to parse the process arguments
193+ // / 1. enumeration (must be the only argument)
194+ template <typename R, typename C, is_enumeration A>
195+ static void inputsFromArgs (R (C::*)(A), const char* /* name*/ , bool /* value*/ , std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>&, std::vector<StringPair>&, std::vector<StringPair>&)
196+ {
197+ std::vector<ConfigParamSpec> inputMetadata;
198+ // FIXME: for the moment we do not support begin, end and step.
199+ DataSpecUtils::updateInputList (inputs, InputSpec{" enumeration" , " DPL" , " ENUM" , 0 , Lifetime::Enumeration, inputMetadata});
200+ }
201+
202+ // / 2. grouping case - 1st argument is an iterator
203+ template <typename R, typename C, soa::is_iterator A, soa::is_table... Args>
204+ 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)
205+ requires(std::is_lvalue_reference_v<A> && (std::is_lvalue_reference_v<Args> && ...))
206+ {
207+ addGroupingCandidates<A, Args...>(bk, bku);
208+ constexpr auto hash = o2::framework::TypeIdHelpers::uniqueId<R (C::*)(A, Args...)>();
209+ addInputsAndExpressions<typename std::decay_t <A>::parent_t , Args...>(hash, name, value, inputs, eInfos);
210+ }
211+
212+ // / 3. generic case
213+ template <typename R, typename C, soa::is_table... Args>
214+ static void inputsFromArgs (R (C::*)(Args...), const char* name, bool value, std::vector<InputSpec>& inputs, std::vector<ExpressionInfo>& eInfos, std::vector<StringPair>&, std::vector<StringPair>&)
215+ requires(std::is_lvalue_reference_v<Args> && ...)
216+ {
217+ constexpr auto hash = o2::framework::TypeIdHelpers::uniqueId<R (C::*)(Args...)>();
218+ addInputsAndExpressions<Args...>(hash, name, value, inputs, eInfos);
219+ }
220+
185221 template <soa::TableRef R>
186222 static auto extractTableFromRecord (InputRecord& record)
187223 {
@@ -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
0 commit comments