ndarray/iterators/
into_iter.rs
1use std::mem;
10use std::ptr::NonNull;
11
12use crate::imp_prelude::*;
13use crate::OwnedRepr;
14
15use super::Baseiter;
16use crate::impl_owned_array::drop_unreachable_raw;
17
18
19pub struct IntoIter<A, D>
21where
22 D: Dimension,
23{
24 array_data: OwnedRepr<A>,
25 inner: Baseiter<A, D>,
26 data_len: usize,
27 array_head_ptr: NonNull<A>,
29 has_unreachable_elements: bool,
32}
33
34impl<A, D> IntoIter<A, D>
35where
36 D: Dimension,
37{
38 pub(crate) fn new(mut array: Array<A, D>) -> Self {
40 unsafe {
41 let array_head_ptr = array.ptr;
42 let ptr = array.as_mut_ptr();
43 let mut array_data = array.data;
44 let data_len = array_data.release_all_elements();
45 debug_assert!(data_len >= array.dim.size());
46 let has_unreachable_elements = array.dim.size() != data_len;
47 let inner = Baseiter::new(ptr, array.dim, array.strides);
48
49 IntoIter {
50 array_data,
51 inner,
52 data_len,
53 array_head_ptr,
54 has_unreachable_elements,
55 }
56 }
57 }
58}
59
60impl<A, D: Dimension> Iterator for IntoIter<A, D> {
61 type Item = A;
62
63 #[inline]
64 fn next(&mut self) -> Option<A> {
65 self.inner.next().map(|p| unsafe { p.read() })
66 }
67
68 fn size_hint(&self) -> (usize, Option<usize>) {
69 self.inner.size_hint()
70 }
71}
72
73impl<A, D: Dimension> ExactSizeIterator for IntoIter<A, D> {
74 fn len(&self) -> usize { self.inner.len() }
75}
76
77impl<A, D> Drop for IntoIter<A, D>
78where
79 D: Dimension
80{
81 fn drop(&mut self) {
82 if !self.has_unreachable_elements || mem::size_of::<A>() == 0 || !mem::needs_drop::<A>() {
83 return;
84 }
85
86 while let Some(_) = self.next() { }
88
89 unsafe {
90 let data_ptr = self.array_data.as_ptr_mut();
91 let view = RawArrayViewMut::new(self.array_head_ptr, self.inner.dim.clone(),
92 self.inner.strides.clone());
93 debug_assert!(self.inner.dim.size() < self.data_len, "data_len {} and dim size {}",
94 self.data_len, self.inner.dim.size());
95 drop_unreachable_raw(view, data_ptr, self.data_len);
96 }
97 }
98}
99
100impl<A, D> IntoIterator for Array<A, D>
101where
102 D: Dimension
103{
104 type Item = A;
105 type IntoIter = IntoIter<A, D>;
106
107 fn into_iter(self) -> Self::IntoIter {
108 IntoIter::new(self)
109 }
110}
111
112impl<A, D> IntoIterator for ArcArray<A, D>
113where
114 D: Dimension,
115 A: Clone,
116{
117 type Item = A;
118 type IntoIter = IntoIter<A, D>;
119
120 fn into_iter(self) -> Self::IntoIter {
121 IntoIter::new(self.into_owned())
122 }
123}
124
125impl<A, D> IntoIterator for CowArray<'_, A, D>
126where
127 D: Dimension,
128 A: Clone,
129{
130 type Item = A;
131 type IntoIter = IntoIter<A, D>;
132
133 fn into_iter(self) -> Self::IntoIter {
134 IntoIter::new(self.into_owned())
135 }
136}