Skip to content

Comments

Fix nd_span iterators to respect strides of non-contiguous views#3

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/fix-nd-span-iterator-strides
Draft

Fix nd_span iterators to respect strides of non-contiguous views#3
Copilot wants to merge 4 commits intomainfrom
copilot/fix-nd-span-iterator-strides

Conversation

Copy link

Copilot AI commented Feb 21, 2026

nd_span::begin()/end() returned raw pointers, iterating linearly over raw memory regardless of strides. This made range-based for loops and STL algorithms produce wrong results for subspans and transposed views (any view with non-unit or non-contiguous strides).

Changes

include/nd_array/nd_array.hpp

  • Added detail::nd_iterator<ElementType, MaxRank> stride-aware forward iterator template in the detail namespace, tracking multi-dimensional indices and computing element addresses as data + Σ(indices[i] × strides[i])
  • Template parameter is the element type directly (Ty for mutable, const Ty for const) rather than a bool IsConst flag, making the iterator reusable by other classes in the same header
  • Supports implicit conversion from iterator to const_iterator
  • Handles edge cases: zero rank, zero-sized extents
  • Added iterator / const_iterator type aliases in nd_span pointing to detail::nd_iterator
  • Replaced raw-pointer begin()/end()/cbegin()/cend() with stride-aware iterator versions
  • Added #include <iterator> for std::forward_iterator_tag

tests/test_nd_span.cpp

Added "nd_span - Stride-aware iteration" test case covering:

  • Column subspan (non-unit stride in outer dimension)
  • Transposed view (swapped strides)
  • Write-through mutation only touches elements inside the subspan

Example

// 3×5 matrix, values 0..14
nd_span<int> span(data.data(), 3, 5);

// Subspan of columns 1–3: extents [3,3], strides [5,1]
auto sub = span.subspan(1, {1, 4});

// Previously: iterated over raw memory [data+0 .. data+9] — wrong values/elements
// Now: visits span(0,1), span(0,2), span(0,3), span(1,1), ... correctly
for (auto v : sub) { /* stride-aware */ }
Original prompt

This section details on the original issue you should resolve

<issue_title>nd_span iterators do not consider the strides of subspans</issue_title>
<issue_description>As the title states. When using begin or end in a nd_span, the stride of that span is not considered and it iterates linearly over the contained memory. This is not useful when creating subspans from nd_array of other nd_spans.</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@codecov
Copy link

codecov bot commented Feb 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.92%. Comparing base (d3e9064) to head (af0aa64).

Additional details and impacted files
@@           Coverage Diff           @@
##             main       #3   +/-   ##
=======================================
  Coverage   97.92%   97.92%           
=======================================
  Files           3        3           
  Lines        1206     1206           
=======================================
  Hits         1181     1181           
  Misses         25       25           
Flag Coverage Δ
Windows-windows-debug 97.65% <0.00%> (ø)
Windows-windows-msvc-debug 97.91% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI and others added 2 commits February 21, 2026 12:29
Co-authored-by: pingelit <22936321+pingelit@users.noreply.github.com>
Co-authored-by: pingelit <22936321+pingelit@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix nd_span iterators to consider strides of subspans Fix nd_span iterators to respect strides of non-contiguous views Feb 21, 2026
Copilot AI requested a review from pingelit February 21, 2026 12:30
Copy link
Owner

@pingelit pingelit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, some minor changes to the iterator class would be nice to encourage reuse.

[[nodiscard]] pointer begin( ) noexcept { return m_data; }
/// \brief Stride-aware forward iterator for nd_span
/// \tparam IsConst Whether this is a const iterator
template<bool IsConst>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think moving the iterator to the detail namespace would make sense here. That way, it could be reused more easily.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 29f04dd — the iterator is now detail::nd_iterator<ElementType, MaxRank> in the detail namespace, and nd_span exposes it via using iterator = detail::nd_iterator<Ty, MaxRank> and using const_iterator = detail::nd_iterator<const Ty, MaxRank>.

Comment on lines 643 to 644
using iterator = basic_iterator<false>; ///< Mutable stride-aware iterator
using const_iterator = basic_iterator<true>; ///< Const stride-aware iterator
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer if the tempate argument would just be the underlying type, either const or non-const, not a bool.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 29f04dd — the template parameter is now the element type directly (template<typename ElementType, size_t MaxRank>), so nd_iterator<Ty, MaxRank> is the mutable iterator and nd_iterator<const Ty, MaxRank> is the const iterator. The bool IsConst + std::conditional_t machinery is gone.

…instead of bool IsConst

Co-authored-by: pingelit <22936321+pingelit@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nd_span iterators do not consider the strides of subspans

2 participants