forked from M-Labs/nalgebra
Merge pull request #797 from Recmo/remco/feat/double-ended-iter
impl DoubleEndedIterator for {MatrixIter, MatrixIterMut}
This commit is contained in:
commit
bc6faa22f3
@ -136,6 +136,30 @@ fn mat500_mul_mat500(bench: &mut criterion::Criterion) {
|
||||
bench.bench_function("mat500_mul_mat500", move |bh| bh.iter(|| &a * &b));
|
||||
}
|
||||
|
||||
fn iter(bench: &mut criterion::Criterion) {
|
||||
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||
|
||||
bench.bench_function("iter", move |bh| {
|
||||
bh.iter(|| {
|
||||
for value in a.iter() {
|
||||
criterion::black_box(value);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn iter_rev(bench: &mut criterion::Criterion) {
|
||||
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||
|
||||
bench.bench_function("iter_rev", move |bh| {
|
||||
bh.iter(|| {
|
||||
for value in a.iter().rev() {
|
||||
criterion::black_box(value);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn copy_from(bench: &mut criterion::Criterion) {
|
||||
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||
let mut b = DMatrix::<f64>::new_random(1000, 1000);
|
||||
@ -235,6 +259,8 @@ criterion_group!(
|
||||
mat10_mul_mat10_static,
|
||||
mat100_mul_mat100,
|
||||
mat500_mul_mat500,
|
||||
iter,
|
||||
iter_rev,
|
||||
copy_from,
|
||||
axpy,
|
||||
tr_mul_to,
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Matrix iterators.
|
||||
|
||||
use std::iter::FusedIterator;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
@ -111,6 +112,46 @@ macro_rules! iterator {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> DoubleEndedIterator
|
||||
for $Name<'a, N, R, C, S>
|
||||
{
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<$Ref> {
|
||||
unsafe {
|
||||
if self.size == 0 {
|
||||
None
|
||||
} else {
|
||||
// Pre-decrement `size` such that it now counts to the
|
||||
// element we want to return.
|
||||
self.size -= 1;
|
||||
|
||||
// Fetch strides
|
||||
let inner_stride = self.strides.0.value();
|
||||
let outer_stride = self.strides.1.value();
|
||||
|
||||
// Compute number of rows
|
||||
// Division should be exact
|
||||
let inner_raw_size = self.inner_end.offset_from(self.inner_ptr) as usize;
|
||||
let inner_size = inner_raw_size / inner_stride;
|
||||
|
||||
// Compute rows and cols remaining
|
||||
let outer_remaining = self.size / inner_size;
|
||||
let inner_remaining = self.size % inner_size;
|
||||
|
||||
// Compute pointer to last element
|
||||
let last = self.ptr.offset(
|
||||
(outer_remaining * outer_stride + inner_remaining * inner_stride)
|
||||
as isize,
|
||||
);
|
||||
|
||||
// We want either `& *last` or `&mut *last` here, depending
|
||||
// on the mutability of `$Ref`.
|
||||
Some(mem::transmute(last))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> ExactSizeIterator
|
||||
for $Name<'a, N, R, C, S>
|
||||
{
|
||||
@ -119,6 +160,11 @@ macro_rules! iterator {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> FusedIterator
|
||||
for $Name<'a, N, R, C, S>
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,24 @@ fn iter() {
|
||||
assert_eq!(*it.next().unwrap(), 6.0);
|
||||
assert!(it.next().is_none());
|
||||
|
||||
let mut it = a.iter();
|
||||
assert_eq!(*it.next().unwrap(), 1.0);
|
||||
assert_eq!(*it.next_back().unwrap(), 6.0);
|
||||
assert_eq!(*it.next_back().unwrap(), 3.0);
|
||||
assert_eq!(*it.next_back().unwrap(), 5.0);
|
||||
assert_eq!(*it.next().unwrap(), 4.0);
|
||||
assert_eq!(*it.next().unwrap(), 2.0);
|
||||
assert!(it.next().is_none());
|
||||
|
||||
let mut it = a.iter().rev();
|
||||
assert_eq!(*it.next().unwrap(), 6.0);
|
||||
assert_eq!(*it.next().unwrap(), 3.0);
|
||||
assert_eq!(*it.next().unwrap(), 5.0);
|
||||
assert_eq!(*it.next().unwrap(), 2.0);
|
||||
assert_eq!(*it.next().unwrap(), 4.0);
|
||||
assert_eq!(*it.next().unwrap(), 1.0);
|
||||
assert!(it.next().is_none());
|
||||
|
||||
let row = a.row(0);
|
||||
let mut it = row.iter();
|
||||
assert_eq!(*it.next().unwrap(), 1.0);
|
||||
|
Loading…
Reference in New Issue
Block a user