Skip to main content

tea_core/vec_core/
trusted.rs

1use std::error::Error;
2use std::iter::Scan;
3use std::slice::Iter;
4
5#[cfg(feature = "polars")]
6use tea_deps::polars::prelude::PolarsIterator;
7#[cfg(feature = "polars")]
8pub(crate) use tea_deps::polars_arrow::trusted_len::TrustedLen as PlTrustedLen;
9
10/// An iterator of known, fixed size.
11///
12/// A trait denoting Rusts' unstable [TrustedLen](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
13/// This is re-defined here and implemented for some iterators until `std::iter::TrustedLen`
14/// is stabilized.
15///
16/// # Safety
17/// This trait must only be implemented when the contract is upheld.
18/// Consumers of this trait must inspect Iterator::size_hint()’s upper bound.
19// #[cfg(not(feature = "polars"))]
20pub unsafe trait TrustedLen: Iterator {
21    #[inline]
22    fn len(&self) -> usize {
23        self.size_hint().1.unwrap()
24    }
25
26    #[inline]
27    fn is_empty(&self) -> bool {
28        self.len() == 0
29    }
30}
31
32unsafe impl<T> TrustedLen for Iter<'_, T> {}
33
34unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Copied<I>
35where
36    I: TrustedLen<Item = &'a T>,
37    T: Copy,
38{
39}
40unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Cloned<I>
41where
42    I: TrustedLen<Item = &'a T>,
43    T: Clone,
44{
45}
46
47unsafe impl<I> TrustedLen for std::iter::Enumerate<I> where I: TrustedLen {}
48
49unsafe impl<I> TrustedLen for std::iter::Empty<I> {}
50unsafe impl<A, B> TrustedLen for std::iter::Zip<A, B>
51where
52    A: TrustedLen,
53    B: TrustedLen,
54{
55}
56
57unsafe impl<T> TrustedLen for std::slice::ChunksExact<'_, T> {}
58
59unsafe impl<T> TrustedLen for std::slice::Windows<'_, T> {}
60
61unsafe impl<A, B> TrustedLen for std::iter::Chain<A, B>
62where
63    A: TrustedLen,
64    B: TrustedLen<Item = A::Item>,
65{
66}
67
68unsafe impl<T> TrustedLen for std::iter::Once<T> {}
69
70unsafe impl<T> TrustedLen for std::vec::IntoIter<T> {}
71
72unsafe impl<A: Clone> TrustedLen for std::iter::Repeat<A> {}
73unsafe impl<A: Clone> TrustedLen for std::iter::RepeatN<A> {}
74unsafe impl<A, F: FnMut() -> A> TrustedLen for std::iter::RepeatWith<F> {}
75unsafe impl<A: TrustedLen> TrustedLen for std::iter::Take<A> {}
76
77#[cfg(feature = "polars")]
78unsafe impl<T> PlTrustedLen for &mut dyn TrustedLen<Item = T> {}
79#[cfg(feature = "polars")]
80unsafe impl<T> PlTrustedLen for Box<dyn TrustedLen<Item = T> + '_> {}
81#[cfg(feature = "polars")]
82unsafe impl<T> TrustedLen for &mut dyn PlTrustedLen<Item = T> {}
83#[cfg(feature = "polars")]
84unsafe impl<T> TrustedLen for Box<dyn PlTrustedLen<Item = T> + '_> {}
85#[cfg(feature = "polars")]
86unsafe impl<T> TrustedLen for dyn PolarsIterator<Item = T> {}
87#[cfg(feature = "polars")]
88unsafe impl<T> TrustedLen for Box<dyn PolarsIterator<Item = T> + '_> {}
89
90unsafe impl<T> TrustedLen for &mut dyn TrustedLen<Item = T> {}
91unsafe impl<T> TrustedLen for Box<dyn TrustedLen<Item = T> + '_> {}
92
93unsafe impl<B, I: TrustedLen, T: FnMut(I::Item) -> B> TrustedLen for std::iter::Map<I, T> {}
94
95unsafe impl<I: TrustedLen + DoubleEndedIterator> TrustedLen for std::iter::Rev<I> {}
96
97unsafe impl<T> TrustedLen for std::ops::Range<T> where std::ops::Range<T>: Iterator {}
98unsafe impl<T> TrustedLen for std::ops::RangeInclusive<T> where std::ops::RangeInclusive<T>: Iterator
99{}
100unsafe impl<A: TrustedLen> TrustedLen for std::iter::StepBy<A> {}
101
102unsafe impl<I, St, F, B> TrustedLen for Scan<I, St, F>
103where
104    F: FnMut(&mut St, I::Item) -> Option<B>,
105    I: TrustedLen + Iterator<Item = B>,
106{
107}
108
109#[cfg(feature = "ndarray")]
110unsafe impl<A, D: tea_deps::ndarray::Dimension> TrustedLen
111    for tea_deps::ndarray::iter::Iter<'_, A, D>
112{
113}
114#[cfg(feature = "ndarray")]
115unsafe impl<A, D: tea_deps::ndarray::Dimension> TrustedLen
116    for tea_deps::ndarray::iter::IterMut<'_, A, D>
117{
118}
119
120// unsafe impl<K, V> TrustedLen for std::collections::hash_map::IntoIter<K, V> {}
121// unsafe impl<K, V> TrustedLen for std::collections::hash_map::IntoValues<K, V> {}
122
123#[cfg(feature = "vecdeque")]
124unsafe impl<T> TrustedLen for std::collections::vec_deque::IntoIter<T> {}
125#[cfg(feature = "vecdeque")]
126unsafe impl<T> TrustedLen for std::collections::vec_deque::Iter<'_, T> {}
127
128/// A wrapper struct for an iterator with a known length.
129///
130/// `TrustIter` wraps an iterator and stores its length, allowing it to implement
131/// `TrustedLen` and provide more efficient size hints.
132///
133/// # Type Parameters
134///
135/// * `I`: The type of the wrapped iterator, which must implement `Iterator`.
136///
137/// # Fields
138///
139/// * `iter`: The wrapped iterator.
140/// * `len`: The known length of the iterator.
141#[derive(Clone)]
142pub struct TrustIter<I: Iterator> {
143    iter: I,
144    len: usize,
145}
146
147impl<I> TrustIter<I>
148where
149    I: Iterator,
150{
151    #[inline]
152    pub fn new(iter: I, len: usize) -> Self {
153        Self { iter, len }
154    }
155}
156
157impl<I> Iterator for TrustIter<I>
158where
159    I: Iterator,
160{
161    type Item = I::Item;
162
163    #[inline]
164    fn next(&mut self) -> Option<Self::Item> {
165        self.iter.next()
166    }
167
168    fn size_hint(&self) -> (usize, Option<usize>) {
169        (self.len, Some(self.len))
170    }
171}
172
173impl<I> ExactSizeIterator for TrustIter<I> where I: Iterator {}
174
175impl<I> DoubleEndedIterator for TrustIter<I>
176where
177    I: Iterator + DoubleEndedIterator,
178{
179    #[inline]
180    fn next_back(&mut self) -> Option<Self::Item> {
181        self.iter.next_back()
182    }
183}
184
185#[cfg(feature = "polars")]
186unsafe impl<I: Iterator> PlTrustedLen for TrustIter<I> {}
187unsafe impl<I: Iterator> TrustedLen for TrustIter<I> {}
188
189/// A trait for converting an iterator into a `TrustIter`.
190///
191/// This trait provides a method to wrap an iterator with a known length
192/// into a `TrustIter`, which implements `TrustedLen`.
193pub trait ToTrustIter: IntoIterator {
194    /// Converts the iterator into a `TrustIter` with a known length.
195    ///
196    /// # Arguments
197    ///
198    /// * `self` - The iterator to be converted.
199    /// * `len` - The known length of the iterator.
200    ///
201    /// # Returns
202    ///
203    /// A `TrustIter` wrapping the original iterator with the specified length.
204    fn to_trust(self, len: usize) -> TrustIter<Self::IntoIter>;
205}
206
207impl<I: IntoIterator> ToTrustIter for I {
208    fn to_trust(self, len: usize) -> TrustIter<Self::IntoIter> {
209        TrustIter::new(self.into_iter(), len)
210    }
211}
212/// A trait for collecting items from a trusted iterator into a collection.
213///
214/// This trait provides methods to efficiently collect items from iterators
215/// that implement `TrustedLen`, allowing for optimized memory allocation
216/// and item placement.
217pub trait CollectTrusted<T> {
218    /// Collects items from a trusted iterator into the implementing collection.
219    ///
220    /// This method assumes that the iterator's length is known and trusted,
221    /// allowing for more efficient collection of items.
222    ///
223    /// # Arguments
224    ///
225    /// * `i` - An iterator with items of type `T` and implementing `TrustedLen`.
226    ///
227    /// # Returns
228    ///
229    /// The collection containing all items from the iterator.
230    fn collect_from_trusted<I>(i: I) -> Self
231    where
232        I: IntoIterator<Item = T>,
233        I::IntoIter: TrustedLen;
234
235    /// Attempts to collect items from a trusted iterator that may produce errors.
236    ///
237    /// This method is similar to `collect_from_trusted`, but handles iterators
238    /// that may produce `TResult<T>` items, allowing for error propagation.
239    ///
240    /// # Arguments
241    ///
242    /// * `i` - An iterator with items of type `TResult<T>` and implementing `TrustedLen`.
243    ///
244    /// # Returns
245    ///
246    /// A `TResult` containing either the successfully collected items or an error.
247    fn try_collect_from_trusted<I, E: Error>(iter: I) -> Result<Self, E>
248    where
249        I: IntoIterator<Item = Result<T, E>>,
250        I::IntoIter: TrustedLen,
251        Self: Sized;
252}
253
254impl<T> CollectTrusted<T> for Vec<T> {
255    /// safety: upper bound on the remaining length of the iterator must be correct.
256    fn collect_from_trusted<I>(iter: I) -> Self
257    where
258        I: IntoIterator<Item = T>,
259        I::IntoIter: TrustedLen,
260    {
261        let iter = iter.into_iter();
262        let len = iter
263            .size_hint()
264            .1
265            .expect("The iterator must have an upper bound");
266        let mut vec = Vec::<T>::with_capacity(len);
267        let mut ptr = vec.as_mut_ptr();
268        unsafe {
269            for v in iter {
270                std::ptr::write(ptr, v);
271                ptr = ptr.add(1);
272            }
273            vec.set_len(len);
274        }
275        vec
276    }
277
278    /// safety: upper bound on the remaining length of the iterator must be correct.
279    fn try_collect_from_trusted<I, E: Error>(iter: I) -> Result<Self, E>
280    where
281        I: IntoIterator<Item = Result<T, E>>,
282        I::IntoIter: TrustedLen,
283        Self: Sized,
284    {
285        let iter = iter.into_iter();
286        let len = iter
287            .size_hint()
288            .1
289            .expect("The iterator must have an upper bound");
290        let mut vec = Vec::<T>::with_capacity(len);
291        let mut ptr = vec.as_mut_ptr();
292        unsafe {
293            for v in iter {
294                let v = v?;
295                std::ptr::write(ptr, v);
296                ptr = ptr.add(1);
297            }
298            vec.set_len(len);
299        }
300        Ok(vec)
301    }
302}
303
304/// A trait for iterators that can be collected into a `Vec` with a trusted length.
305///
306/// This trait is implemented for all iterators that implement `TrustedLen`,
307/// allowing for efficient collection into a `Vec` without unnecessary reallocations.
308pub trait CollectTrustedToVec: Iterator + TrustedLen + Sized {
309    /// Collects the iterator into a `Vec` using the trusted length information.
310    ///
311    /// This method is more efficient than the standard `collect()` method for
312    /// iterators with a known length, as it can allocate the exact amount of
313    /// memory needed upfront.
314    ///
315    /// # Returns
316    ///
317    /// A `Vec` containing all the items from the iterator.
318    #[inline(always)]
319    fn collect_trusted_to_vec(self) -> Vec<Self::Item> {
320        CollectTrusted::<Self::Item>::collect_from_trusted(self)
321    }
322}
323
324/// A trait for iterators that can be collected into a `Vec` with a trusted length,
325/// where each item is a `Result`.
326///
327/// This trait is implemented for all iterators that implement `TrustedLen` and
328/// yield `Result` items, allowing for efficient collection into a `Vec` while
329/// propagating any errors encountered during iteration.
330pub trait TryCollectTrustedToVec<T, E: Error>:
331    Iterator<Item = Result<T, E>> + TrustedLen + Sized
332{
333    /// Attempts to collect the iterator into a `Vec` using the trusted length information.
334    ///
335    /// This method is more efficient than the standard `collect()` method for
336    /// iterators with a known length, as it can allocate the exact amount of
337    /// memory needed upfront. If any item in the iterator is an `Err`, the
338    /// collection process is short-circuited and the error is returned.
339    ///
340    /// # Returns
341    ///
342    /// A `TResult` containing either:
343    /// - `Ok(Vec<T>)`: A `Vec` containing all the successfully collected items.
344    /// - `Err(E)`: The first error encountered during iteration.
345    #[inline(always)]
346    fn try_collect_trusted_to_vec(self) -> Result<Vec<T>, E> {
347        CollectTrusted::<T>::try_collect_from_trusted(self)
348    }
349}
350
351impl<T: TrustedLen> CollectTrustedToVec for T {}
352impl<I: TrustedLen<Item = Result<T, E>> + Sized, T, E: Error> TryCollectTrustedToVec<T, E> for I {}