vortex_buffer/
trusted_len.rs1use itertools::ProcessResults;
5
6pub unsafe trait TrustedLen: Iterator {}
17
18pub struct TrustedLenAdapter<I> {
24 inner: I,
25 len: usize,
26 #[cfg(debug_assertions)]
27 count: usize,
28}
29
30impl<I: Iterator> Iterator for TrustedLenAdapter<I> {
31 type Item = I::Item;
32
33 #[inline]
34 fn next(&mut self) -> Option<Self::Item> {
35 match self.inner.next() {
36 None => {
37 #[cfg(debug_assertions)]
38 {
39 assert_eq!(
40 self.len, self.count,
41 "TrustedLenAdapter: iterator ended early"
42 );
43 }
44 None
45 }
46 Some(item) => {
47 #[cfg(debug_assertions)]
48 {
49 self.count += 1;
50 assert!(
51 self.count <= self.len,
52 "TrustedLenAdapter: iterator yielded more items than promised"
53 );
54 }
55 Some(item)
56 }
57 }
58 }
59
60 #[inline]
61 fn size_hint(&self) -> (usize, Option<usize>) {
62 (self.len, Some(self.len))
63 }
64}
65
66unsafe impl<I: Iterator> TrustedLen for TrustedLenAdapter<I> {}
67
68pub trait TrustedLenExt: Iterator + Sized {
70 unsafe fn trusted_len(self) -> TrustedLenAdapter<Self> {
76 let (lower_bound, upper_bound_opt) = self.size_hint();
77 if let Some(upper_bound) = upper_bound_opt {
78 assert_eq!(
79 lower_bound, upper_bound,
80 "TrustedLenExt: iterator size hints must match if upper bound is given"
81 );
82 }
83
84 TrustedLenAdapter {
85 inner: self,
86 len: lower_bound,
87 #[cfg(debug_assertions)]
88 count: 0,
89 }
90 }
91}
92
93impl<I: Iterator> TrustedLenExt for I {}
94
95macro_rules! impl_for_range {
96 ($($typ:ty),*) => {
97 $(
98 unsafe impl TrustedLen for std::ops::Range<$typ> {}
99 unsafe impl TrustedLen for std::ops::RangeInclusive<$typ> {}
100 unsafe impl TrustedLen for std::iter::StepBy<std::ops::Range<$typ>> {}
103 unsafe impl TrustedLen for std::iter::StepBy<std::ops::RangeInclusive<$typ>> {}
104 )*
105 };
106}
107
108impl_for_range!(u8, u16, u32, u64, i8, i16, i32, i64, usize);
109
110unsafe impl<T> TrustedLen for std::slice::Iter<'_, T> {}
112
113unsafe impl<T> TrustedLen for std::slice::IterMut<'_, T> {}
114
115unsafe impl<B, I, F> TrustedLen for std::iter::Map<I, F>
117where
118 I: TrustedLen,
119 F: FnMut(I::Item) -> B,
120{
121}
122
123unsafe impl<I> TrustedLen for std::iter::Skip<I> where I: TrustedLen {}
124
125unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Copied<I>
126where
127 I: TrustedLen<Item = &'a T>,
128 T: Copy,
129{
130}
131
132unsafe impl<'a, I, T: 'a> TrustedLen for std::iter::Cloned<I>
133where
134 I: TrustedLen<Item = &'a T>,
135 T: Clone,
136{
137}
138
139unsafe impl<T> TrustedLen for std::vec::IntoIter<T> {}
140
141unsafe impl<T, const N: usize> TrustedLen for std::array::IntoIter<T, N> {}
143
144unsafe impl<T> TrustedLen for crate::Iter<'_, T> {}
146unsafe impl<T: Copy> TrustedLen for crate::BufferIterator<T> {}
147
148unsafe impl<'a, I, T: 'a, E: 'a> TrustedLen for ProcessResults<'a, I, E> where
150 I: TrustedLen<Item = Result<T, E>>
151{
152}
153
154unsafe impl<I, T> TrustedLen for std::iter::Enumerate<I> where I: TrustedLen<Item = T> {}
156
157unsafe impl<T, U> TrustedLen for std::iter::Zip<T, U>
159where
160 T: TrustedLen,
161 U: TrustedLen,
162{
163}
164
165unsafe impl<T: Clone> TrustedLen for std::iter::RepeatN<T> {}
166
167unsafe impl<'a> TrustedLen for crate::bit::BitIterator<'a> {}
169unsafe impl<'a> TrustedLen for crate::bit::BitChunkIterator<'a> {}
170unsafe impl<'a> TrustedLen for crate::bit::UnalignedBitChunkIterator<'a> {}