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, {}}