rune_alloc/slice/
iter.rs

1//! Definitions of a bunch of iterators for `[T]`.
2
3#![allow(unused_unsafe)]
4
5#[macro_use]
6mod macros;
7
8use core::fmt;
9use core::iter::FusedIterator;
10use core::slice::{from_raw_parts, from_raw_parts_mut};
11
12use crate::alloc::SizedTypeProperties;
13use crate::hint::assume;
14use crate::ptr::{self, invalid, invalid_mut, NonNull};
15
16/// Inline slice iterator
17///
18/// This struct is created by the [`iter`] method on [slices].
19///
20/// # Examples
21///
22/// Basic usage:
23///
24/// ```
25/// use rune::alloc::try_vec;
26///
27/// // First, we declare a type which has `iter` method to get the `Iter` struct (`&[usize]` here):
28/// let vec = try_vec![1, 2, 3];
29///
30/// // Then, we iterate over it:
31/// unsafe {
32///     for element in vec.raw_iter() {
33///         println!("{}", *element);
34///     }
35/// }
36/// # Ok::<_, rune::alloc::Error>(())
37/// ```
38///
39/// [`iter`]: slice::iter
40/// [slices]: slice
41#[must_use = "iterators are lazy and do nothing unless consumed"]
42pub struct RawIter<T> {
43    /// The pointer to the next element to return, or the past-the-end location
44    /// if the iterator is empty.
45    ///
46    /// This address will be used for all ZST elements, never changed.
47    ptr: NonNull<T>,
48    /// For non-ZSTs, the non-null pointer to the past-the-end element.
49    ///
50    /// For ZSTs, this is `ptr::invalid(len)`.
51    end_or_len: *const T,
52}
53
54impl<T: fmt::Debug> fmt::Debug for RawIter<T> {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        f.debug_tuple("Iter").finish()
57    }
58}
59
60unsafe impl<T: Sync> Sync for RawIter<T> {}
61unsafe impl<T: Sync> Send for RawIter<T> {}
62
63impl<T> RawIter<T> {
64    #[inline]
65    pub(crate) fn new(slice: &[T]) -> Self {
66        let ptr = slice.as_ptr();
67        // SAFETY: Similar to `IterMut::new`.
68        unsafe {
69            let end_or_len = if T::IS_ZST {
70                invalid(slice.len())
71            } else {
72                ptr.add(slice.len())
73            };
74
75            Self {
76                ptr: NonNull::new_unchecked(ptr as *mut T),
77                end_or_len,
78            }
79        }
80    }
81
82    /// Views the underlying data as a subslice of the original data.
83    ///
84    /// This has the same lifetime as the original slice, and so the
85    /// iterator can continue to be used while this exists.
86    ///
87    /// # Examples
88    ///
89    /// Basic usage:
90    ///
91    /// ```
92    /// use rune::alloc::try_vec;
93    ///
94    /// // First, we declare a type which has the `iter` method to get the `Iter`
95    /// // struct (`&[usize]` here):
96    /// let slice = try_vec![1, 2, 3];
97    ///
98    /// unsafe {
99    ///     // Then, we get the iterator:
100    ///     let mut iter = slice.raw_iter();
101    ///
102    ///     // So if we print what `as_slice` method returns here, we have "[1, 2, 3]":
103    ///     println!("{:?}", iter.as_slice());
104    ///
105    ///     // Next, we move to the second element of the slice:
106    ///     iter.next();
107    ///     // Now `as_slice` returns "[2, 3]":
108    ///     println!("{:?}", iter.as_slice());
109    /// }
110    /// # Ok::<_, rune::alloc::Error>(())
111    /// ```
112    #[must_use]
113    #[inline]
114    pub unsafe fn as_slice<'a>(&self) -> &'a [T] {
115        self.make_slice()
116    }
117}
118
119iterator! {struct RawIter -> *const T, *const T, const, {/* no mut */}, as_ref, {}}
120
121impl<T> Clone for RawIter<T> {
122    #[inline]
123    fn clone(&self) -> Self {
124        RawIter {
125            ptr: self.ptr,
126            end_or_len: self.end_or_len,
127        }
128    }
129}
130
131/// Mutable slice iterator.
132///
133/// This struct is created by the [`iter_mut`] method on [slices].
134///
135/// # Examples
136///
137/// Basic usage:
138///
139/// ```
140/// use rune::alloc::try_vec;
141///
142/// // First, we declare a type which has `iter_mut` method to get the `IterMut`
143/// // struct (`&[usize]` here):
144/// let mut slice = try_vec![1, 2, 3];
145///
146/// // Then, we iterate over it and increment each element value:
147/// unsafe {
148///     for element in slice.raw_iter_mut() {
149///         *element += 1;
150///     }
151/// }
152///
153/// // We now have "[2, 3, 4]":
154/// println!("{slice:?}");
155/// # Ok::<_, rune::alloc::Error>(())
156/// ```
157///
158/// [`iter_mut`]: slice::iter_mut
159/// [slices]: slice
160#[must_use = "iterators are lazy and do nothing unless consumed"]
161pub struct RawIterMut<T> {
162    /// The pointer to the next element to return, or the past-the-end location
163    /// if the iterator is empty.
164    ///
165    /// This address will be used for all ZST elements, never changed.
166    ptr: NonNull<T>,
167    /// For non-ZSTs, the non-null pointer to the past-the-end element.
168    ///
169    /// For ZSTs, this is `ptr::invalid_mut(len)`.
170    end_or_len: *mut T,
171}
172
173impl<T: fmt::Debug> fmt::Debug for RawIterMut<T> {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        f.debug_tuple("IterMut").finish()
176    }
177}
178
179unsafe impl<T: Sync> Sync for RawIterMut<T> {}
180unsafe impl<T: Send> Send for RawIterMut<T> {}
181
182impl<T> RawIterMut<T> {
183    #[inline]
184    pub(crate) fn new(slice: &mut [T]) -> Self {
185        let ptr = slice.as_mut_ptr();
186        // SAFETY: There are several things here:
187        //
188        // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
189        // reference thus it is non-NUL and safe to use and pass to
190        // `NonNull::new_unchecked` .
191        //
192        // Adding `slice.len()` to the starting pointer gives a pointer
193        // at the end of `slice`. `end` will never be dereferenced, only checked
194        // for direct pointer equality with `ptr` to check if the iterator is
195        // done.
196        //
197        // In the case of a ZST, the end pointer is just the length.  It's never
198        // used as a pointer at all, and thus it's fine to have no provenance.
199        //
200        // See the `next_unchecked!` and `is_empty!` macros as well as the
201        // `post_inc_start` method for more information.
202        unsafe {
203            let end_or_len = if T::IS_ZST {
204                invalid_mut(slice.len())
205            } else {
206                ptr.add(slice.len())
207            };
208
209            Self {
210                ptr: NonNull::new_unchecked(ptr),
211                end_or_len,
212            }
213        }
214    }
215
216    /// Views the underlying data as a subslice of the original data.
217    ///
218    /// To avoid creating `&mut [T]` references that alias, the returned slice
219    /// borrows its lifetime from the iterator the method is applied on.
220    ///
221    /// # Examples
222    ///
223    /// Basic usage:
224    ///
225    /// ```
226    /// use rune::alloc::try_vec;
227    ///
228    /// let mut slice = try_vec![1, 2, 3];
229    ///
230    /// unsafe {
231    ///     // First, we get the iterator:
232    ///     let mut iter = slice.raw_iter_mut();
233    ///
234    ///     // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]":
235    ///     assert_eq!(iter.as_slice(), &[1, 2, 3]);
236    ///
237    ///     // Next, we move to the second element of the slice:
238    ///     iter.next();
239    ///     // Now `as_slice` returns "[2, 3]":
240    ///     assert_eq!(iter.as_slice(), &[2, 3]);
241    /// }
242    /// # Ok::<_, rune::alloc::Error>(())
243    /// ```
244    #[must_use]
245    #[inline]
246    pub unsafe fn as_slice<'a>(&self) -> &'a [T] {
247        self.make_slice()
248    }
249
250    /// Views the underlying data as a mutable subslice of the original data.
251    ///
252    /// To avoid creating `&mut [T]` references that alias, the returned slice
253    /// borrows its lifetime from the iterator the method is applied on.
254    ///
255    /// # Examples
256    ///
257    /// Basic usage:
258    ///
259    /// ```
260    /// use rune::alloc::try_vec;
261    ///
262    /// let mut slice = try_vec![1, 2, 3];
263    ///
264    /// unsafe {
265    ///     // First, we get the iterator:
266    ///     let mut iter = slice.raw_iter_mut();
267    ///     // Then, we get a mutable slice from it:
268    ///     let mut_slice = iter.as_mut_slice();
269    ///     // So if we check what the `as_mut_slice` method returned, we have "[1, 2, 3]":
270    ///     assert_eq!(mut_slice, &mut [1, 2, 3]);
271    ///
272    ///     // We can use it to mutate the slice:
273    ///     mut_slice[0] = 4;
274    ///     mut_slice[2] = 5;
275    ///
276    ///     // Next, we can move to the second element of the slice, checking that
277    ///     // it yields the value we just wrote:
278    ///     assert!(iter.next().is_some());
279    ///     // Now `as_mut_slice` returns "[2, 5]":
280    ///     assert_eq!(iter.as_mut_slice(), &mut [2, 5]);
281    /// }
282    /// # Ok::<_, rune::alloc::Error>(())
283    /// ```
284    #[must_use]
285    pub unsafe fn as_mut_slice<'a>(&mut self) -> &'a mut [T] {
286        from_raw_parts_mut(self.ptr.as_ptr(), len!(self))
287    }
288}
289
290iterator! {struct RawIterMut -> *mut T, *mut T, mut, {mut}, as_mut, {}}