Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-arrow/src/trusted_len.rs
6939 views
1
//! Declares [`TrustedLen`].
2
use std::iter::Scan;
3
use 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.
14
pub unsafe trait TrustedLen: Iterator {}
15
16
unsafe impl<T> TrustedLen for Iter<'_, T> {}
17
unsafe impl<T> TrustedLen for IterMut<'_, T> {}
18
19
unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Copied<I>
20
where
21
I: TrustedLen<Item = &'a T>,
22
T: Copy,
23
{
24
}
25
unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Cloned<I>
26
where
27
I: TrustedLen<Item = &'a T>,
28
T: Clone,
29
{
30
}
31
32
unsafe impl<I> TrustedLen for std::iter::Enumerate<I> where I: TrustedLen {}
33
34
unsafe impl<A, B> TrustedLen for std::iter::Zip<A, B>
35
where
36
A: TrustedLen,
37
B: TrustedLen,
38
{
39
}
40
41
unsafe impl<T> TrustedLen for std::slice::ChunksExact<'_, T> {}
42
43
unsafe impl<T> TrustedLen for std::slice::Windows<'_, T> {}
44
45
unsafe impl<A, B> TrustedLen for std::iter::Chain<A, B>
46
where
47
A: TrustedLen,
48
B: TrustedLen<Item = A::Item>,
49
{
50
}
51
52
unsafe impl<T> TrustedLen for std::iter::Once<T> {}
53
54
unsafe impl<T> TrustedLen for std::vec::IntoIter<T> {}
55
56
unsafe impl<A: Clone> TrustedLen for std::iter::Repeat<A> {}
57
unsafe impl<A, F: FnMut() -> A> TrustedLen for std::iter::RepeatWith<F> {}
58
unsafe impl<A: TrustedLen> TrustedLen for std::iter::Take<A> {}
59
60
unsafe impl<A: Clone> TrustedLen for std::iter::RepeatN<A> {}
61
62
unsafe impl<T> TrustedLen for &mut dyn TrustedLen<Item = T> {}
63
unsafe impl<T> TrustedLen for Box<dyn TrustedLen<Item = T> + '_> {}
64
65
unsafe impl<B, I: TrustedLen, T: FnMut(I::Item) -> B> TrustedLen for std::iter::Map<I, T> {}
66
67
unsafe impl<I: TrustedLen + DoubleEndedIterator> TrustedLen for std::iter::Rev<I> {}
68
69
unsafe impl<I: Iterator<Item = J>, J> TrustedLen for TrustMyLength<I, J> {}
70
unsafe impl<T> TrustedLen for std::ops::Range<T> where std::ops::Range<T>: Iterator {}
71
unsafe impl<T> TrustedLen for std::ops::RangeInclusive<T> where std::ops::RangeInclusive<T>: Iterator
72
{}
73
unsafe impl<A: TrustedLen> TrustedLen for std::iter::StepBy<A> {}
74
75
unsafe impl<I, St, F, B> TrustedLen for Scan<I, St, F>
76
where
77
F: FnMut(&mut St, I::Item) -> Option<B>,
78
I: TrustedLen,
79
{
80
}
81
82
unsafe impl<K, V> TrustedLen for hashbrown::hash_map::IntoIter<K, V> {}
83
84
#[derive(Clone)]
85
pub struct TrustMyLength<I: Iterator<Item = J>, J> {
86
iter: I,
87
len: usize,
88
}
89
90
impl<I, J> TrustMyLength<I, J>
91
where
92
I: Iterator<Item = J>,
93
{
94
/// Create a new `TrustMyLength` iterator
95
///
96
/// # Safety
97
///
98
/// This is safe if the iterator always has the exact length given by `len`.
99
#[inline]
100
pub unsafe fn new(iter: I, len: usize) -> Self {
101
Self { iter, len }
102
}
103
}
104
105
impl<J: Clone> TrustMyLength<std::iter::RepeatN<J>, J> {
106
/// Create a new `TrustMyLength` iterator that repeats `value` `len` times.
107
pub fn new_repeat_n(value: J, len: usize) -> Self {
108
// SAFETY: This is always safe since repeat(..).take(n) always repeats exactly `n` times`.
109
unsafe { Self::new(std::iter::repeat_n(value, len), len) }
110
}
111
}
112
113
impl<I, J> Iterator for TrustMyLength<I, J>
114
where
115
I: Iterator<Item = J>,
116
{
117
type Item = J;
118
119
#[inline]
120
fn next(&mut self) -> Option<Self::Item> {
121
self.iter.next()
122
}
123
124
#[inline]
125
fn size_hint(&self) -> (usize, Option<usize>) {
126
(self.len, Some(self.len))
127
}
128
}
129
130
impl<I, J> ExactSizeIterator for TrustMyLength<I, J> where I: Iterator<Item = J> {}
131
132
impl<I, J> DoubleEndedIterator for TrustMyLength<I, J>
133
where
134
I: Iterator<Item = J> + DoubleEndedIterator,
135
{
136
#[inline]
137
fn next_back(&mut self) -> Option<Self::Item> {
138
self.iter.next_back()
139
}
140
}
141
142