1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
use std::iter::Scan;
use std::slice::Iter;

#[cfg(feature = "polars")]
use polars::export::arrow::trusted_len::TrustedLen as PlTrustedLen;
#[cfg(feature = "polars")]
use polars::prelude::PolarsIterator;
use tea_error::TResult;

/// An iterator of known, fixed size.
///
/// A trait denoting Rusts' unstable [TrustedLen](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
/// This is re-defined here and implemented for some iterators until `std::iter::TrustedLen`
/// is stabilized.
///
/// # Safety
/// This trait must only be implemented when the contract is upheld.
/// Consumers of this trait must inspect Iterator::size_hint()’s upper bound.
// #[cfg(not(feature = "polars"))]
pub unsafe trait TrustedLen: Iterator {
    #[inline]
    fn len(&self) -> usize {
        self.size_hint().1.unwrap()
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

unsafe impl<T> TrustedLen for Iter<'_, T> {}

unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Copied<I>
where
    I: TrustedLen<Item = &'a T>,
    T: Copy,
{
}
unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Cloned<I>
where
    I: TrustedLen<Item = &'a T>,
    T: Clone,
{
}

unsafe impl<I> TrustedLen for std::iter::Enumerate<I> where I: TrustedLen {}

unsafe impl<I> TrustedLen for std::iter::Empty<I> {}
unsafe impl<A, B> TrustedLen for std::iter::Zip<A, B>
where
    A: TrustedLen,
    B: TrustedLen,
{
}

unsafe impl<T> TrustedLen for std::slice::ChunksExact<'_, T> {}

unsafe impl<T> TrustedLen for std::slice::Windows<'_, T> {}

unsafe impl<A, B> TrustedLen for std::iter::Chain<A, B>
where
    A: TrustedLen,
    B: TrustedLen<Item = A::Item>,
{
}

unsafe impl<T> TrustedLen for std::iter::Once<T> {}

unsafe impl<T> TrustedLen for std::vec::IntoIter<T> {}

unsafe impl<A: Clone> TrustedLen for std::iter::Repeat<A> {}
unsafe impl<A, F: FnMut() -> A> TrustedLen for std::iter::RepeatWith<F> {}
unsafe impl<A: TrustedLen> TrustedLen for std::iter::Take<A> {}

#[cfg(feature = "polars")]
unsafe impl<T> PlTrustedLen for &mut dyn TrustedLen<Item = T> {}
#[cfg(feature = "polars")]
unsafe impl<'a, T> PlTrustedLen for Box<dyn TrustedLen<Item = T> + 'a> {}
#[cfg(feature = "polars")]
unsafe impl<T> TrustedLen for &mut dyn PlTrustedLen<Item = T> {}
#[cfg(feature = "polars")]
unsafe impl<'a, T> TrustedLen for Box<dyn PlTrustedLen<Item = T> + 'a> {}
#[cfg(feature = "polars")]
unsafe impl<T> TrustedLen for dyn PolarsIterator<Item = T> {}
#[cfg(feature = "polars")]
unsafe impl<'a, T> TrustedLen for Box<dyn PolarsIterator<Item = T> + 'a> {}

unsafe impl<T> TrustedLen for &mut dyn TrustedLen<Item = T> {}
unsafe impl<T> TrustedLen for Box<dyn TrustedLen<Item = T> + '_> {}

unsafe impl<B, I: TrustedLen, T: FnMut(I::Item) -> B> TrustedLen for std::iter::Map<I, T> {}

unsafe impl<I: TrustedLen + DoubleEndedIterator> TrustedLen for std::iter::Rev<I> {}

unsafe impl<T> TrustedLen for std::ops::Range<T> where std::ops::Range<T>: Iterator {}
unsafe impl<T> TrustedLen for std::ops::RangeInclusive<T> where std::ops::RangeInclusive<T>: Iterator
{}
unsafe impl<A: TrustedLen> TrustedLen for std::iter::StepBy<A> {}

unsafe impl<I, St, F, B> TrustedLen for Scan<I, St, F>
where
    F: FnMut(&mut St, I::Item) -> Option<B>,
    I: TrustedLen + Iterator<Item = B>,
{
}

#[cfg(feature = "ndarray")]
unsafe impl<'a, A, D: ndarray::Dimension> TrustedLen for ndarray::iter::Iter<'a, A, D> {}
#[cfg(feature = "ndarray")]
unsafe impl<'a, A, D: ndarray::Dimension> TrustedLen for ndarray::iter::IterMut<'a, A, D> {}

// unsafe impl<K, V> TrustedLen for std::collections::hash_map::IntoIter<K, V> {}
// unsafe impl<K, V> TrustedLen for std::collections::hash_map::IntoValues<K, V> {}

#[cfg(feature = "vecdeque")]
unsafe impl<T> TrustedLen for std::collections::vec_deque::IntoIter<T> {}
#[cfg(feature = "vecdeque")]
unsafe impl<'a, T> TrustedLen for std::collections::vec_deque::Iter<'a, T> {}

/// A wrapper struct for an iterator with a known length.
///
/// `TrustIter` wraps an iterator and stores its length, allowing it to implement
/// `TrustedLen` and provide more efficient size hints.
///
/// # Type Parameters
///
/// * `I`: The type of the wrapped iterator, which must implement `Iterator`.
///
/// # Fields
///
/// * `iter`: The wrapped iterator.
/// * `len`: The known length of the iterator.
#[derive(Clone)]
pub struct TrustIter<I: Iterator> {
    iter: I,
    len: usize,
}

impl<I> TrustIter<I>
where
    I: Iterator,
{
    #[inline]
    pub fn new(iter: I, len: usize) -> Self {
        Self { iter, len }
    }
}

impl<I> Iterator for TrustIter<I>
where
    I: Iterator,
{
    type Item = I::Item;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl<I> ExactSizeIterator for TrustIter<I> where I: Iterator {}

impl<I> DoubleEndedIterator for TrustIter<I>
where
    I: Iterator + DoubleEndedIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iter.next_back()
    }
}

#[cfg(feature = "polars")]
unsafe impl<I: Iterator> PlTrustedLen for TrustIter<I> {}
unsafe impl<I: Iterator> TrustedLen for TrustIter<I> {}

/// A trait for converting an iterator into a `TrustIter`.
///
/// This trait provides a method to wrap an iterator with a known length
/// into a `TrustIter`, which implements `TrustedLen`.
pub trait ToTrustIter: IntoIterator {
    /// Converts the iterator into a `TrustIter` with a known length.
    ///
    /// # Arguments
    ///
    /// * `self` - The iterator to be converted.
    /// * `len` - The known length of the iterator.
    ///
    /// # Returns
    ///
    /// A `TrustIter` wrapping the original iterator with the specified length.
    fn to_trust(self, len: usize) -> TrustIter<Self::IntoIter>;
}

impl<I: IntoIterator> ToTrustIter for I {
    fn to_trust(self, len: usize) -> TrustIter<Self::IntoIter> {
        TrustIter::new(self.into_iter(), len)
    }
}
/// A trait for collecting items from a trusted iterator into a collection.
///
/// This trait provides methods to efficiently collect items from iterators
/// that implement `TrustedLen`, allowing for optimized memory allocation
/// and item placement.
pub trait CollectTrusted<T> {
    /// Collects items from a trusted iterator into the implementing collection.
    ///
    /// This method assumes that the iterator's length is known and trusted,
    /// allowing for more efficient collection of items.
    ///
    /// # Arguments
    ///
    /// * `i` - An iterator with items of type `T` and implementing `TrustedLen`.
    ///
    /// # Returns
    ///
    /// The collection containing all items from the iterator.
    fn collect_from_trusted<I>(i: I) -> Self
    where
        I: IntoIterator<Item = T>,
        I::IntoIter: TrustedLen;

