Initial draft for into_row_iter and into_column_iter
https://github.com/dimforge/nalgebra/issues/834
This commit is contained in:
parent
6ed6084745
commit
267eb01fe5
|
@ -18,7 +18,7 @@ use crate::base::{DefaultAllocator, Scalar};
|
|||
/// same `Buffer` type.
|
||||
pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
|
||||
/// The type of buffer this allocator can instanciate.
|
||||
type Buffer: ContiguousStorageMut<N, R, C> + Clone;
|
||||
type Buffer: ContiguousStorageMut<N, R, C> + Clone + IntoIterator<Item=N>;
|
||||
|
||||
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
||||
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer;
|
||||
|
|
|
@ -46,6 +46,20 @@ where
|
|||
data: GenericArray<N, Prod<R::Value, C::Value>>,
|
||||
}
|
||||
|
||||
impl<N, R, C> IntoIterator for ArrayStorage<N, R, C>
|
||||
where
|
||||
R: DimName,
|
||||
C: DimName,
|
||||
R::Value: Mul<C::Value>,
|
||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
||||
{
|
||||
type Item = N;
|
||||
type IntoIter = <GenericArray<N, Prod<R::Value, C::Value>> as IntoIterator>::IntoIter;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.data.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(note = "renamed to `ArrayStorage`")]
|
||||
/// Renamed to [ArrayStorage].
|
||||
pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>;
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::base::dimension::{
|
|||
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
|
||||
};
|
||||
use crate::base::iter::{MatrixIter, MatrixIterMut};
|
||||
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
|
||||
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut, Owned};
|
||||
use crate::base::{
|
||||
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixMN, MatrixSlice,
|
||||
MatrixSliceMut, Scalar,
|
||||
|
@ -86,6 +86,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar, R: Dim, C: Dim> IntoIterator for Matrix<N, R, C, Owned<N, R, C>>
|
||||
where DefaultAllocator: Allocator<N, R, C>
|
||||
{
|
||||
type Item = N;
|
||||
type IntoIter = <Owned<N, R, C> as IntoIterator>::IntoIter;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
<Owned<N, R, C> as IntoIterator>::into_iter(self.data)
|
||||
}
|
||||
}
|
||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Matrix<N, R, C, S> {
|
||||
type Item = &'a N;
|
||||
type IntoIter = MatrixIter<'a, N, R, C, S>;
|
||||
|
|
114
src/base/iter.rs
114
src/base/iter.rs
|
@ -3,9 +3,9 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
use crate::base::dimension::{Dim, U1};
|
||||
use crate::base::storage::{Storage, StorageMut};
|
||||
use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar};
|
||||
use crate::base::dimension::{Dim, U1, Dynamic};
|
||||
use crate::base::storage::{Storage, StorageMut, Owned};
|
||||
use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar, Vector, RowVector};
|
||||
|
||||
macro_rules! iterator {
|
||||
(struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
|
||||
|
@ -237,6 +237,58 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
|
|||
}
|
||||
}
|
||||
|
||||
/// An owned iterator through the rows of a matrix.
|
||||
pub struct OwnedRowIter<N: Scalar> {
|
||||
rows: std::vec::IntoIter<RowVector<N, Dynamic, Owned<N, U1, Dynamic>>>,
|
||||
}
|
||||
|
||||
impl<N: Scalar> OwnedRowIter<N> {
|
||||
pub(crate) fn new(mat: Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>>) -> Self {
|
||||
let ncols = mat.ncols();
|
||||
let nrows = mat.nrows();
|
||||
let mut rows: Vec<Vec<N>> = vec![Vec::with_capacity(ncols); nrows];
|
||||
let mut i = 0;
|
||||
for item in mat.into_iter() {
|
||||
rows[i % nrows].push(item);
|
||||
i += 1;
|
||||
}
|
||||
let rows: Vec<RowVector<N, Dynamic, Owned<N, U1, Dynamic>>> =
|
||||
rows.into_iter()
|
||||
.map(|row| RowVector::<N, Dynamic, Owned<N, U1, Dynamic>>::from_iterator_generic(
|
||||
U1::from_usize(1), Dynamic::from_usize(ncols), row.into_iter()))
|
||||
.collect();
|
||||
OwnedRowIter { rows: rows.into_iter() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar> Iterator for OwnedRowIter<N> {
|
||||
type Item = RowVector<N, Dynamic, Owned<N, U1, Dynamic>>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.rows.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.rows.size_hint()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.rows.count()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar> ExactSizeIterator
|
||||
for OwnedRowIter<N>
|
||||
{
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.rows.len()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Column iterators.
|
||||
|
@ -350,3 +402,59 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
|
|||
self.ncols() - self.curr
|
||||
}
|
||||
}
|
||||
|
||||
/// An owned iterator through the rows of a matrix.
|
||||
pub struct OwnedColumnIter<N: Scalar> {
|
||||
cols: std::vec::IntoIter<Vector<N, Dynamic, Owned<N, Dynamic, U1>>>,
|
||||
}
|
||||
|
||||
impl<N: Scalar> OwnedColumnIter<N> {
|
||||
pub(crate) fn new(mat: Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>>) -> Self {
|
||||
let ncols = mat.ncols();
|
||||
let nrows = mat.nrows();
|
||||
let mut cols: Vec<Vec<N>> = vec![Vec::with_capacity(nrows); ncols];
|
||||
let mut i = 0;
|
||||
for item in mat.into_iter() {
|
||||
cols[i / nrows].push(item);
|
||||
i += 1;
|
||||
}
|
||||
let cols: Vec<Vector<N, Dynamic, Owned<N, Dynamic, U1>>> =
|
||||
cols.into_iter()
|
||||
.map(|col|
|
||||
Vector::<N, Dynamic, Owned<N, Dynamic, U1>>::from_iterator_generic(
|
||||
Dynamic::from_usize(nrows),
|
||||
U1::from_usize(1),
|
||||
col.into_iter()
|
||||
)
|
||||
)
|
||||
.collect();
|
||||
OwnedColumnIter { cols: cols.into_iter() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar> Iterator for OwnedColumnIter<N> {
|
||||
type Item = Vector<N, Dynamic, Owned<N, Dynamic, U1>>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.cols.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.cols.size_hint()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.cols.count()
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar> ExactSizeIterator
|
||||
for OwnedColumnIter<N> {
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.cols.len()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ use simba::simd::SimdPartialOrd;
|
|||
|
||||
use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR};
|
||||
use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
||||
use crate::base::dimension::{Dim, DimAdd, DimSum, IsNotStaticOne, U1, U2, U3};
|
||||
use crate::base::dimension::{Dim, DimAdd, DimSum, IsNotStaticOne, U1, U2, U3, Dynamic};
|
||||
use crate::base::iter::{
|
||||
ColumnIter, ColumnIterMut, MatrixIter, MatrixIterMut, RowIter, RowIterMut,
|
||||
ColumnIter, ColumnIterMut, OwnedColumnIter, MatrixIter, MatrixIterMut, RowIter, RowIterMut, OwnedRowIter,
|
||||
};
|
||||
use crate::base::storage::{
|
||||
ContiguousStorage, ContiguousStorageMut, Owned, SameShapeStorage, Storage, StorageMut,
|
||||
ContiguousStorage, ContiguousStorageMut, SameShapeStorage, Storage, StorageMut, Owned
|
||||
};
|
||||
use crate::base::{DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN};
|
||||
use crate::SimdComplexField;
|
||||
|
@ -859,6 +859,45 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar> Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>> {
|
||||
/// Move rows of this matrix into an owned iterator.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use nalgebra::DMatrix;
|
||||
/// let values = vec![1, 4, 2, 5, 3, 6].into_iter();
|
||||
/// let mut a = DMatrix::from_iterator(2, 3, values);
|
||||
/// let c = a.clone();
|
||||
/// for (i, row) in a.into_row_iter().enumerate() {
|
||||
/// for (v1, &v2) in row.into_iter().zip(c.row(i).iter()) {
|
||||
/// assert_eq!(v1, v2)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn into_row_iter(self) -> OwnedRowIter<N> {
|
||||
OwnedRowIter::new(self)
|
||||
}
|
||||
|
||||
/// Move columns of this matrix into an owned iterator.
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use nalgebra::DMatrix;
|
||||
/// let values = vec![1, 4, 2, 5, 3, 6].into_iter();
|
||||
/// let mut a = DMatrix::from_iterator(2, 3, values);
|
||||
/// let c = a.clone();
|
||||
/// for (i, column) in a.into_column_iter().enumerate() {
|
||||
/// for (v1, &v2) in column.into_iter().zip(c.column(i).iter()) {
|
||||
/// assert_eq!(v1, v2)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn into_column_iter(self) -> OwnedColumnIter<N> {
|
||||
OwnedColumnIter::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// # Iteration on components, rows, and columns
|
||||
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
/// Iterates through this matrix coordinates in column-major order.
|
||||
|
|
|
@ -31,6 +31,18 @@ pub struct VecStorage<N, R: Dim, C: Dim> {
|
|||
ncols: C,
|
||||
}
|
||||
|
||||
impl<N, R, C> IntoIterator for VecStorage<N, R, C>
|
||||
where
|
||||
R: Dim,
|
||||
C: Dim,
|
||||
{
|
||||
type Item = N;
|
||||
type IntoIter = <Vec<N> as IntoIterator>::IntoIter;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.data.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(note = "renamed to `VecStorage`")]
|
||||
/// Renamed to [VecStorage].
|
||||
pub type MatrixVec<N, R, C> = VecStorage<N, R, C>;
|
||||
|
|
Loading…
Reference in New Issue