diff --git a/src/data_repr.rs b/src/data_repr.rs
index a24cd7789..4041c192b 100644
--- a/src/data_repr.rs
+++ b/src/data_repr.rs
@@ -59,11 +59,6 @@ impl OwnedRepr
self.ptr.as_ptr()
}
- pub(crate) fn as_ptr_mut(&self) -> *mut A
- {
- self.ptr.as_ptr()
- }
-
pub(crate) fn as_nonnull_mut(&mut self) -> NonNull
{
self.ptr
diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs
index db176210c..44ac12dd4 100644
--- a/src/impl_owned_array.rs
+++ b/src/impl_owned_array.rs
@@ -1,9 +1,10 @@
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
+use core::ptr::NonNull;
use std::mem;
use std::mem::MaybeUninit;
-#[allow(unused_imports)]
+#[allow(unused_imports)] // Needed for Rust 1.64
use rawpointer::PointerExt;
use crate::imp_prelude::*;
@@ -435,7 +436,7 @@ where D: Dimension
// "deconstruct" self; the owned repr releases ownership of all elements and we
// carry on with raw view methods
let data_len = self.data.len();
- let data_ptr = self.data.as_nonnull_mut().as_ptr();
+ let data_ptr = self.data.as_nonnull_mut();
unsafe {
// Safety: self.data releases ownership of the elements. Any panics below this point
@@ -866,8 +867,9 @@ where D: Dimension
///
/// This is an internal function for use by move_into and IntoIter only, safety invariants may need
/// to be upheld across the calls from those implementations.
-pub(crate) unsafe fn drop_unreachable_raw(mut self_: RawArrayViewMut, data_ptr: *mut A, data_len: usize)
-where D: Dimension
+pub(crate) unsafe fn drop_unreachable_raw(
+ mut self_: RawArrayViewMut, data_ptr: NonNull, data_len: usize,
+) where D: Dimension
{
let self_len = self_.len();
@@ -878,7 +880,7 @@ where D: Dimension
}
sort_axes_in_default_order(&mut self_);
// with uninverted axes this is now the element with lowest address
- let array_memory_head_ptr = self_.ptr.as_ptr();
+ let array_memory_head_ptr = self_.ptr;
let data_end_ptr = data_ptr.add(data_len);
debug_assert!(data_ptr <= array_memory_head_ptr);
debug_assert!(array_memory_head_ptr <= data_end_ptr);
@@ -907,7 +909,7 @@ where D: Dimension
// iter is a raw pointer iterator traversing the array in memory order now with the
// sorted axes.
- let mut iter = Baseiter::new(self_.ptr.as_ptr(), self_.dim, self_.strides);
+ let mut iter = Baseiter::new(self_.ptr, self_.dim, self_.strides);
let mut dropped_elements = 0;
let mut last_ptr = data_ptr;
@@ -917,7 +919,7 @@ where D: Dimension
// should now be dropped. This interval may be empty, then we just skip this loop.
while last_ptr != elem_ptr {
debug_assert!(last_ptr < data_end_ptr);
- std::ptr::drop_in_place(last_ptr);
+ std::ptr::drop_in_place(last_ptr.as_mut());
last_ptr = last_ptr.add(1);
dropped_elements += 1;
}
@@ -926,7 +928,7 @@ where D: Dimension
}
while last_ptr < data_end_ptr {
- std::ptr::drop_in_place(last_ptr);
+ std::ptr::drop_in_place(last_ptr.as_mut());
last_ptr = last_ptr.add(1);
dropped_elements += 1;
}
diff --git a/src/impl_views/conversions.rs b/src/impl_views/conversions.rs
index ef6923a56..1dd7d97f2 100644
--- a/src/impl_views/conversions.rs
+++ b/src/impl_views/conversions.rs
@@ -199,7 +199,7 @@ where D: Dimension
#[inline]
pub(crate) fn into_base_iter(self) -> Baseiter
{
- unsafe { Baseiter::new(self.ptr.as_ptr(), self.dim, self.strides) }
+ unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
}
}
@@ -209,7 +209,7 @@ where D: Dimension
#[inline]
pub(crate) fn into_base_iter(self) -> Baseiter
{
- unsafe { Baseiter::new(self.ptr.as_ptr(), self.dim, self.strides) }
+ unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
}
}
@@ -220,7 +220,7 @@ where D: Dimension
#[inline]
pub(crate) fn into_base_iter(self) -> Baseiter
{
- unsafe { Baseiter::new(self.ptr.as_ptr(), self.dim, self.strides) }
+ unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
}
#[inline]
@@ -262,7 +262,7 @@ where D: Dimension
#[inline]
pub(crate) fn into_base_iter(self) -> Baseiter
{
- unsafe { Baseiter::new(self.ptr.as_ptr(), self.dim, self.strides) }
+ unsafe { Baseiter::new(self.ptr, self.dim, self.strides) }
}
#[inline]
diff --git a/src/iterators/chunks.rs b/src/iterators/chunks.rs
index 465428968..9e2f08e1e 100644
--- a/src/iterators/chunks.rs
+++ b/src/iterators/chunks.rs
@@ -204,7 +204,7 @@ impl_iterator! {
fn item(&mut self, ptr) {
unsafe {
- ArrayView::new_(
+ ArrayView::new(
ptr,
self.chunk.clone(),
self.inner_strides.clone())
@@ -226,7 +226,7 @@ impl_iterator! {
fn item(&mut self, ptr) {
unsafe {
- ArrayViewMut::new_(
+ ArrayViewMut::new(
ptr,
self.chunk.clone(),
self.inner_strides.clone())
diff --git a/src/iterators/into_iter.rs b/src/iterators/into_iter.rs
index fcc2e4b8c..9374608cb 100644
--- a/src/iterators/into_iter.rs
+++ b/src/iterators/into_iter.rs
@@ -33,16 +33,15 @@ impl IntoIter
where D: Dimension
{
/// Create a new by-value iterator that consumes `array`
- pub(crate) fn new(mut array: Array) -> Self
+ pub(crate) fn new(array: Array) -> Self
{
unsafe {
let array_head_ptr = array.ptr;
- let ptr = array.as_mut_ptr();
let mut array_data = array.data;
let data_len = array_data.release_all_elements();
debug_assert!(data_len >= array.dim.size());
let has_unreachable_elements = array.dim.size() != data_len;
- let inner = Baseiter::new(ptr, array.dim, array.strides);
+ let inner = Baseiter::new(array_head_ptr, array.dim, array.strides);
IntoIter {
array_data,
@@ -62,7 +61,7 @@ impl Iterator for IntoIter
#[inline]
fn next(&mut self) -> Option
{
- self.inner.next().map(|p| unsafe { p.read() })
+ self.inner.next().map(|p| unsafe { p.as_ptr().read() })
}
fn size_hint(&self) -> (usize, Option)
@@ -92,7 +91,7 @@ where D: Dimension
while let Some(_) = self.next() {}
unsafe {
- let data_ptr = self.array_data.as_ptr_mut();
+ let data_ptr = self.array_data.as_nonnull_mut();
let view = RawArrayViewMut::new(self.array_head_ptr, self.inner.dim.clone(), self.inner.strides.clone());
debug_assert!(self.inner.dim.size() < self.data_len, "data_len {} and dim size {}",
self.data_len, self.inner.dim.size());
diff --git a/src/iterators/mod.rs b/src/iterators/mod.rs
index d49ffe2d0..e7321d15b 100644
--- a/src/iterators/mod.rs
+++ b/src/iterators/mod.rs
@@ -19,6 +19,10 @@ use alloc::vec::Vec;
use std::iter::FromIterator;
use std::marker::PhantomData;
use std::ptr;
+use std::ptr::NonNull;
+
+#[allow(unused_imports)] // Needed for Rust 1.64
+use rawpointer::PointerExt;
use crate::Ix1;
@@ -34,11 +38,11 @@ use std::slice::{self, Iter as SliceIter, IterMut as SliceIterMut};
/// Base for iterators over all axes.
///
-/// Iterator element type is `*mut A`.
+/// Iterator element type is `NonNull`.
#[derive(Debug)]
pub struct Baseiter
{
- ptr: *mut A,
+ ptr: NonNull,
dim: D,
strides: D,
index: Option,
@@ -50,7 +54,7 @@ impl Baseiter
/// to be correct to avoid performing an unsafe pointer offset while
/// iterating.
#[inline]
- pub unsafe fn new(ptr: *mut A, len: D, stride: D) -> Baseiter
+ pub unsafe fn new(ptr: NonNull, len: D, stride: D) -> Baseiter
{
Baseiter {
ptr,
@@ -63,10 +67,10 @@ impl Baseiter
impl Iterator for Baseiter
{
- type Item = *mut A;
+ type Item = NonNull;
#[inline]
- fn next(&mut self) -> Option<*mut A>
+ fn next(&mut self) -> Option
{
let index = match self.index {
None => return None,
@@ -84,7 +88,7 @@ impl Iterator for Baseiter
}
fn fold(mut self, init: Acc, mut g: G) -> Acc
- where G: FnMut(Acc, *mut A) -> Acc
+ where G: FnMut(Acc, Self::Item) -> Acc
{
let ndim = self.dim.ndim();
debug_assert_ne!(ndim, 0);
@@ -133,14 +137,14 @@ impl ExactSizeIterator for Baseiter
impl DoubleEndedIterator for Baseiter
{
#[inline]
- fn next_back(&mut self) -> Option<*mut A>
+ fn next_back(&mut self) -> Option
{
let index = match self.index {
None => return None,
Some(ix) => ix,
};
self.dim[0] -= 1;
- let offset = <_>::stride_offset(&self.dim, &self.strides);
+ let offset = Ix1::stride_offset(&self.dim, &self.strides);
if index == self.dim {
self.index = None;
}
@@ -148,13 +152,13 @@ impl DoubleEndedIterator for Baseiter
unsafe { Some(self.ptr.offset(offset)) }
}
- fn nth_back(&mut self, n: usize) -> Option<*mut A>
+ fn nth_back(&mut self, n: usize) -> Option
{
let index = self.index?;
let len = self.dim[0] - index[0];
if n < len {
self.dim[0] -= n + 1;
- let offset = <_>::stride_offset(&self.dim, &self.strides);
+ let offset = Ix1::stride_offset(&self.dim, &self.strides);
if index == self.dim {
self.index = None;
}
@@ -166,7 +170,7 @@ impl DoubleEndedIterator for Baseiter
}
fn rfold(mut self, init: Acc, mut g: G) -> Acc
- where G: FnMut(Acc, *mut A) -> Acc
+ where G: FnMut(Acc, Self::Item) -> Acc
{
let mut accum = init;
if let Some(index) = self.index {
@@ -226,7 +230,7 @@ impl<'a, A, D: Dimension> Iterator for ElementsBase<'a, A, D>
#[inline]
fn next(&mut self) -> Option<&'a A>
{
- self.inner.next().map(|p| unsafe { &*p })
+ self.inner.next().map(|p| unsafe { p.as_ref() })
}
fn size_hint(&self) -> (usize, Option)
@@ -237,7 +241,7 @@ impl<'a, A, D: Dimension> Iterator for ElementsBase<'a, A, D>
fn fold(self, init: Acc, mut g: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc
{
- unsafe { self.inner.fold(init, move |acc, ptr| g(acc, &*ptr)) }
+ unsafe { self.inner.fold(init, move |acc, ptr| g(acc, ptr.as_ref())) }
}
}
@@ -246,13 +250,13 @@ impl<'a, A> DoubleEndedIterator for ElementsBase<'a, A, Ix1>
#[inline]
fn next_back(&mut self) -> Option<&'a A>
{
- self.inner.next_back().map(|p| unsafe { &*p })
+ self.inner.next_back().map(|p| unsafe { p.as_ref() })
}
fn rfold(self, init: Acc, mut g: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc
{
- unsafe { self.inner.rfold(init, move |acc, ptr| g(acc, &*ptr)) }
+ unsafe { self.inner.rfold(init, move |acc, ptr| g(acc, ptr.as_ref())) }
}
}
@@ -646,7 +650,7 @@ impl<'a, A, D: Dimension> Iterator for ElementsBaseMut<'a, A, D>
#[inline]
fn next(&mut self) -> Option<&'a mut A>
{
- self.inner.next().map(|p| unsafe { &mut *p })
+ self.inner.next().map(|mut p| unsafe { p.as_mut() })
}
fn size_hint(&self) -> (usize, Option)
@@ -657,7 +661,10 @@ impl<'a, A, D: Dimension> Iterator for ElementsBaseMut<'a, A, D>
fn fold(self, init: Acc, mut g: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc
{
- unsafe { self.inner.fold(init, move |acc, ptr| g(acc, &mut *ptr)) }
+ unsafe {
+ self.inner
+ .fold(init, move |acc, mut ptr| g(acc, ptr.as_mut()))
+ }
}
}
@@ -666,13 +673,16 @@ impl<'a, A> DoubleEndedIterator for ElementsBaseMut<'a, A, Ix1>
#[inline]
fn next_back(&mut self) -> Option<&'a mut A>
{
- self.inner.next_back().map(|p| unsafe { &mut *p })
+ self.inner.next_back().map(|mut p| unsafe { p.as_mut() })
}
fn rfold(self, init: Acc, mut g: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc
{
- unsafe { self.inner.rfold(init, move |acc, ptr| g(acc, &mut *ptr)) }
+ unsafe {
+ self.inner
+ .rfold(init, move |acc, mut ptr| g(acc, ptr.as_mut()))
+ }
}
}
@@ -748,7 +758,7 @@ where D: Dimension
{
self.iter
.next()
- .map(|ptr| unsafe { ArrayView::new_(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
+ .map(|ptr| unsafe { ArrayView::new(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
}
fn size_hint(&self) -> (usize, Option)
@@ -772,7 +782,7 @@ impl<'a, A> DoubleEndedIterator for LanesIter<'a, A, Ix1>
{
self.iter
.next_back()
- .map(|ptr| unsafe { ArrayView::new_(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
+ .map(|ptr| unsafe { ArrayView::new(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
}
}
@@ -800,7 +810,7 @@ where D: Dimension
{
self.iter
.next()
- .map(|ptr| unsafe { ArrayViewMut::new_(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
+ .map(|ptr| unsafe { ArrayViewMut::new(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
}
fn size_hint(&self) -> (usize, Option)
@@ -824,7 +834,7 @@ impl<'a, A> DoubleEndedIterator for LanesIterMut<'a, A, Ix1>
{
self.iter
.next_back()
- .map(|ptr| unsafe { ArrayViewMut::new_(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
+ .map(|ptr| unsafe { ArrayViewMut::new(ptr, Ix1(self.inner_len), Ix1(self.inner_stride as Ix)) })
}
}
diff --git a/src/iterators/windows.rs b/src/iterators/windows.rs
index 453ef5024..1c2ab6a85 100644
--- a/src/iterators/windows.rs
+++ b/src/iterators/windows.rs
@@ -115,7 +115,7 @@ impl_iterator! {
fn item(&mut self, ptr) {
unsafe {
- ArrayView::new_(
+ ArrayView::new(
ptr,
self.window.clone(),
self.strides.clone())
diff --git a/tests/iterators.rs b/tests/iterators.rs
index 23175fd40..908b64d15 100644
--- a/tests/iterators.rs
+++ b/tests/iterators.rs
@@ -1,6 +1,4 @@
-#![allow(
- clippy::many_single_char_names, clippy::deref_addrof, clippy::unreadable_literal, clippy::many_single_char_names
-)]
+#![allow(clippy::deref_addrof, clippy::unreadable_literal)]
use ndarray::prelude::*;
use ndarray::{arr3, indices, s, Slice, Zip};
@@ -1055,3 +1053,33 @@ impl Drop for DropCount<'_>
self.drops.set(self.drops.get() + 1);
}
}
+
+#[test]
+fn test_impl_iter_compiles()
+{
+ // Requires that the iterators are covariant in the element type
+
+ // base case: std
+ fn slice_iter_non_empty_indices<'s, 'a>(array: &'a Vec<&'s str>) -> impl Iterator- + 'a
+ {
+ array
+ .iter()
+ .enumerate()
+ .filter(|(_index, elem)| !elem.is_empty())
+ .map(|(index, _elem)| index)
+ }
+
+ let _ = slice_iter_non_empty_indices;
+
+ // ndarray case
+ fn array_iter_non_empty_indices<'s, 'a>(array: &'a Array<&'s str, Ix1>) -> impl Iterator
- + 'a
+ {
+ array
+ .iter()
+ .enumerate()
+ .filter(|(_index, elem)| !elem.is_empty())
+ .map(|(index, _elem)| index)
+ }
+
+ let _ = array_iter_non_empty_indices;
+}