    /// Attempts to collect items from a trusted iterator that may produce errors.
    ///
    /// This method is similar to `collect_from_trusted`, but handles iterators
    /// that may produce `TResult<T>` items, allowing for error propagation.
    ///
    /// # Arguments
    ///
    /// * `i` - An iterator with items of type `TResult<T>` and implementing `TrustedLen`.
    ///
    /// # Returns
    ///
    /// A `TResult` containing either the successfully collected items or an error.
    fn try_collect_from_trusted<I>(i: I) -> TResult<Self>
    where
        I: IntoIterator<Item = TResult<T>>,
        I::IntoIter: TrustedLen,
        Self: Sized;
}

impl<T> CollectTrusted<T> for Vec<T> {
    /// safety: upper bound on the remaining length of the iterator must be correct.
    fn collect_from_trusted<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = T>,
        I::IntoIter: TrustedLen,
    {
        let iter = iter.into_iter();
        let len = iter
            .size_hint()
            .1
            .expect("The iterator must have an upper bound");
        let mut vec = Vec::<T>::with_capacity(len);
        let mut ptr = vec.as_mut_ptr();
        unsafe {
            for v in iter {
                std::ptr::write(ptr, v);
                ptr = ptr.add(1);
            }
            vec.set_len(len);
        }
        vec
    }

