From e44bdb8386ad5279b1a13596cbb228be051e13be Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Thu, 19 Jun 2025 10:12:27 +0200 Subject: [PATCH 1/4] DPL Analysis: rework table builder cursor signature logic --- Framework/Core/include/Framework/ASoA.h | 70 +++++++++---------- .../Core/include/Framework/AnalysisHelpers.h | 13 ++-- .../Framework/ArrowTableSlicingCache.h | 4 +- .../Core/include/Framework/GroupSlicer.h | 6 +- .../Core/include/Framework/TableBuilder.h | 24 +++---- Framework/Core/src/ASoA.cxx | 4 +- Framework/Core/src/ArrowTableSlicingCache.cxx | 2 +- Framework/Core/test/test_ASoA.cxx | 4 +- 8 files changed, 65 insertions(+), 62 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 6a49ed25e40d2..44f956f0ee9e2 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -561,21 +561,21 @@ class ColumnIterator : ChunkingPolicy mLast = mCurrent + array->length() + (mFirstIndex >> SCALE_FACTOR); } - decltype(auto) operator*() const + auto operator*() const requires std::same_as> { checkSkipChunk(); return (*(mCurrent - (mOffset >> SCALE_FACTOR) + ((*mCurrentPos + mOffset) >> SCALE_FACTOR)) & (1 << ((*mCurrentPos + mOffset) & 0x7))) != 0; } - decltype(auto) operator*() const + auto operator*() const requires((!std::same_as>) && std::same_as, arrow::ListArray>) { checkSkipChunk(); auto list = std::static_pointer_cast(mColumn->chunk(mCurrentChunk)); auto offset = list->value_offset(*mCurrentPos - mFirstIndex); auto length = list->value_length(*mCurrentPos - mFirstIndex); - return gsl::span{mCurrent + mFirstIndex + offset, mCurrent + mFirstIndex + (offset + length)}; + return std::span const>{mCurrent + mFirstIndex + offset, mCurrent + mFirstIndex + (offset + length)}; } decltype(auto) operator*() const @@ -851,7 +851,7 @@ struct FilteredIndexPolicy : IndexPolicyBase { // which happens below which will properly setup the first index // by remapping the filtered index 0 to whatever unfiltered index // it belongs to. - FilteredIndexPolicy(gsl::span selection, int64_t rows, uint64_t offset = 0) + FilteredIndexPolicy(std::span selection, int64_t rows, uint64_t offset = 0) : IndexPolicyBase{-1, offset}, mSelectedRows(selection), mMaxSelection(selection.size()), @@ -860,7 +860,7 @@ struct FilteredIndexPolicy : IndexPolicyBase { this->setCursor(0); } - void resetSelection(gsl::span selection) + void resetSelection(std::span selection) { mSelectedRows = selection; mMaxSelection = selection.size(); @@ -944,7 +944,7 @@ struct FilteredIndexPolicy : IndexPolicyBase { { this->mRowIndex = O2_BUILTIN_LIKELY(mSelectionRow < mMaxSelection) ? mSelectedRows[mSelectionRow] : -1; } - gsl::span mSelectedRows; + std::span mSelectedRows; int64_t mSelectionRow = 0; int64_t mMaxSelection = 0; int64_t nRows = 0; @@ -1428,7 +1428,7 @@ struct PreslicePolicyGeneral : public PreslicePolicyBase { void updateSliceInfo(SliceInfoUnsortedPtr&& si); SliceInfoUnsortedPtr sliceInfo; - gsl::span getSliceFor(int value) const; + std::span getSliceFor(int value) const; }; template @@ -1453,7 +1453,7 @@ struct PresliceBase : public Policy { return Policy::getSliceFor(value, input, offset); } - gsl::span getSliceFor(int value) const + std::span getSliceFor(int value) const { if constexpr (OPT) { if (Policy::isMissing()) { @@ -1549,7 +1549,7 @@ auto doSliceBy(T const* table, o2::framework::PresliceBase const } template -auto doSliceByHelper(T const* table, gsl::span const& selection) +auto doSliceByHelper(T const* table, std::span const& selection) { auto t = soa::Filtered({table->asArrowTable()}, selection); table->copyIndexBindings(t); @@ -1560,7 +1560,7 @@ auto doSliceByHelper(T const* table, gsl::span const& selection) template requires(!soa::is_filtered_table) -auto doSliceByHelper(T const* table, gsl::span const& selection) +auto doSliceByHelper(T const* table, std::span const& selection) { auto t = soa::Filtered({table->asArrowTable()}, selection); table->copyIndexBindings(t); @@ -1581,7 +1581,7 @@ auto doSliceBy(T const* table, o2::framework::PresliceBase const return doSliceByHelper(table, selection); } -SelectionVector sliceSelection(gsl::span const& mSelectedRows, int64_t nrows, uint64_t offset); +SelectionVector sliceSelection(std::span const& mSelectedRows, int64_t nrows, uint64_t offset); template auto prepareFilteredSlice(T const* table, std::shared_ptr slice, uint64_t offset) @@ -2011,7 +2011,7 @@ class Table return RowViewSentinel{mEnd}; } - filtered_iterator filtered_begin(gsl::span selection) + filtered_iterator filtered_begin(std::span selection) { // Note that the FilteredIndexPolicy will never outlive the selection which // is held by the table, so we are safe passing the bare pointer. If it does it @@ -2556,12 +2556,12 @@ consteval auto getIndexTargets() _Name_##Ids(_Name_##Ids const& other) = default; \ _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ \ - gsl::span inline getIds() const \ + std::span inline getIds() const \ { \ return _Getter_##Ids(); \ } \ \ - gsl::span _Getter_##Ids() const \ + std::span _Getter_##Ids() const \ { \ return *mColumnIterator; \ } \ @@ -2915,12 +2915,12 @@ consteval auto getIndexTargets() _Name_##Ids() = default; \ _Name_##Ids(_Name_##Ids const& other) = default; \ _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - gsl::span inline getIds() const \ + std::span inline getIds() const \ { \ return _Getter_##Ids(); \ } \ \ - gsl::span _Getter_##Ids() const \ + std::span _Getter_##Ids() const \ { \ return *mColumnIterator; \ } \ @@ -3371,7 +3371,7 @@ class FilteredBase : public T mSelectedRowsCache{std::move(selection)}, mCached{true} { - mSelectedRows = gsl::span{mSelectedRowsCache}; + mSelectedRows = std::span{mSelectedRowsCache}; if (this->tableSize() != 0) { mFilteredBegin = table_t::filtered_begin(mSelectedRows); } @@ -3379,7 +3379,7 @@ class FilteredBase : public T mFilteredBegin.bindInternalIndices(this); } - FilteredBase(std::vector>&& tables, gsl::span const& selection, uint64_t offset = 0) + FilteredBase(std::vector>&& tables, std::span const& selection, uint64_t offset = 0) : T{std::move(tables), offset}, mSelectedRows{selection} { @@ -3458,12 +3458,12 @@ class FilteredBase : public T static inline auto getSpan(gandiva::Selection const& sel) { if (sel == nullptr) { - return gsl::span{}; + return std::span{}; } auto array = std::static_pointer_cast(sel->ToArray()); auto start = array->raw_values(); auto stop = start + array->length(); - return gsl::span{start, stop}; + return std::span{start, stop}; } /// Bind the columns which refer to other tables @@ -3562,7 +3562,7 @@ class FilteredBase : public T resetRanges(); } - void sumWithSelection(gsl::span const& selection) + void sumWithSelection(std::span const& selection) { mCached = true; SelectionVector rowsUnion; @@ -3572,7 +3572,7 @@ class FilteredBase : public T resetRanges(); } - void intersectWithSelection(gsl::span const& selection) + void intersectWithSelection(std::span const& selection) { mCached = true; SelectionVector intersection; @@ -3591,7 +3591,7 @@ class FilteredBase : public T void resetRanges() { if (mCached) { - mSelectedRows = gsl::span{mSelectedRowsCache}; + mSelectedRows = std::span{mSelectedRowsCache}; } mFilteredEnd.reset(new RowViewSentinel{static_cast(mSelectedRows.size())}); if (tableSize() == 0) { @@ -3601,7 +3601,7 @@ class FilteredBase : public T } } - gsl::span mSelectedRows; + std::span mSelectedRows; SelectionVector mSelectedRowsCache; bool mCached = false; iterator mFilteredBegin; @@ -3637,7 +3637,7 @@ class Filtered : public FilteredBase Filtered(std::vector>&& tables, SelectionVector&& selection, uint64_t offset = 0) : FilteredBase(std::move(tables), std::forward(selection), offset) {} - Filtered(std::vector>&& tables, gsl::span const& selection, uint64_t offset = 0) + Filtered(std::vector>&& tables, std::span const& selection, uint64_t offset = 0) : FilteredBase(std::move(tables), selection, offset) {} Filtered operator+(SelectionVector const& selection) @@ -3647,7 +3647,7 @@ class Filtered : public FilteredBase return copy; } - Filtered operator+(gsl::span const& selection) + Filtered operator+(std::span const& selection) { Filtered copy(*this); copy.sumWithSelection(selection); @@ -3665,7 +3665,7 @@ class Filtered : public FilteredBase return *this; } - Filtered operator+=(gsl::span const& selection) + Filtered operator+=(std::span const& selection) { this->sumWithSelection(selection); return *this; @@ -3683,7 +3683,7 @@ class Filtered : public FilteredBase return copy; } - Filtered operator*(gsl::span const& selection) + Filtered operator*(std::span const& selection) { Filtered copy(*this); copy.intersectWithSelection(selection); @@ -3701,7 +3701,7 @@ class Filtered : public FilteredBase return *this; } - Filtered operator*=(gsl::span const& selection) + Filtered operator*=(std::span const& selection) { this->intersectWithSelection(selection); return *this; @@ -3809,7 +3809,7 @@ class Filtered> : public FilteredBase } } - Filtered(std::vector>&& tables, gsl::span const& selection, uint64_t offset = 0) + Filtered(std::vector>&& tables, std::span const& selection, uint64_t offset = 0) : FilteredBase(std::move(extractTablesFromFiltered(tables)), selection, offset) { for (auto& table : tables) { @@ -3824,7 +3824,7 @@ class Filtered> : public FilteredBase return copy; } - Filtered> operator+(gsl::span const& selection) + Filtered> operator+(std::span const& selection) { Filtered> copy(*this); copy.sumWithSelection(selection); @@ -3842,7 +3842,7 @@ class Filtered> : public FilteredBase return *this; } - Filtered> operator+=(gsl::span const& selection) + Filtered> operator+=(std::span const& selection) { this->sumWithSelection(selection); return *this; @@ -3860,7 +3860,7 @@ class Filtered> : public FilteredBase return copy; } - Filtered> operator*(gsl::span const& selection) + Filtered> operator*(std::span const& selection) { Filtered> copy(*this); copy.intersectionWithSelection(selection); @@ -3878,7 +3878,7 @@ class Filtered> : public FilteredBase return *this; } - Filtered> operator*=(gsl::span const& selection) + Filtered> operator*=(std::span const& selection) { this->intersectWithSelection(selection); return *this; @@ -3987,7 +3987,7 @@ struct SmallGroupsBase : public Filtered { SmallGroupsBase(std::vector>&& tables, SelectionVector&& selection, uint64_t offset = 0) : Filtered(std::move(tables), std::forward(selection), offset) {} - SmallGroupsBase(std::vector>&& tables, gsl::span const& selection, uint64_t offset = 0) + SmallGroupsBase(std::vector>&& tables, std::span const& selection, uint64_t offset = 0) : Filtered(std::move(tables), selection, offset) {} }; diff --git a/Framework/Core/include/Framework/AnalysisHelpers.h b/Framework/Core/include/Framework/AnalysisHelpers.h index 6e9b1e211bb76..93edc30c1877c 100644 --- a/Framework/Core/include/Framework/AnalysisHelpers.h +++ b/Framework/Core/include/Framework/AnalysisHelpers.h @@ -119,6 +119,9 @@ class TableConsumer; template concept is_producable = soa::has_metadata> || soa::has_metadata>; +template +concept is_enumerated_iterator = requires (T t) { t.globalIndex(); }; + template struct WritingCursor { public: @@ -126,9 +129,9 @@ struct WritingCursor { using cursor_t = decltype(std::declval().cursor()); template - void operator()(Ts... args) + void operator()(Ts&&... args) + requires(sizeof...(Ts) == framework::pack_size(typename persistent_table_t::persistent_columns_t{})) { - static_assert(sizeof...(Ts) == framework::pack_size(typename persistent_table_t::persistent_columns_t{}), "Argument number mismatch"); ++mCount; cursor(0, extract(args)...); } @@ -167,15 +170,15 @@ struct WritingCursor { decltype(FFL(std::declval())) cursor; private: - template - requires requires { &A::globalIndex; } + template static decltype(auto) extract(A const& arg) { return arg.globalIndex(); } template - static decltype(auto) extract(A const& arg) + requires(!is_enumerated_iterator) + static decltype(auto) extract(A&& arg) { return arg; } diff --git a/Framework/Core/include/Framework/ArrowTableSlicingCache.h b/Framework/Core/include/Framework/ArrowTableSlicingCache.h index 41d6b33e48476..40991a955e52b 100644 --- a/Framework/Core/include/Framework/ArrowTableSlicingCache.h +++ b/Framework/Core/include/Framework/ArrowTableSlicingCache.h @@ -28,10 +28,10 @@ struct SliceInfoPtr { }; struct SliceInfoUnsortedPtr { - gsl::span values; + std::span values; ListVector const* groups; - gsl::span getSliceFor(int value) const; + std::span getSliceFor(int value) const; }; struct Entry { diff --git a/Framework/Core/include/Framework/GroupSlicer.h b/Framework/Core/include/Framework/GroupSlicer.h index 112bf7e147ff0..4cfbb8c440fd3 100644 --- a/Framework/Core/include/Framework/GroupSlicer.h +++ b/Framework/Core/include/Framework/GroupSlicer.h @@ -264,9 +264,9 @@ struct GroupSlicer { std::tuple* mAt; typename grouping_t::iterator mGroupingElement; uint64_t position = 0; - gsl::span groupSelection; - std::array const*, sizeof...(A)> selections; - std::array::iterator, sizeof...(A)> starts; + std::span groupSelection; + std::array const*, sizeof...(A)> selections; + std::array::iterator, sizeof...(A)> starts; std::array sliceInfos; std::array sliceInfosUnsorted; diff --git a/Framework/Core/include/Framework/TableBuilder.h b/Framework/Core/include/Framework/TableBuilder.h index 74395a2680077..1eb493bfd052d 100644 --- a/Framework/Core/include/Framework/TableBuilder.h +++ b/Framework/Core/include/Framework/TableBuilder.h @@ -105,7 +105,7 @@ void addLabelToSchema(std::shared_ptr& schema, const char* label) struct BuilderUtils { template - static arrow::Status appendToList(std::unique_ptr& builder, T* data, int size = 1) + static arrow::Status appendToList(std::unique_ptr& builder, const T* data, int size = 1) { using ArrowType = typename detail::ConversionTraits>::ArrowType; using BuilderType = typename arrow::TypeTraits::BuilderType; @@ -134,7 +134,7 @@ struct BuilderUtils { /// Assumes that the pointer actually points to a buffer /// which contains the correct number of elements. template - static arrow::Status append(HolderType& holder, T* data) + static arrow::Status append(HolderType& holder, const T* data) { if constexpr (std::is_same_v>) { return appendToList(holder.builder, data); @@ -144,21 +144,21 @@ struct BuilderUtils { } /// Appender for the array case. template - static arrow::Status append(HolderType& holder, T (&data)[N]) + static arrow::Status append(HolderType& holder, const T (&data)[N]) { return holder.builder->Append(reinterpret_cast(data)); } /// Appender for the array case. template - static arrow::Status append(HolderType& holder, std::array const& data) + static arrow::Status append(HolderType& holder, std::array const& data) { return holder.builder->Append(reinterpret_cast(data.data())); } /// Appender for the vector case. template - static arrow::Status append(HolderType& holder, std::vector const& data) + static arrow::Status append(HolderType& holder, std::span data) { using ArrowType = typename detail::ConversionTraits::ArrowType; using ValueBuilderType = typename arrow::TypeTraits::BuilderType; @@ -171,7 +171,7 @@ struct BuilderUtils { } template - static void unsafeAppend(HolderType& holder, std::vector const& value) + static void unsafeAppend(HolderType& holder, std::span value) { auto status = append(holder, value); if (!status.ok()) { @@ -300,7 +300,7 @@ struct BuilderMaker> { template struct BuilderMaker> { - using FillType = std::pair; + using FillType = std::pair const&; using STLValueType = typename ITERATOR::value_type; using ArrowType = arrow::ListType; using ValueType = typename detail::ConversionTraits::ArrowType; @@ -321,7 +321,7 @@ struct BuilderMaker> { template struct BuilderMaker { - using FillType = T*; + using FillType = const T*; using STLValueType = T; using BuilderType = arrow::FixedSizeListBuilder; using ArrowType = arrow::FixedSizeListType; @@ -343,7 +343,7 @@ struct BuilderMaker { template struct BuilderMaker { - using FillType = T*; + using FillType = const T*; using BuilderType = arrow::FixedSizeListBuilder; using ArrowType = arrow::FixedSizeListType; using ElementType = typename detail::ConversionTraits::ArrowType; @@ -364,7 +364,7 @@ struct BuilderMaker { template struct BuilderMaker> { - using FillType = T*; + using FillType = const T*; using BuilderType = arrow::FixedSizeListBuilder; using ArrowType = arrow::FixedSizeListType; using ElementType = typename detail::ConversionTraits::ArrowType; @@ -385,7 +385,7 @@ struct BuilderMaker> { template struct BuilderMaker> { - using FillType = std::vector; + using FillType = std::span; using BuilderType = arrow::ListBuilder; using ArrowType = arrow::ListType; using ElementType = typename detail::ConversionTraits::ArrowType; @@ -678,7 +678,7 @@ class TableBuilder { auto persister = persistTuple(framework::pack{}, columnNames); // Callback used to fill the builders - return [persister = persister](unsigned int slot, typename BuilderMaker::FillType const& arg, typename BuilderMaker::FillType... args) -> void { + return [persister = persister](unsigned int slot, typename BuilderMaker::FillType arg, typename BuilderMaker::FillType... args) -> void { persister(slot, std::forward_as_tuple(arg, args...)); }; } diff --git a/Framework/Core/src/ASoA.cxx b/Framework/Core/src/ASoA.cxx index 3a681ee931a2b..7b5cdf72191cf 100644 --- a/Framework/Core/src/ASoA.cxx +++ b/Framework/Core/src/ASoA.cxx @@ -50,7 +50,7 @@ SelectionVector selectionToVector(gandiva::Selection const& sel) return rows; } -SelectionVector sliceSelection(gsl::span const& mSelectedRows, int64_t nrows, uint64_t offset) +SelectionVector sliceSelection(std::span const& mSelectedRows, int64_t nrows, uint64_t offset) { auto start = offset; auto end = start + nrows; @@ -217,7 +217,7 @@ std::shared_ptr PreslicePolicySorted::getSliceFor(int value, std:: return output; } -gsl::span PreslicePolicyGeneral::getSliceFor(int value) const +std::span PreslicePolicyGeneral::getSliceFor(int value) const { return this->sliceInfo.getSliceFor(value); } diff --git a/Framework/Core/src/ArrowTableSlicingCache.cxx b/Framework/Core/src/ArrowTableSlicingCache.cxx index 26bb9bcee80eb..0d06a926dd930 100644 --- a/Framework/Core/src/ArrowTableSlicingCache.cxx +++ b/Framework/Core/src/ArrowTableSlicingCache.cxx @@ -42,7 +42,7 @@ std::pair SliceInfoPtr::getSliceFor(int value) const return {offsets[value], sizes[value]}; } -gsl::span SliceInfoUnsortedPtr::getSliceFor(int value) const +std::span SliceInfoUnsortedPtr::getSliceFor(int value) const { if (values.empty()) { return {}; diff --git a/Framework/Core/test/test_ASoA.cxx b/Framework/Core/test/test_ASoA.cxx index 80519aebc9ee7..a60f51d3928c2 100644 --- a/Framework/Core/test/test_ASoA.cxx +++ b/Framework/Core/test/test_ASoA.cxx @@ -1150,8 +1150,8 @@ TEST_CASE("TestListColumns") for (auto& row : tbl) { auto f = row.l1(); auto i = row.l2(); - auto constexpr bf = std::same_as>; - auto constexpr bi = std::same_as>; + auto constexpr bf = std::same_as>; + auto constexpr bi = std::same_as>; REQUIRE(bf); REQUIRE(bi); REQUIRE(f.size() == s); From e6628f3f1b570e476d32d384ac30fd97cbe3d8d3 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Tue, 24 Jun 2025 11:58:19 +0000 Subject: [PATCH 2/4] Please consider the following formatting changes --- Framework/Core/include/Framework/AnalysisHelpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/AnalysisHelpers.h b/Framework/Core/include/Framework/AnalysisHelpers.h index 93edc30c1877c..0a8e42f5f1496 100644 --- a/Framework/Core/include/Framework/AnalysisHelpers.h +++ b/Framework/Core/include/Framework/AnalysisHelpers.h @@ -120,7 +120,7 @@ template concept is_producable = soa::has_metadata> || soa::has_metadata>; template -concept is_enumerated_iterator = requires (T t) { t.globalIndex(); }; +concept is_enumerated_iterator = requires(T t) { t.globalIndex(); }; template struct WritingCursor { From c38e5a0aa9fd08ceef520f053816c20008a8b137 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Thu, 21 Aug 2025 08:37:49 +0200 Subject: [PATCH 3/4] use gsl::span for now in the VLA return --- Framework/Core/include/Framework/ASoA.h | 10 +++++----- Framework/Core/test/test_ASoA.cxx | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 44f956f0ee9e2..3aab089fde00c 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -575,7 +575,7 @@ class ColumnIterator : ChunkingPolicy auto list = std::static_pointer_cast(mColumn->chunk(mCurrentChunk)); auto offset = list->value_offset(*mCurrentPos - mFirstIndex); auto length = list->value_length(*mCurrentPos - mFirstIndex); - return std::span const>{mCurrent + mFirstIndex + offset, mCurrent + mFirstIndex + (offset + length)}; + return gsl::span const>{mCurrent + mFirstIndex + offset, mCurrent + mFirstIndex + (offset + length)}; } decltype(auto) operator*() const @@ -2556,12 +2556,12 @@ consteval auto getIndexTargets() _Name_##Ids(_Name_##Ids const& other) = default; \ _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ \ - std::span inline getIds() const \ + gsl::span inline getIds() const \ { \ return _Getter_##Ids(); \ } \ \ - std::span _Getter_##Ids() const \ + gsl::span _Getter_##Ids() const \ { \ return *mColumnIterator; \ } \ @@ -2915,12 +2915,12 @@ consteval auto getIndexTargets() _Name_##Ids() = default; \ _Name_##Ids(_Name_##Ids const& other) = default; \ _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - std::span inline getIds() const \ + gsl::span inline getIds() const \ { \ return _Getter_##Ids(); \ } \ \ - std::span _Getter_##Ids() const \ + gsl::span _Getter_##Ids() const \ { \ return *mColumnIterator; \ } \ diff --git a/Framework/Core/test/test_ASoA.cxx b/Framework/Core/test/test_ASoA.cxx index a60f51d3928c2..80519aebc9ee7 100644 --- a/Framework/Core/test/test_ASoA.cxx +++ b/Framework/Core/test/test_ASoA.cxx @@ -1150,8 +1150,8 @@ TEST_CASE("TestListColumns") for (auto& row : tbl) { auto f = row.l1(); auto i = row.l2(); - auto constexpr bf = std::same_as>; - auto constexpr bi = std::same_as>; + auto constexpr bf = std::same_as>; + auto constexpr bi = std::same_as>; REQUIRE(bf); REQUIRE(bi); REQUIRE(f.size() == s); From bd75c0348a48b84c4b575ee4eb801cfb92c13732 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Thu, 21 Aug 2025 10:32:53 +0200 Subject: [PATCH 4/4] simplify constraint --- Framework/Core/include/Framework/AnalysisHelpers.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Framework/Core/include/Framework/AnalysisHelpers.h b/Framework/Core/include/Framework/AnalysisHelpers.h index 0a8e42f5f1496..0fc4821e6a420 100644 --- a/Framework/Core/include/Framework/AnalysisHelpers.h +++ b/Framework/Core/include/Framework/AnalysisHelpers.h @@ -170,8 +170,7 @@ struct WritingCursor { decltype(FFL(std::declval())) cursor; private: - template - static decltype(auto) extract(A const& arg) + static decltype(auto) extract(is_enumerated_iterator auto const& arg) { return arg.globalIndex(); }