runtime_sized_array/
array_iters.rs

1//! Provides different iterators for [`Array`](crate::Array)
2
3pub use iter::Iter;
4pub use itermut::IterMut;
5pub use into_iter::IntoIter;
6
7
8mod iter {
9
10    use std::marker::PhantomData;
11    use crate::array::Array;
12
13    /// Immutable array iterator.
14    ///
15    /// This `struct` is created by the [`iter`] method on [`Array`](Array).
16    ///
17    /// # Example
18    ///
19    /// Basic usage:
20    ///
21    /// ```
22    /// use runtime_sized_array::Array;
23    ///
24    /// let array : Array<i32> = vec![1,2,3].into();
25    /// for item in array.iter() {
26    ///     println!("{item}");
27    /// }
28    /// ```
29    ///
30    /// [`iter`]: Array::iter
31    #[must_use = "iterators are lazy and do nothing unless consumed"]
32    pub struct Iter<'a, T> {
33        // this make borrow checker not let you to drop array before iterator
34        // otherwise iterator will have access to freed memory
35        marker: PhantomData<&'a T>,
36        ptr: *const T,
37        end: *const T,
38    }
39
40
41    impl<'a, T> Iter<'a, T> {
42
43        #[inline]
44        pub(crate) fn new(array: &'a Array<T>) -> Self {
45            let ptr = array.pointer;
46            Self {
47                marker: PhantomData,
48                ptr,
49                end: unsafe { ptr.add(array.size()) }
50            }
51        }
52    }
53
54
55    impl<'a, T> Iterator for Iter<'a, T> {
56        type Item = &'a T;
57
58        #[inline]
59        fn next(&mut self) -> Option<Self::Item> {
60            if self.ptr == self.end {
61                None
62            } else {
63                unsafe {
64                    let p = self.ptr;
65                    self.ptr = self.ptr.add(1);
66                    Some(&*p)
67                }
68            }
69        }
70    }
71}
72
73
74mod itermut {
75
76    use std::marker::PhantomData;
77    use crate::array::Array;
78
79    /// Mutable array iterator.
80    ///
81    /// This `struct` is created by the [`iter_mut`] method on [`Array`](Array).
82    ///
83    /// # Example
84    ///
85    /// Basic usage:
86    ///
87    /// ```
88    /// use runtime_sized_array::Array;
89    ///
90    /// let mut array : Array<i32> = vec![1,2,3].into();
91    /// for item in array.iter_mut() {
92    ///     *item += 1;
93    /// }
94    /// assert_eq!(array.try_get(1), Some(&3));
95    /// ```
96    ///
97    /// [`iter_mut`]: Array::iter_mut
98    #[must_use = "iterators are lazy and do nothing unless consumed"]
99    pub struct IterMut<'a, T> {
100        // this make borrow checker not let you to drop array before iterator
101        // otherwise iterator will have access to freed memory
102        marker: PhantomData<&'a T>,
103        ptr: *mut T,
104        end: *mut T,
105    }
106
107
108    impl<'a, T> IterMut<'a, T> {
109
110        #[inline]
111        pub(crate) fn new(array: &'a mut Array<T>) -> Self {
112            let ptr = array.pointer;
113            let size = array.size();
114            Self {
115                marker: PhantomData,
116                ptr,
117                end: unsafe { ptr.add(size) }
118            }
119        }
120    }
121
122
123    impl<'a, T> Iterator for IterMut<'a, T> {
124        type Item = &'a mut T;
125
126        #[inline]
127        fn next(&mut self) -> Option<Self::Item> {
128            if self.ptr == self.end {
129                None
130            } else {
131                unsafe {
132                    let p = self.ptr;
133                    self.ptr = self.ptr.add(1);
134                    Some(&mut *p)
135                }
136            }
137        }
138    }
139}
140
141
142mod into_iter {
143
144    use std::marker::PhantomData;
145    use crate::array::Array;
146
147
148    /// An iterator that moves out of an array.
149    ///
150    /// This `struct` is created by the `into_iter` method on [`Array`](Array)
151    /// (provided by the [`IntoIterator`] trait).
152    ///
153    /// # Example
154    ///
155    /// ```
156    /// use runtime_sized_array::{Array, IntoIter};
157    ///
158    /// let mut array : Array<i32> = vec![1,2,3].into();
159    /// let iter: IntoIter<_>  = array.into_iter();
160    /// ```
161    pub struct IntoIter<T> {
162        // do not let array be dropped before one's time
163        array: Array<T>,
164        ptr: *const T,
165        end: *const T,
166    }
167
168
169    impl<T> IntoIter<T> {
170
171        #[inline]
172        pub(crate) fn new(array: Array<T>) -> Self {
173            let end = unsafe { array.pointer.add(array.size()) };
174            let ptr = array.pointer.as_const();
175            Self { array, ptr, end }
176        }
177    }
178
179
180    impl<T> Iterator for IntoIter<T> {
181        type Item = T;
182
183        #[inline]
184        fn next(&mut self) -> Option<Self::Item> {
185            if self.ptr == self.end {
186                None
187            } else {
188                unsafe {
189                    let p = self.ptr;
190                    self.ptr = self.ptr.add(1);
191                    Some(std::ptr::read(p))
192                }
193            }
194        }
195    }
196}
197