diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index e098cd89f6d5d..7bab9d89c7f9a 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -213,8 +213,6 @@ template struct TableMetadata { using columns = framework::pack; using persistent_columns_t = framework::selected_pack; - using external_index_columns_t = framework::selected_pack; - using internal_index_columns_t = framework::selected_pack; template static consteval std::array getMap(framework::pack) @@ -814,9 +812,6 @@ concept is_dynamic_column = requires(C& c) { template concept is_marker_column = requires { &C::mark; }; -template -using is_dynamic_t = std::conditional_t, std::true_type, std::false_type>; - template concept is_column = is_persistent_column || is_dynamic_column || is_indexing_column || is_marker_column; @@ -1039,6 +1034,17 @@ concept can_bind = requires(T&& t) { template concept has_index = (is_indexing_column || ...); +template +consteval auto inBindings(framework::pack) +{ + return framework::has_type_at_v(framework::pack() { + if constexpr (is_index_column && !is_self_index_column) { + return std::declval(); + } else { + return; + } }.template operator()())...>{}); +} + template struct TableIterator : IP, C... { public: @@ -1046,13 +1052,10 @@ struct TableIterator : IP, C... { using policy_t = IP; using all_columns = framework::pack; using persistent_columns_t = framework::selected_pack; - using external_index_columns_t = framework::selected_pack; - using internal_index_columns_t = framework::selected_pack; - using bindings_pack_t = decltype([](framework::pack) -> framework::pack {}(external_index_columns_t{})); // decltype(extractBindings(external_index_columns_t{})); TableIterator(arrow::ChunkedArray* columnData[sizeof...(C)], IP&& policy) : IP{policy}, - C(columnData[framework::has_type_at_v(all_columns{})])... + C(columnData[framework::has_type_at_v(framework::pack{})])... { bind(); } @@ -1060,7 +1063,7 @@ struct TableIterator : IP, C... { TableIterator(arrow::ChunkedArray* columnData[sizeof...(C)], IP&& policy) requires(has_index) : IP{policy}, - C(columnData[framework::has_type_at_v(all_columns{})])... + C(columnData[framework::has_type_at_v(framework::pack{})])... { bind(); // In case we have an index column might need to constrain the actual @@ -1138,58 +1141,61 @@ struct TableIterator : IP, C... { return *this; } - template - void doSetCurrentIndex(framework::pack, TA* current) - { - (CL::setCurrent(current), ...); - } - template auto getCurrent() const { return CL::getCurrentRaw(); } - template - auto getIndexBindingsImpl(framework::pack) const + std::vector getIndexBindings() const { - return std::vector{static_cast(*this).getCurrentRaw()...}; - } - - auto getIndexBindings() const - { - return getIndexBindingsImpl(external_index_columns_t{}); + return { [this]() { + if constexpr (soa::is_index_column && !soa::is_self_index_column) { + return o2::soa::Binding{CL::getCurrentRaw()}; + } else { + return o2::soa::Binding{}; + } + }.template operator()()... }; } template void bindExternalIndices(TA*... current) { - (doSetCurrentIndex(external_index_columns_t{}, current), ...); - } - - template - void doSetCurrentIndexRaw(framework::pack p, std::vector&& ptrs) - { - (Cs::setCurrentRaw(ptrs[framework::has_type_at_v(p)]), ...); - } - - template - void doSetCurrentInternal(framework::pack, I const* ptr) - { - o2::soa::Binding b; - b.bind(ptr); - (Cs::setCurrentRaw(b), ...); + ([this](framework::pack, TT* t) { + ([this](TI* c) { + if constexpr (soa::is_index_column && !soa::is_self_index_column) { + CL::setCurrent(c); + } + }.template operator()(t), + ...); + }(framework::pack{}, current), + ...); } - void bindExternalIndicesRaw(std::vector&& ptrs) + void bindExternalIndicesRaw(std::vector&& bindings) { - doSetCurrentIndexRaw(external_index_columns_t{}, std::forward>(ptrs)); + [&bindings, this](std::index_sequence) { + ([&bindings, this]() { + using column = typename framework::pack_element_t>; + if constexpr (soa::is_index_column && !soa::is_self_index_column) { + column::setCurrentRaw(bindings[Is]); + } + }(), + ...); + }(std::make_index_sequence()); } template void bindInternalIndices(I const* table) { - doSetCurrentInternal(internal_index_columns_t{}, table); + o2::soa::Binding b; + b.bind(table); + ([this](o2::soa::Binding const& bb) { + if constexpr (soa::is_self_index_column) { + CL::setCurrentRaw(bb); + } + }.template operator()(b), + ...); } private: @@ -1205,42 +1211,36 @@ struct TableIterator : IP, C... { void bind() { using namespace o2::soa; - auto f = framework::overloaded{ - [this](T*) -> void { T::mColumnIterator.mCurrentPos = &this->mRowIndex; }, - [this](T*) -> void { bindDynamicColumn(typename T::bindings_t{}); }, - [this](T*) -> void {}, - }; - (f(static_cast(nullptr)), ...); + ([this]() { + if constexpr (soa::is_persistent_column) { + C::mColumnIterator.mCurrentPos = &this->mRowIndex; + } else if constexpr (soa::is_dynamic_column) { + bindDynamicColumn(typename C::bindings_t{}); + } + }(), + ...); + if constexpr (has_index) { this->setIndices(this->getIndices()); this->setOffsets(this->getOffsets()); } } - template - auto bindDynamicColumn(framework::pack) - { - DC::boundIterators = std::make_tuple(getDynamicBinding()...); - } - // Sometimes dynamic columns are defined for tables in // the hope that it will be joined / extended with another one which provides // the full set of bindings. This is to avoid a compilation // error if constructor for the table or any other thing involving a missing // binding is preinstanciated. - template - requires(can_bind) - decltype(auto) getDynamicBinding() - { - static_assert(std::same_as(this)->mColumnIterator)), std::decay_t*>, "foo"); - return &(static_cast(this)->mColumnIterator); - // return static_cast*>(nullptr); - } - - template - decltype(auto) getDynamicBinding() + template + auto bindDynamicColumn(framework::pack) { - return static_cast*>(nullptr); + DC::boundIterators = std::make_tuple([this]() { + if constexpr (can_bind) { + return &(static_cast(this)->mColumnIterator); + } else { + return static_cast*>(nullptr); + } + }.template operator()()...); } }; @@ -1373,25 +1373,39 @@ static constexpr std::string getLabelFromTypeForKey(std::string const& key) template consteval static bool hasIndexTo(framework::pack&&) { - return (o2::soa::is_binding_compatible_v() || ...); + return ([]() { + if constexpr (soa::is_index_column && !soa::is_self_index_column) { + return o2::soa::is_binding_compatible_v(); + } else { + return false; + } + }.template operator()() || + ...); } template consteval static bool hasSortedIndexTo(framework::pack&&) { - return ((C::sorted && o2::soa::is_binding_compatible_v()) || ...); + return ([]() { + if constexpr (soa::is_index_column && !soa::is_self_index_column) { + return CC::sorted && o2::soa::is_binding_compatible_v(); + } else { + return false; + } + }.template operator()() || + ...); } template consteval static bool relatedByIndex() { - return hasIndexTo(typename Z::table_t::external_index_columns_t{}); + return hasIndexTo(typename Z::table_t::columns_t{}); } template consteval static bool relatedBySortedIndex() { - return hasSortedIndexTo(typename Z::table_t::external_index_columns_t{}); + return hasSortedIndexTo(typename Z::table_t::columns_t{}); } } // namespace o2::soa @@ -1719,17 +1733,12 @@ class Table using persistent_columns_t = decltype([](framework::pack&&) -> framework::selected_pack {}(columns_t{})); using column_types = decltype([](framework::pack) -> framework::pack {}(persistent_columns_t{})); - using external_index_columns_t = decltype([](framework::pack&&) -> framework::selected_pack {}(columns_t{})); - using internal_index_columns_t = decltype([](framework::pack&&) -> framework::selected_pack {}(columns_t{})); template using base_iterator = decltype(base_iter(columns_t{})); template struct TableIteratorBase : base_iterator { using columns_t = typename Parent::columns_t; - using external_index_columns_t = typename Parent::external_index_columns_t; - using bindings_pack_t = decltype([](framework::pack) -> framework::pack {}(external_index_columns_t{})); - // static constexpr const std::array originals{T::ref...}; static constexpr auto originals = Parent::originals; using policy_t = IP; using parent_t = Parent; @@ -1818,33 +1827,34 @@ class Table template auto getId() const { - using decayed = std::decay_t; - if constexpr (framework::has_type(bindings_pack_t{})) { // index to another table - constexpr auto idx = framework::has_type_at_v(bindings_pack_t{}); - return framework::pack_element_t::getId(); - } else if constexpr (std::same_as) { // self index - return this->globalIndex(); - } else if constexpr (is_indexing_column) { // soa::Index<> - return this->globalIndex(); - } else { - return static_cast(-1); - } + return static_cast(-1); } - template + template + requires(std::same_as, Parent> || is_indexing_column>) + auto getId() const + { + return this->globalIndex(); + } + + template + requires(inBindings>(typename Parent::all_columns{}) < framework::pack_size(typename Parent::all_columns{})) + auto getId() const + { + return inBindings>(typename Parent::all_columns{}); + } + + template auto getDynamicColumn() const { - using decayed = std::decay_t; - static_assert(is_dynamic_t(), "Requested column is not a dynamic column"); - return static_cast(*this).template getDynamicValue(); + return static_cast>(*this).template getDynamicValue(); } template + requires(is_dynamic_column || is_persistent_column) auto getValue() const { - using COL = std::decay_t; - static_assert(is_dynamic_t() || soa::is_persistent_column, "Should be persistent or dynamic column with no argument that has a return type convertable to float"); - return static_cast(static_cast(*this).get()); + return static_cast(static_cast>(*this).get()); } template @@ -2049,13 +2059,18 @@ class Table void bindInternalIndicesExplicit(o2::soa::Binding binding) { - doBindInternalIndicesExplicit(internal_index_columns_t{}, binding); + doBindInternalIndicesExplicit(columns_t{}, binding); } template void doBindInternalIndicesExplicit(framework::pack, o2::soa::Binding binding) { - (static_cast(mBegin).setCurrentRaw(binding), ...); + ([this](o2::soa::Binding b) { + if constexpr (soa::is_self_index_column) { + static_cast(mBegin).setCurrentRaw(b); + } + }.template operator()(binding), + ...); } void bindExternalIndicesRaw(std::vector&& ptrs) @@ -2072,7 +2087,7 @@ class Table template void copyIndexBindings(T& dest) const { - doCopyIndexBindings(external_index_columns_t{}, dest); + doCopyIndexBindings(columns_t{}, dest); } auto select(framework::expressions::Filter const& f) const @@ -3349,7 +3364,6 @@ class FilteredBase : public T using T::originals; using columns_t = typename T::columns_t; using persistent_columns_t = typename T::persistent_columns_t; - using external_index_columns_t = typename T::external_index_columns_t; using iterator = T::template iterator_template_o; using unfiltered_iterator = T::template iterator_template_o; @@ -3495,7 +3509,7 @@ class FilteredBase : public T template void copyIndexBindings(T1& dest) const { - doCopyIndexBindings(external_index_columns_t{}, dest); + doCopyIndexBindings(columns_t{}, dest); } template diff --git a/Framework/Core/include/Framework/GroupedCombinations.h b/Framework/Core/include/Framework/GroupedCombinations.h index b0a6c9e658a10..48780a157cf1d 100644 --- a/Framework/Core/include/Framework/GroupedCombinations.h +++ b/Framework/Core/include/Framework/GroupedCombinations.h @@ -35,13 +35,18 @@ auto interleaveTuples(std::tuple& t1, std::tuple& t2) } template -using is_index_to_g_t = typename std::conditional(), std::true_type, std::false_type>::type; +using is_index_to_g_t = decltype([]() { + if constexpr (soa::is_index_column && !soa::is_self_index_column) { + return std::conditional_t, typename std::decay_t::binding_t>(), std::true_type, std::false_type>{}; + } else { + return std::false_type{}; + } +}()); template expressions::BindingNode getMatchingIndexNode() { - using external_index_columns_pack = typename A::external_index_columns_t; - using selected_indices_t = selected_pack_multicondition, external_index_columns_pack>; + using selected_indices_t = selected_pack_multicondition, typename A::columns_t>; static_assert(pack_size(selected_indices_t{}) == 1, "No matching index column from associated to grouping"); using index_column_t = pack_head_t; return expressions::BindingNode{index_column_t::mLabel, o2::framework::TypeIdHelpers::uniqueId(), expressions::selectArrowType()};