Skip to content

Commit

Permalink
implement DoubleEndedIterator for 1d lanes
Browse files Browse the repository at this point in the history
This is especially useful when one wants to iterate over rows or
columns of a 2d array in reverse.

Co-authored-by: Ulrik Sverdrup <bluss@users.noreply.github.com>
  • Loading branch information
Muthsera and bluss committed Mar 10, 2024
1 parent ba8f45c commit 2033b76
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/iterators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,15 @@ where
}
}

impl<'a, A> DoubleEndedIterator for LanesIter<'a, A, Ix1>
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(|ptr| unsafe {
ArrayView::new_(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix))
})
}
}

// NOTE: LanesIterMut is a mutable iterator and must not expose aliasing
// pointers. Due to this we use an empty slice for the raw data (it's unused
// anyway).
Expand Down Expand Up @@ -772,6 +781,15 @@ where
}
}

impl<'a, A> DoubleEndedIterator for LanesIterMut<'a, A, Ix1>
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(|ptr| unsafe {
ArrayViewMut::new_(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix))
})
}
}

#[derive(Debug)]
pub struct AxisIterCore<A, D> {
/// Index along the axis of the value of `.next()`, relative to the start
Expand Down
16 changes: 16 additions & 0 deletions tests/iterators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ fn double_ended() {
assert_equal(aview1(&[1, 2, 3]).into_iter().rev(), [1, 2, 3].iter().rev());
}

#[test]
fn double_ended_rows() {
let a = ArcArray::from_iter(0..8).into_shape_clone((4, 2)).unwrap();
let mut row_it = a.rows().into_iter();
assert_equal(row_it.next_back().unwrap(), &[6, 7]);
assert_equal(row_it.next().unwrap(), &[0, 1]);
assert_equal(row_it.next_back().unwrap(), &[4, 5]);
assert_equal(row_it.next_back().unwrap(), &[2, 3]);
assert!(row_it.next().is_none());
assert!(row_it.next_back().is_none());

for (row, check) in a.rows().into_iter().rev().zip(&[[6, 7], [4, 5], [2, 3], [0, 1]]) {
assert_equal(row, check);
}
}

#[test]
fn iter_size_hint() {
// Check that the size hint is correctly computed
Expand Down

0 comments on commit 2033b76

Please sign in to comment.