polars_arrow/
trusted_len.rs

1//! Declares [`TrustedLen`].
2use std::iter::Scan;
3use std::slice::{Iter, IterMut};
4
5/// An iterator of known, fixed size.
6///
7/// A trait denoting Rusts' unstable [TrustedLen](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
8/// This is re-defined here and implemented for some iterators until `std::iter::TrustedLen`
9/// is stabilized.
10///
11/// # Safety
12/// This trait must only be implemented when the contract is upheld.
13/// Consumers of this trait must inspect Iterator::size_hint()’s upper bound.
14pub unsafe trait TrustedLen: Iterator {}
15
16unsafe impl<T> TrustedLen for Iter<'_, T> {}
17unsafe impl<T> TrustedLen for IterMut<'_, T> {}
18
19unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Copied<I>
20where
21    I: TrustedLen<Item = &'a T>,
22    T: Copy,
23{
24}
25unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Cloned<I>
26where
27    I: TrustedLen<Item = &'a T>,
28    T: Clone,
29{
30}
31
32unsafe impl<I> TrustedLen for std::iter::Enumerate<I> where I: TrustedLen {}
33
34unsafe impl<A, B> TrustedLen for std::iter::Zip<A, B>
35where
36    A: TrustedLen,
37    B: TrustedLen,
38{
39}
40
41unsafe impl<T> TrustedLen for std::slice::ChunksExact<'_, T> {}
42
43unsafe impl<T> TrustedLen for std::slice::Windows<'_, T> {}
44
45unsafe impl<A, B> TrustedLen for std::iter::Chain<A, B>
46where
47    A: TrustedLen,
48    B: TrustedLen<Item = A::Item>,
49{
50}
51
52unsafe impl<T> TrustedLen for std::iter::Once<T> {}
53
54unsafe impl<T> TrustedLen for std::vec::IntoIter<T> {}
55
56unsafe impl<A: Clone> TrustedLen for std::iter::Repeat<A> {}
57unsafe impl<A, F: FnMut() -> A> TrustedLen for std::iter::RepeatWith<F> {}
58unsafe impl<A: TrustedLen> TrustedLen for std::iter::Take<A> {}
59
60unsafe impl<T> TrustedLen for &mut dyn TrustedLen<Item = T> {}
61unsafe impl<T> TrustedLen for Box<dyn TrustedLen<Item = T> + '_> {}
62
63unsafe impl<B, I: TrustedLen, T: FnMut(I::Item) -> B> TrustedLen for std::iter::Map<I, T> {}
64
65unsafe impl<I: TrustedLen + DoubleEndedIterator> TrustedLen for std::iter::Rev<I> {}
66
67unsafe impl<I: Iterator<Item = J>, J> TrustedLen for TrustMyLength<I, J> {}
68unsafe impl<T> TrustedLen for std::ops::Range<T> where std::ops::Range<T>: Iterator {}
69unsafe impl<T> TrustedLen for std::ops::RangeInclusive<T> where std::ops::RangeInclusive<T>: Iterator
70{}
71unsafe impl<A: TrustedLen> TrustedLen for std::iter::StepBy<A> {}
72
73unsafe impl<I, St, F, B> TrustedLen for Scan<I, St, F>
74where
75    F: FnMut(&mut St, I::Item) -> Option<B>,
76    I: TrustedLen,
77{
78}
79
80unsafe impl<K, V> TrustedLen for hashbrown::hash_map::IntoIter<K, V> {}
81
82#[derive(Clone)]
83pub struct TrustMyLength<I: Iterator<Item = J>, J> {
84    iter: I,
85    len: usize,
86}
87
88impl<I, J> TrustMyLength<I, J>
89where
90    I: Iterator<Item = J>,
91{
92    /// Create a new `TrustMyLength` iterator
93    ///
94    /// # Safety
95    ///
96    /// This is safe if the iterator always has the exact length given by `len`.
97    #[inline]
98    pub unsafe fn new(iter: I, len: usize) -> Self {
99        Self { iter, len }
100    }
101}
102
103impl<J: Clone> TrustMyLength<std::iter::Take<std::iter::Repeat<J>>, J> {
104    /// Create a new `TrustMyLength` iterator that repeats `value` `len` times.
105    pub fn new_repeat_n(value: J, len: usize) -> Self {
106        // SAFETY: This is always safe since repeat(..).take(n) always repeats exactly `n` times`.
107        unsafe { Self::new(std::iter::repeat(value).take(len), len) }
108    }
109}
110
111impl<I, J> Iterator for TrustMyLength<I, J>
112where
113    I: Iterator<Item = J>,
114{
115    type Item = J;
116
117    #[inline]
118    fn next(&mut self) -> Option<Self::Item> {
119        self.iter.next()
120    }
121
122    #[inline]
123    fn size_hint(&self) -> (usize, Option<usize>) {
124        (self.len, Some(self.len))
125    }
126}
127
128impl<I, J> ExactSizeIterator for TrustMyLength<I, J> where I: Iterator<Item = J> {}
129
130impl<I, J> DoubleEndedIterator for TrustMyLength<I, J>
131where
132    I: Iterator<Item = J> + DoubleEndedIterator,
133{
134    #[inline]
135    fn next_back(&mut self) -> Option<Self::Item> {
136        self.iter.next_back()
137    }
138}