    /// safety: upper bound on the remaining length of the iterator must be correct.
    fn try_collect_from_trusted<I>(iter: I) -> TResult<Self>
    where
        I: IntoIterator<Item = TResult<T>>,
        I::IntoIter: TrustedLen,
        Self: Sized,
    {
        let iter = iter.into_iter();
        let len = iter
            .size_hint()
            .1
            .expect("The iterator must have an upper bound");
        let mut vec = Vec::<T>::with_capacity(len);
        let mut ptr = vec.as_mut_ptr();
        unsafe {
            for v in iter {
                let v = v?;
                std::ptr::write(ptr, v);
                ptr = ptr.add(1);
            }
            vec.set_len(len);
        }
        Ok(vec)
    }
}

/// A trait for iterators that can be collected into a `Vec` with a trusted length.
///
/// This trait is implemented for all iterators that implement `TrustedLen`,
/// allowing for efficient collection into a `Vec` without unnecessary reallocations.
pub trait CollectTrustedToVec: Iterator + TrustedLen + Sized {
    /// Collects the iterator into a `Vec` using the trusted length information.
    ///
    /// This method is more efficient than the standard `collect()` method for
    /// iterators with a known length, as it can allocate the exact amount of
    /// memory needed upfront.
    ///
    /// # Returns
    ///
    /// A `Vec` containing all the items from the iterator.
    #[inline(always)]
    fn collect_trusted_to_vec(self) -> Vec<Self::Item> {
        CollectTrusted::<Self::Item>::collect_from_trusted(self)
    }
}

/// A trait for iterators that can be collected into a `Vec` with a trusted length,
/// where each item is a `Result`.
///
/// This trait is implemented for all iterators that implement `TrustedLen` and
/// yield `Result` items, allowing for efficient collection into a `Vec` while
/// propagating any errors encountered during iteration.
pub trait TryCollectTrustedToVec<T>: Iterator<Item = TResult<T>> + TrustedLen + Sized {
    /// Attempts to collect the iterator into a `Vec` using the trusted length information.
    ///
    /// This method is more efficient than the standard `collect()` method for
    /// iterators with a known length, as it can allocate the exact amount of
    /// memory needed upfront. If any item in the iterator is an `Err`, the
    /// collection process is short-circuited and the error is returned.
    ///
    /// # Returns
    ///
    /// A `TResult` containing either:
    /// - `Ok(Vec<T>)`: A `Vec` containing all the successfully collected items.
    /// - `Err(E)`: The first error encountered during iteration.
    #[inline(always)]
    fn try_collect_trusted_to_vec(self) -> TResult<Vec<T>> {
        CollectTrusted::<T>::try_collect_from_trusted(self)
    }
}

impl<T: TrustedLen> CollectTrustedToVec for T {}
impl<I: TrustedLen<Item = TResult<T>> + Sized, T> TryCollectTrustedToVec<T> for I {}