Repository: bluss/rust-ndarray
Pull request #230 (2016-11-11 23:00:19)

Iterator struct names, constructors & consistency
Rename iterators to match conventions.

Rename Indexes to Indices, and change it to be created using a free function. Now both functions `indices` and `indices_of` exist.


Patch:
diff --git a/src/array_serde.rs b/src/array_serde.rs
index 89adcd9d..d80d8a46 100644
--- a/src/array_serde.rs
+++ b/src/array_serde.rs
@@ -12,7 +12,7 @@ use std::marker::PhantomData;
 use imp_prelude::*;
 
 use super::arraytraits::ARRAY_FORMAT_VERSION;
-use super::Elements;
+use super::Iter;
 use Dim;
 use dimension::DimPrivate;
 
@@ -57,7 +57,7 @@ impl<A, D, S> Serialize for ArrayBase<S, D>
 }
 
 // private iterator wrapper
-struct Sequence<'a, A: 'a, D>(Elements<'a, A, D>);
+struct Sequence<'a, A: 'a, D>(Iter<'a, A, D>);
 
 impl<'a, A, D> Serialize for Sequence<'a, A, D>
     where A: Serialize,
diff --git a/src/arraytraits.rs b/src/arraytraits.rs
index 7e4739c7..e165f898 100644
--- a/src/arraytraits.rs
+++ b/src/arraytraits.rs
@@ -16,8 +16,8 @@ use std::ops::{
 
 use imp_prelude::*;
 use {
-    Elements,
-    ElementsMut,
+    Iter,
+    IterMut,
     NdIndex,
 };
 
@@ -127,7 +127,7 @@ impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
           S: Data,
 {
     type Item = &'a S::Elem;
-    type IntoIter = Elements<'a, S::Elem, D>;
+    type IntoIter = Iter<'a, S::Elem, D>;
 
     fn into_iter(self) -> Self::IntoIter {
         self.iter()
@@ -139,7 +139,7 @@ impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
           S: DataMut
 {
     type Item = &'a mut S::Elem;
-    type IntoIter = ElementsMut<'a, S::Elem, D>;
+    type IntoIter = IterMut<'a, S::Elem, D>;
 
     fn into_iter(self) -> Self::IntoIter {
         self.iter_mut()
@@ -150,7 +150,7 @@ impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
     where D: Dimension
 {
     type Item = &'a A;
-    type IntoIter = Elements<'a, A, D>;
+    type IntoIter = Iter<'a, A, D>;
 
     fn into_iter(self) -> Self::IntoIter {
         self.into_iter_()
@@ -161,7 +161,7 @@ impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
     where D: Dimension
 {
     type Item = &'a mut A;
-    type IntoIter = ElementsMut<'a, A, D>;
+    type IntoIter = IterMut<'a, A, D>;
 
     fn into_iter(self) -> Self::IntoIter {
         self.into_iter_()
diff --git a/src/impl_constructors.rs b/src/impl_constructors.rs
index c27ed385..fd6e93d3 100644
--- a/src/impl_constructors.rs
+++ b/src/impl_constructors.rs
@@ -17,7 +17,7 @@ use StrideShape;
 use dimension;
 use linspace;
 use error::{self, ShapeError, ErrorKind};
-use Indexes;
+use indices;
 use iterators::{to_vec, to_vec_mapped};
 
 /// # Constructor Methods for Owned Arrays
@@ -184,7 +184,7 @@ impl<S, A, D> ArrayBase<S, D>
               F: FnMut(D::Pattern) -> A,
     {
         let shape = shape.into_shape();
-        let v = to_vec_mapped(Indexes::new(shape.dim.clone()), f);
+        let v = to_vec_mapped(indices(shape.dim.clone()), f);
         unsafe { Self::from_shape_vec_unchecked(shape, v) }
     }
 
diff --git a/src/impl_methods.rs b/src/impl_methods.rs
index 1c117870..5b936f4a 100644
--- a/src/impl_methods.rs
+++ b/src/impl_methods.rs
@@ -26,10 +26,10 @@ use {
     NdIndex,
     AxisChunksIter,
     AxisChunksIterMut,
-    Elements,
-    ElementsMut,
-    Indexed,
-    IndexedMut,
+    Iter,
+    IterMut,
+    IndexedIter,
+    IndexedIterMut,
     InnerIter,
     InnerIterMut,
     AxisIter,
@@ -132,16 +132,22 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
 
     /// Return an iterator of references to the elements of the array.
     ///
+    /// Elements are visited in the *logical order* of the array, which
+    /// is where the rightmost index is varying the fastest.
+    ///
     /// Iterator element type is `&A`.
-    pub fn iter(&self) -> Elements<A, D> {
+    pub fn iter(&self) -> Iter<A, D> {
         debug_assert!(self.pointer_is_inbounds());
         self.view().into_iter_()
     }
 
     /// Return an iterator of mutable references to the elements of the array.
     ///
+    /// Elements are visited in the *logical order* of the array, which
+    /// is where the rightmost index is varying the fastest.
+    ///
     /// Iterator element type is `&mut A`.
-    pub fn iter_mut(&mut self) -> ElementsMut<A, D>
+    pub fn iter_mut(&mut self) -> IterMut<A, D>
         where S: DataMut,
     {
         self.view_mut().into_iter_()
@@ -150,17 +156,17 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
     /// Return an iterator of indexes and references to the elements of the array.
     ///
     /// Iterator element type is `(D::Pattern, &A)`.
-    pub fn indexed_iter(&self) -> Indexed<A, D> {
-        Indexed(self.view().into_elements_base())
+    pub fn indexed_iter(&self) -> IndexedIter<A, D> {
+        IndexedIter(self.view().into_elements_base())
     }
 
     /// Return an iterator of indexes and mutable references to the elements of the array.
     ///
     /// Iterator element type is `(D::Pattern, &mut A)`.
-    pub fn indexed_iter_mut(&mut self) -> IndexedMut<A, D>
+    pub fn indexed_iter_mut(&mut self) -> IndexedIterMut<A, D>
         where S: DataMut,
     {
-        IndexedMut(self.view_mut().into_elements_base())
+        IndexedIterMut(self.view_mut().into_elements_base())
     }
 
 
@@ -485,6 +491,7 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
     /// Return an iterator that traverses over the outermost dimension
     /// and yields each subview.
     ///
+    /// The outer iterator is equivalent to `.axis_iter(Axis(0))`.
     /// For example, in a 2 × 2 × 3 array, the iterator element
     /// is a 2 × 3 subview (and there are 2 in total).
     ///
@@ -512,6 +519,8 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
     /// Return an iterator that traverses over the outermost dimension
     /// and yields each subview.
     ///
+    /// The outer iterator is equivalent to `.axis_iter_mut(Axis(0))`.
+    ///
     /// Iterator element is `ArrayViewMut<A, D::Smaller>` (read-write array view).
     #[allow(deprecated)]
     pub fn outer_iter_mut(&mut self) -> AxisIterMut<A, D::Smaller>
diff --git a/src/indexes.rs b/src/indexes.rs
index 7744b9d9..030e0d3a 100644
--- a/src/indexes.rs
+++ b/src/indexes.rs
@@ -5,6 +5,7 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
+use {ArrayBase, Data};
 use super::Dimension;
 use dimension::IntoDimension;
 
@@ -12,25 +13,36 @@ use dimension::IntoDimension;
 ///
 /// Iterator element type is `D`.
 #[derive(Clone)]
-pub struct Indexes<D> {
+pub struct Indices<D> {
     dim: D,
     index: Option<D>,
 }
 
-impl<D: Dimension> Indexes<D> {
-    /// Create an iterator over the array shape `dim`.
-    pub fn new<E>(shape: E) -> Indexes<D>
-        where E: IntoDimension<Dim=D>,
-    {
-        let dim = shape.into_dimension();
-        Indexes {
-            index: dim.first_index(),
-            dim: dim,
-        }
+/// Create an iterator over the array shape `shape`.
+///
+/// *Note:* prefer higher order methods, arithmetic operations and
+/// non-indexed iteration before using indices.
+pub fn indices<E>(shape: E) -> Indices<E::Dim>
+    where E: IntoDimension,
+{
+    let dim = shape.into_dimension();
+    Indices {
+        index: dim.first_index(),
+        dim: dim,
     }
 }
 
-impl<D> Iterator for Indexes<D>
+/// Create an iterator over the indices of the passed-in array.
+///
+/// *Note:* prefer higher order methods, arithmetic operations and
+/// non-indexed iteration before using indices.
+pub fn indices_of<S, D>(array: &ArrayBase<S, D>) -> Indices<D>
+    where S: Data, D: Dimension,
+{
+    indices(array.dim())
+}
+
+impl<D> Iterator for Indices<D>
     where D: Dimension,
 {
     type Item = D::Pattern;
@@ -61,6 +73,6 @@ impl<D> Iterator for Indexes<D>
     }
 }
 
-impl<D> ExactSizeIterator for Indexes<D>
+impl<D> ExactSizeIterator for Indices<D>
     where D: Dimension
 {}
diff --git a/src/iterators.rs b/src/iterators.rs
index 7118b406..1fe7c39d 100644
--- a/src/iterators.rs
+++ b/src/iterators.rs
@@ -11,7 +11,7 @@ use std::ptr;
 use Ix1;
 
 use super::{Dimension, Ix, Ixs};
-use super::{Elements, ElementsRepr, ElementsBase, ElementsBaseMut, ElementsMut, Indexed, IndexedMut};
+use super::{Iter, ElementsRepr, ElementsBase, ElementsBaseMut, IterMut, IndexedIter, IndexedIterMut};
 use super::{
     ArrayBase,
     Data,
@@ -216,9 +216,9 @@ macro_rules! either_mut {
 }
 
 
-impl<'a, A, D: Clone> Clone for Elements<'a, A, D> {
-    fn clone(&self) -> Elements<'a, A, D> {
-        Elements {
+impl<'a, A, D: Clone> Clone for Iter<'a, A, D> {
+    fn clone(&self) -> Iter<'a, A, D> {
+        Iter {
             inner: match self.inner {
                 ElementsRepr::Slice(ref iter) => ElementsRepr::Slice(iter.clone()),
                 ElementsRepr::Counted(ref iter) => {
@@ -229,7 +229,7 @@ impl<'a, A, D: Clone> Clone for Elements<'a, A, D> {
     }
 }
 
-impl<'a, A, D: Dimension> Iterator for Elements<'a, A, D> {
+impl<'a, A, D: Dimension> Iterator for Iter<'a, A, D> {
     type Item = &'a A;
     #[inline]
     fn next(&mut self) -> Option<&'a A> {
@@ -247,19 +247,19 @@ impl<'a, A, D: Dimension> Iterator for Elements<'a, A, D> {
     }
 }
 
-impl<'a, A> DoubleEndedIterator for Elements<'a, A, Ix1> {
+impl<'a, A> DoubleEndedIterator for Iter<'a, A, Ix1> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a A> {
         either_mut!(self.inner, iter => iter.next_back())
     }
 }
 
-impl<'a, A, D> ExactSizeIterator for Elements<'a, A, D>
+impl<'a, A, D> ExactSizeIterator for Iter<'a, A, D>
     where D: Dimension
 {}
 
 
-impl<'a, A, D: Dimension> Iterator for Indexed<'a, A, D> {
+impl<'a, A, D: Dimension> Iterator for IndexedIter<'a, A, D> {
     type Item = (D::Pattern, &'a A);
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
@@ -279,11 +279,11 @@ impl<'a, A, D: Dimension> Iterator for Indexed<'a, A, D> {
     }
 }
 
-impl<'a, A, D> ExactSizeIterator for Indexed<'a, A, D>
+impl<'a, A, D> ExactSizeIterator for IndexedIter<'a, A, D>
     where D: Dimension
 {}
 
-impl<'a, A, D: Dimension> Iterator for ElementsMut<'a, A, D> {
+impl<'a, A, D: Dimension> Iterator for IterMut<'a, A, D> {
     type Item = &'a mut A;
     #[inline]
     fn next(&mut self) -> Option<&'a mut A> {
@@ -301,14 +301,14 @@ impl<'a, A, D: Dimension> Iterator for ElementsMut<'a, A, D> {
     }
 }
 
-impl<'a, A> DoubleEndedIterator for ElementsMut<'a, A, Ix1> {
+impl<'a, A> DoubleEndedIterator for IterMut<'a, A, Ix1> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut A> {
         either_mut!(self.inner, iter => iter.next_back())
     }
 }
 
-impl<'a, A, D> ExactSizeIterator for ElementsMut<'a, A, D>
+impl<'a, A, D> ExactSizeIterator for IterMut<'a, A, D>
     where D: Dimension
 {}
 
@@ -340,7 +340,7 @@ impl<'a, A> DoubleEndedIterator for ElementsBaseMut<'a, A, Ix1> {
     }
 }
 
-impl<'a, A, D: Dimension> Iterator for IndexedMut<'a, A, D> {
+impl<'a, A, D: Dimension> Iterator for IndexedIterMut<'a, A, D> {
     type Item = (D::Pattern, &'a mut A);
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
@@ -360,7 +360,7 @@ impl<'a, A, D: Dimension> Iterator for IndexedMut<'a, A, D> {
     }
 }
 
-impl<'a, A, D> ExactSizeIterator for IndexedMut<'a, A, D>
+impl<'a, A, D> ExactSizeIterator for IndexedIterMut<'a, A, D>
     where D: Dimension
 {}
 
@@ -946,14 +946,14 @@ macro_rules! send_sync_read_write {
     }
 }
 
-send_sync_read_only!(Elements);
-send_sync_read_only!(Indexed);
+send_sync_read_only!(Iter);
+send_sync_read_only!(IndexedIter);
 send_sync_read_only!(InnerIter);
 send_sync_read_only!(AxisIter);
 send_sync_read_only!(AxisChunksIter);
 
-send_sync_read_write!(ElementsMut);
-send_sync_read_write!(IndexedMut);
+send_sync_read_write!(IterMut);
+send_sync_read_write!(IndexedIterMut);
 send_sync_read_write!(InnerIterMut);
 send_sync_read_write!(AxisIterMut);
 send_sync_read_write!(AxisChunksIterMut);
@@ -965,15 +965,15 @@ pub unsafe trait TrustedIterator { }
 use std::slice;
 use std::iter;
 use linspace::Linspace;
-use indexes::Indexes;
+use indexes::Indices;
 
 unsafe impl<F> TrustedIterator for Linspace<F> { }
-unsafe impl<'a, A, D> TrustedIterator for Elements<'a, A, D> { }
+unsafe impl<'a, A, D> TrustedIterator for Iter<'a, A, D> { }
 unsafe impl<I, F> TrustedIterator for iter::Map<I, F>
     where I: TrustedIterator { }
 unsafe impl<'a, A> TrustedIterator for slice::Iter<'a, A> { }
 unsafe impl TrustedIterator for ::std::ops::Range<usize> { }
-unsafe impl<D> TrustedIterator for Indexes<D> where D: Dimension { }
+unsafe impl<D> TrustedIterator for Indices<D> where D: Dimension { }
 
 
 /// Like Iterator::collect, but only for trusted length iterators
diff --git a/src/lib.rs b/src/lib.rs
index eb5e2526..cb57e078 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -81,9 +81,10 @@ extern crate itertools;
 extern crate num_traits as libnum;
 extern crate num_complex;
 
-use std::rc::Rc;
-use std::slice::{self, Iter, IterMut};
+use std::iter::Zip;
 use std::marker::PhantomData;
+use std::rc::Rc;
+use std::slice::{self, Iter as SliceIter, IterMut as SliceIterMut};
 
 pub use dimension::{
     Dimension,
@@ -94,7 +95,8 @@ pub use dimension::{
 pub use dimension::dim::*;
 
 pub use dimension::NdIndex;
-pub use indexes::Indexes;
+pub use indexes::Indices;
+pub use indexes::{indices, indices_of};
 pub use error::{ShapeError, ErrorKind};
 pub use si::{Si, S};
 
@@ -304,7 +306,8 @@ pub type Ixs = isize;
 /// A *column major* (a.k.a. “f” or fortran) memory order array has
 /// columns (or, in general, the outermost axis) with contiguous elements.
 ///
-/// The logical order of any array’s elements is the row major order.
+/// The logical order of any array’s elements is the row major order 
+/// (the rightmost index is varying the fastest).
 /// The iterators `.iter(), .iter_mut()` always adhere to this order, for example.
 ///
 /// ## Slicing
@@ -618,8 +621,8 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a A>, D>
         ElementsBase { inner: self.into_base_iter() }
     }
 
-    fn into_iter_(self) -> Elements<'a, A, D> {
-        Elements {
+    fn into_iter_(self) -> Iter<'a, A, D> {
+        Iter {
             inner: if let Some(slc) = self.into_slice() {
                 ElementsRepr::Slice(slc.iter())
             } else {
@@ -677,8 +680,8 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a mut A>, D>
         ElementsBaseMut { inner: self.into_base_iter() }
     }
 
-    fn into_iter_(self) -> ElementsMut<'a, A, D> {
-        ElementsMut {
+    fn into_iter_(self) -> IterMut<'a, A, D> {
+        IterMut {
             inner:
                 if self.is_standard_layout() {
                     let slc = unsafe {
@@ -718,8 +721,8 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a mut A>, D>
 /// Iterator element type is `&'a A`.
 ///
 /// See [`.iter()`](struct.ArrayBase.html#method.iter) for more information.
-pub struct Elements<'a, A: 'a, D> {
-    inner: ElementsRepr<Iter<'a, A>, ElementsBase<'a, A, D>>,
+pub struct Iter<'a, A: 'a, D> {
+    inner: ElementsRepr<SliceIter<'a, A>, ElementsBase<'a, A, D>>,
 }
 
 /// Counted read only iterator
@@ -732,8 +735,8 @@ struct ElementsBase<'a, A: 'a, D> {
 /// Iterator element type is `&'a mut A`.
 ///
 /// See [`.iter_mut()`](struct.ArrayBase.html#method.iter_mut) for more information.
-pub struct ElementsMut<'a, A: 'a, D> {
-    inner: ElementsRepr<IterMut<'a, A>, ElementsBaseMut<'a, A, D>>,
+pub struct IterMut<'a, A: 'a, D> {
+    inner: ElementsRepr<SliceIterMut<'a, A>, ElementsBaseMut<'a, A, D>>,
 }
 
 /// An iterator over the elements of an array.
@@ -747,15 +750,12 @@ struct ElementsBaseMut<'a, A: 'a, D> {
 ///
 /// See [`.indexed_iter()`](struct.ArrayBase.html#method.indexed_iter) for more information.
 #[derive(Clone)]
-pub struct Indexed<'a, A: 'a, D>(ElementsBase<'a, A, D>);
+pub struct IndexedIter<'a, A: 'a, D>(ElementsBase<'a, A, D>);
 /// An iterator over the indexes and elements of an array (mutable).
 ///
 /// See [`.indexed_iter_mut()`](struct.ArrayBase.html#method.indexed_iter_mut) for more information.
-pub struct IndexedMut<'a, A: 'a, D>(ElementsBaseMut<'a, A, D>);
+pub struct IndexedIterMut<'a, A: 'a, D>(ElementsBaseMut<'a, A, D>);
 
-use std::slice::Iter as SliceIter;
-use std::slice::IterMut as SliceIterMut;
-use std::iter::Zip;
 fn zipsl<'a, 'b, A, B>(t: &'a [A], u: &'b [B])
     -> Zip<SliceIter<'a, A>, SliceIter<'b, B>> {
     t.iter().zip(u)


Test patch:
diff --git a/tests/array.rs b/tests/array.rs
index 6728c3ae..173567d8 100644
--- a/tests/array.rs
+++ b/tests/array.rs
@@ -12,7 +12,7 @@ use ndarray::{
     aview_mut1,
     Ix0, Ix2,
 };
-use ndarray::Indexes;
+use ndarray::indices;
 use itertools::free::enumerate;
 
 #[test]
@@ -90,13 +90,13 @@ fn test_index()
         *elt = i;
     }
 
-    for ((i, j), a) in Indexes::new((2, 3)).zip(A.iter()) {
+    for ((i, j), a) in indices((2, 3)).zip(A.iter()) {
         assert_eq!(*a, A[[i, j]]);
     }
 
     let vi = A.slice(&[Si(1, None, 1), Si(0, None, 2)]);
     let mut it = vi.iter();
-    for ((i, j), x) in Indexes::new((1, 2)).zip(it.by_ref()) {
+    for ((i, j), x) in indices((1, 2)).zip(it.by_ref()) {
         assert_eq!(*x, vi[[i, j]]);
     }
     assert!(it.next().is_none());
diff --git a/tests/iterators.rs b/tests/iterators.rs
index 94f316c0..104ef775 100644
--- a/tests/iterators.rs
+++ b/tests/iterators.rs
@@ -13,7 +13,7 @@ use ndarray::{
     arr2,
     arr3,
     Axis,
-    Indexes,
+    indices,
 };
 
 use itertools::assert_equal;
@@ -479,7 +479,7 @@ fn iterators_are_send_sync() {
     _send_sync(&a.axis_iter_mut(Axis(1)));
     _send_sync(&a.axis_chunks_iter(Axis(1), 1));
     _send_sync(&a.axis_chunks_iter_mut(Axis(1), 1));
-    _send_sync(&Indexes::new(a.dim()));
+    _send_sync(&indices(a.dim()));
 }
 
 #[test]