non_empty_slice/
iter.rs

1//! Various non-empty iterators over non-empty vectors and slices.
2
3#[cfg(feature = "std")]
4use std::vec::IntoIter;
5
6#[cfg(all(not(feature = "std"), feature = "alloc"))]
7use alloc::vec::IntoIter;
8
9use core::{
10    iter::Map,
11    slice::{self, Iter, IterMut},
12};
13
14use non_zero_size::Size;
15
16use non_empty_iter::{NonEmptyAdapter, NonEmptyIterator};
17
18use crate::slice::NonEmptySlice;
19
20/// Represents non-empty by-value iterators.
21#[cfg(any(feature = "std", feature = "alloc"))]
22pub type IntoNonEmptyIter<T> = NonEmptyAdapter<IntoIter<T>>;
23
24/// Represents non-empty by-reference iterators.
25pub type NonEmptyIter<'a, T> = NonEmptyAdapter<Iter<'a, T>>;
26
27/// Represents non-empty by-mutable-reference iterators.
28pub type NonEmptyIterMut<'a, T> = NonEmptyAdapter<IterMut<'a, T>>;
29
30/// Represents functions mapping chunks to non-empty slices.
31///
32/// This is mostly an implementation detail, though it can be useful in case
33/// one needs to name the type of the iterator explicitly.
34pub type NonEmptySliceFn<'a, T> = fn(&'a [T]) -> &'a NonEmptySlice<T>;
35
36/// Represents functions mapping mutable chunks to non-empty mutable slices.
37///
38/// This is mostly an implementation detail, though it can be useful in case
39/// one needs to name the type of the iterator explicitly.
40pub type NonEmptyMutSliceFn<'a, T> = fn(&'a mut [T]) -> &'a mut NonEmptySlice<T>;
41
42/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
43/// starting at the beginning of the non-empty slice.
44///
45/// This `struct` is created by the [`chunks`] method on [`NonEmptySlice<T>`].
46///
47/// [`chunks`]: NonEmptySlice::chunks
48pub struct Chunks<'a, T> {
49    slice: &'a NonEmptySlice<T>,
50    size: Size,
51}
52
53impl<'a, T> Chunks<'a, T> {
54    /// Constructs [`Self`].
55    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
56        Self { slice, size }
57    }
58}
59
60impl<'a, T> IntoIterator for Chunks<'a, T> {
61    type Item = &'a NonEmptySlice<T>;
62
63    type IntoIter = Map<slice::Chunks<'a, T>, NonEmptySliceFn<'a, T>>;
64
65    fn into_iter(self) -> Self::IntoIter {
66        self.slice
67            .as_slice()
68            .chunks(self.size.get())
69            // SAFETY: chunks are never empty
70            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
71    }
72}
73
74unsafe impl<T> NonEmptyIterator for Chunks<'_, T> {}
75
76/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
77/// starting at the beginning of the non-empty slice.
78///
79/// This `struct` is created by the [`chunks_mut`] method on [`NonEmptySlice<T>`].
80///
81/// [`chunks_mut`]: NonEmptySlice::chunks_mut
82pub struct ChunksMut<'a, T> {
83    slice: &'a mut NonEmptySlice<T>,
84    size: Size,
85}
86
87impl<'a, T> ChunksMut<'a, T> {
88    /// Constructs [`Self`].
89    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
90        Self { slice, size }
91    }
92}
93
94impl<'a, T> IntoIterator for ChunksMut<'a, T> {
95    type Item = &'a mut NonEmptySlice<T>;
96
97    type IntoIter = Map<slice::ChunksMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
98
99    fn into_iter(self) -> Self::IntoIter {
100        self.slice
101            .as_mut_slice()
102            .chunks_mut(self.size.get())
103            // SAFETY: chunks are never empty
104            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
105    }
106}
107
108unsafe impl<T> NonEmptyIterator for ChunksMut<'_, T> {}
109
110/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
111/// starting at the end of the non-empty slice.
112///
113/// This `struct` is created by the [`rchunks`] method on [`NonEmptySlice<T>`].
114///
115/// [`rchunks`]: NonEmptySlice::rchunks
116pub struct RChunks<'a, T> {
117    slice: &'a NonEmptySlice<T>,
118    size: Size,
119}
120
121impl<'a, T> RChunks<'a, T> {
122    /// Constructs [`Self`].
123    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
124        Self { slice, size }
125    }
126}
127
128unsafe impl<T> NonEmptyIterator for RChunks<'_, T> {}
129
130impl<'a, T> IntoIterator for RChunks<'a, T> {
131    type Item = &'a NonEmptySlice<T>;
132
133    type IntoIter = Map<slice::RChunks<'a, T>, NonEmptySliceFn<'a, T>>;
134
135    fn into_iter(self) -> Self::IntoIter {
136        self.slice
137            .as_slice()
138            .rchunks(self.size.get())
139            // SAFETY: chunks are never empty
140            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
141    }
142}
143
144/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
145/// starting at the end of the non-empty slice.
146///
147/// This `struct` is created by the [`rchunks_mut`] method on [`NonEmptySlice<T>`].
148///
149/// [`rchunks_mut`]: NonEmptySlice::rchunks_mut
150pub struct RChunksMut<'a, T> {
151    slice: &'a mut NonEmptySlice<T>,
152    size: Size,
153}
154
155impl<'a, T> RChunksMut<'a, T> {
156    /// Constructs [`Self`].
157    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
158        Self { slice, size }
159    }
160}
161
162impl<'a, T> IntoIterator for RChunksMut<'a, T> {
163    type Item = &'a mut NonEmptySlice<T>;
164
165    type IntoIter = Map<slice::RChunksMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
166
167    fn into_iter(self) -> Self::IntoIter {
168        self.slice
169            .as_mut_slice()
170            .rchunks_mut(self.size.get())
171            // SAFETY: chunks are never empty
172            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
173    }
174}
175
176unsafe impl<T> NonEmptyIterator for RChunksMut<'_, T> {}
177
178/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
179/// starting at the beginning of the non-empty slice.
180///
181/// When the length of the non-empty slice is not divisible by the chunk size,
182/// the last chunk will be omitted.
183///
184/// This `struct` is created by the [`chunks_exact`] method on [`NonEmptySlice<T>`].
185///
186/// [`chunks_exact`]: NonEmptySlice::chunks_exact
187pub struct ChunksExact<'a, T> {
188    slice: &'a NonEmptySlice<T>,
189    size: Size,
190}
191
192impl<'a, T> ChunksExact<'a, T> {
193    /// Constructs [`Self`].
194    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
195        Self { slice, size }
196    }
197}
198
199impl<'a, T> IntoIterator for ChunksExact<'a, T> {
200    type Item = &'a NonEmptySlice<T>;
201
202    type IntoIter = Map<slice::ChunksExact<'a, T>, NonEmptySliceFn<'a, T>>;
203
204    fn into_iter(self) -> Self::IntoIter {
205        self.slice
206            .as_slice()
207            .chunks_exact(self.size.get())
208            // SAFETY: chunks are never empty
209            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
210    }
211}
212
213unsafe impl<T> NonEmptyIterator for ChunksExact<'_, T> {}
214
215/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
216/// starting at the beginning of the non-empty slice.
217///
218/// When the length of the non-empty slice is not divisible by the chunk size,
219/// the last chunk will be omitted.
220///
221/// This `struct` is created by the [`chunks_exact_mut`] method on [`NonEmptySlice<T>`].
222///
223/// [`chunks_exact_mut`]: NonEmptySlice::chunks_exact_mut
224pub struct ChunksExactMut<'a, T> {
225    slice: &'a mut NonEmptySlice<T>,
226    size: Size,
227}
228
229impl<'a, T> ChunksExactMut<'a, T> {
230    /// Constructs [`Self`].
231    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
232        Self { slice, size }
233    }
234}
235
236impl<'a, T> IntoIterator for ChunksExactMut<'a, T> {
237    type Item = &'a mut NonEmptySlice<T>;
238
239    type IntoIter = Map<slice::ChunksExactMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
240
241    fn into_iter(self) -> Self::IntoIter {
242        self.slice
243            .as_mut_slice()
244            .chunks_exact_mut(self.size.get())
245            // SAFETY: chunks are never empty
246            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
247    }
248}
249
250unsafe impl<T> NonEmptyIterator for ChunksExactMut<'_, T> {}
251
252/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
253/// starting at the end of the non-empty slice.
254///
255/// When the length of the non-empty slice is not divisible by the chunk size,
256/// the last chunk will be omitted.
257///
258/// This `struct` is created by the [`rchunks_exact`] method on [`NonEmptySlice<T>`].
259///
260/// [`rchunks_exact`]: NonEmptySlice::rchunks_exact
261pub struct RChunksExact<'a, T> {
262    slice: &'a NonEmptySlice<T>,
263    size: Size,
264}
265
266impl<'a, T> RChunksExact<'a, T> {
267    /// Constructs [`Self`].
268    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
269        Self { slice, size }
270    }
271}
272
273impl<'a, T> IntoIterator for RChunksExact<'a, T> {
274    type Item = &'a NonEmptySlice<T>;
275
276    type IntoIter = Map<slice::RChunksExact<'a, T>, NonEmptySliceFn<'a, T>>;
277
278    fn into_iter(self) -> Self::IntoIter {
279        self.slice
280            .as_slice()
281            .rchunks_exact(self.size.get())
282            // SAFETY: chunks are never empty
283            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
284    }
285}
286
287unsafe impl<T> NonEmptyIterator for RChunksExact<'_, T> {}
288
289/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
290/// starting at the end of the non-empty slice.
291///
292/// When the length of the non-empty slice is not divisible by the chunk size,
293/// the last chunk will be omitted.
294///
295/// This `struct` is created by the [`rchunks_exact_mut`] method on [`NonEmptySlice<T>`].
296///
297/// [`rchunks_exact_mut`]: NonEmptySlice::rchunks_exact_mut
298pub struct RChunksExactMut<'a, T> {
299    slice: &'a mut NonEmptySlice<T>,
300    size: Size,
301}
302
303impl<'a, T> RChunksExactMut<'a, T> {
304    /// Constructs [`Self`].
305    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
306        Self { slice, size }
307    }
308}
309
310impl<'a, T> IntoIterator for RChunksExactMut<'a, T> {
311    type Item = &'a mut NonEmptySlice<T>;
312
313    type IntoIter = Map<slice::RChunksExactMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
314
315    fn into_iter(self) -> Self::IntoIter {
316        self.slice
317            .as_mut_slice()
318            .rchunks_exact_mut(self.size.get())
319            // SAFETY: chunks are never empty
320            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
321    }
322}
323
324unsafe impl<T> NonEmptyIterator for RChunksExactMut<'_, T> {}
325
326/// Represents non-empty iterators over non-empty slices in (overlapping) windows.
327///
328/// This `struct` is created by the [`windows`] method on [`NonEmptySlice<T>`].
329///
330/// [`windows`]: NonEmptySlice::windows
331pub struct Windows<'a, T> {
332    slice: &'a NonEmptySlice<T>,
333    size: Size,
334}
335
336impl<'a, T> Windows<'a, T> {
337    /// Constructs [`Self`].
338    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
339        Self { slice, size }
340    }
341}
342
343impl<'a, T> IntoIterator for Windows<'a, T> {
344    type Item = &'a NonEmptySlice<T>;
345
346    type IntoIter = Map<slice::Windows<'a, T>, NonEmptySliceFn<'a, T>>;
347
348    fn into_iter(self) -> Self::IntoIter {
349        self.slice
350            .as_slice()
351            .windows(self.size.get())
352            // SAFETY: windows are never empty
353            .map(|window| unsafe { NonEmptySlice::from_slice_unchecked(window) })
354    }
355}
356
357unsafe impl<T> NonEmptyIterator for Windows<'_, T> {}
358
359/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
360/// separated by the given predicate.
361///
362/// This `struct` is created by the [`chunk_by`] method on [`NonEmptySlice<T>`].
363///
364/// [`chunk_by`]: NonEmptySlice::chunk_by
365pub struct ChunkBy<'a, T, P: FnMut(&T, &T) -> bool> {
366    slice: &'a NonEmptySlice<T>,
367    predicate: P,
368}
369
370impl<'a, T, P: FnMut(&T, &T) -> bool> ChunkBy<'a, T, P> {
371    /// Constructs [`Self`].
372    pub const fn new(slice: &'a NonEmptySlice<T>, predicate: P) -> Self {
373        Self { slice, predicate }
374    }
375}
376
377impl<'a, T, P: FnMut(&T, &T) -> bool> IntoIterator for ChunkBy<'a, T, P> {
378    type Item = &'a NonEmptySlice<T>;
379
380    type IntoIter = Map<slice::ChunkBy<'a, T, P>, NonEmptySliceFn<'a, T>>;
381
382    fn into_iter(self) -> Self::IntoIter {
383        self.slice
384            .as_slice()
385            .chunk_by(self.predicate)
386            // SAFETY: chunks are never empty
387            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
388    }
389}
390
391unsafe impl<T, P: FnMut(&T, &T) -> bool> NonEmptyIterator for ChunkBy<'_, T, P> {}
392
393/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
394/// separated by the given predicate.
395///
396/// This `struct` is created by the [`chunk_by_mut`] method on [`NonEmptySlice<T>`].
397///
398/// [`chunk_by_mut`]: NonEmptySlice::chunk_by_mut
399pub struct ChunkByMut<'a, T, P: FnMut(&T, &T) -> bool> {
400    slice: &'a mut NonEmptySlice<T>,
401    predicate: P,
402}
403
404impl<'a, T, P: FnMut(&T, &T) -> bool> ChunkByMut<'a, T, P> {
405    /// Constructs [`Self`].
406    pub const fn new(slice: &'a mut NonEmptySlice<T>, predicate: P) -> Self {
407        Self { slice, predicate }
408    }
409}
410
411impl<'a, T, P: FnMut(&T, &T) -> bool> IntoIterator for ChunkByMut<'a, T, P> {
412    type Item = &'a mut NonEmptySlice<T>;
413
414    type IntoIter = Map<slice::ChunkByMut<'a, T, P>, NonEmptyMutSliceFn<'a, T>>;
415
416    fn into_iter(self) -> Self::IntoIter {
417        self.slice
418            .as_mut_slice()
419            .chunk_by_mut(self.predicate)
420            // SAFETY: chunks are never empty
421            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
422    }
423}
424
425unsafe impl<T, P: FnMut(&T, &T) -> bool> NonEmptyIterator for ChunkByMut<'_, T, P> {}