tea_core/vec_core/
trusted.rs

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