1 use super::plumbing::*; 2 use super::*; 3 4 /// `MinLen` is an iterator that imposes a minimum length on iterator splits. 5 /// This struct is created by the [`with_min_len()`] method on [`IndexedParallelIterator`] 6 /// 7 /// [`with_min_len()`]: trait.IndexedParallelIterator.html#method.with_min_len 8 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html 9 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 10 #[derive(Debug, Clone)] 11 pub struct MinLen<I: IndexedParallelIterator> { 12 base: I, 13 min: usize, 14 } 15 16 impl<I> MinLen<I> 17 where 18 I: IndexedParallelIterator, 19 { 20 /// Creates a new `MinLen` iterator. new(base: I, min: usize) -> Self21 pub(super) fn new(base: I, min: usize) -> Self { 22 MinLen { base, min } 23 } 24 } 25 26 impl<I> ParallelIterator for MinLen<I> 27 where 28 I: IndexedParallelIterator, 29 { 30 type Item = I::Item; 31 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,32 fn drive_unindexed<C>(self, consumer: C) -> C::Result 33 where 34 C: UnindexedConsumer<Self::Item>, 35 { 36 bridge(self, consumer) 37 } 38 opt_len(&self) -> Option<usize>39 fn opt_len(&self) -> Option<usize> { 40 Some(self.len()) 41 } 42 } 43 44 impl<I> IndexedParallelIterator for MinLen<I> 45 where 46 I: IndexedParallelIterator, 47 { drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result48 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result { 49 bridge(self, consumer) 50 } 51 len(&self) -> usize52 fn len(&self) -> usize { 53 self.base.len() 54 } 55 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,56 fn with_producer<CB>(self, callback: CB) -> CB::Output 57 where 58 CB: ProducerCallback<Self::Item>, 59 { 60 return self.base.with_producer(Callback { 61 callback, 62 min: self.min, 63 }); 64 65 struct Callback<CB> { 66 callback: CB, 67 min: usize, 68 } 69 70 impl<T, CB> ProducerCallback<T> for Callback<CB> 71 where 72 CB: ProducerCallback<T>, 73 { 74 type Output = CB::Output; 75 fn callback<P>(self, base: P) -> CB::Output 76 where 77 P: Producer<Item = T>, 78 { 79 let producer = MinLenProducer { 80 base, 81 min: self.min, 82 }; 83 self.callback.callback(producer) 84 } 85 } 86 } 87 } 88 89 /// //////////////////////////////////////////////////////////////////////// 90 /// `MinLenProducer` implementation 91 92 struct MinLenProducer<P> { 93 base: P, 94 min: usize, 95 } 96 97 impl<P> Producer for MinLenProducer<P> 98 where 99 P: Producer, 100 { 101 type Item = P::Item; 102 type IntoIter = P::IntoIter; 103 into_iter(self) -> Self::IntoIter104 fn into_iter(self) -> Self::IntoIter { 105 self.base.into_iter() 106 } 107 min_len(&self) -> usize108 fn min_len(&self) -> usize { 109 Ord::max(self.min, self.base.min_len()) 110 } 111 max_len(&self) -> usize112 fn max_len(&self) -> usize { 113 self.base.max_len() 114 } 115 split_at(self, index: usize) -> (Self, Self)116 fn split_at(self, index: usize) -> (Self, Self) { 117 let (left, right) = self.base.split_at(index); 118 ( 119 MinLenProducer { 120 base: left, 121 min: self.min, 122 }, 123 MinLenProducer { 124 base: right, 125 min: self.min, 126 }, 127 ) 128 } 129 fold_with<F>(self, folder: F) -> F where F: Folder<Self::Item>,130 fn fold_with<F>(self, folder: F) -> F 131 where 132 F: Folder<Self::Item>, 133 { 134 self.base.fold_with(folder) 135 } 136 } 137 138 /// `MaxLen` is an iterator that imposes a maximum length on iterator splits. 139 /// This struct is created by the [`with_max_len()`] method on [`IndexedParallelIterator`] 140 /// 141 /// [`with_max_len()`]: trait.IndexedParallelIterator.html#method.with_max_len 142 /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html 143 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] 144 #[derive(Debug, Clone)] 145 pub struct MaxLen<I: IndexedParallelIterator> { 146 base: I, 147 max: usize, 148 } 149 150 impl<I> MaxLen<I> 151 where 152 I: IndexedParallelIterator, 153 { 154 /// Creates a new `MaxLen` iterator. new(base: I, max: usize) -> Self155 pub(super) fn new(base: I, max: usize) -> Self { 156 MaxLen { base, max } 157 } 158 } 159 160 impl<I> ParallelIterator for MaxLen<I> 161 where 162 I: IndexedParallelIterator, 163 { 164 type Item = I::Item; 165 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,166 fn drive_unindexed<C>(self, consumer: C) -> C::Result 167 where 168 C: UnindexedConsumer<Self::Item>, 169 { 170 bridge(self, consumer) 171 } 172 opt_len(&self) -> Option<usize>173 fn opt_len(&self) -> Option<usize> { 174 Some(self.len()) 175 } 176 } 177 178 impl<I> IndexedParallelIterator for MaxLen<I> 179 where 180 I: IndexedParallelIterator, 181 { drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result182 fn drive<C: Consumer<Self::Item>>(self, consumer: C) -> C::Result { 183 bridge(self, consumer) 184 } 185 len(&self) -> usize186 fn len(&self) -> usize { 187 self.base.len() 188 } 189 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,190 fn with_producer<CB>(self, callback: CB) -> CB::Output 191 where 192 CB: ProducerCallback<Self::Item>, 193 { 194 return self.base.with_producer(Callback { 195 callback, 196 max: self.max, 197 }); 198 199 struct Callback<CB> { 200 callback: CB, 201 max: usize, 202 } 203 204 impl<T, CB> ProducerCallback<T> for Callback<CB> 205 where 206 CB: ProducerCallback<T>, 207 { 208 type Output = CB::Output; 209 fn callback<P>(self, base: P) -> CB::Output 210 where 211 P: Producer<Item = T>, 212 { 213 let producer = MaxLenProducer { 214 base, 215 max: self.max, 216 }; 217 self.callback.callback(producer) 218 } 219 } 220 } 221 } 222 223 /// //////////////////////////////////////////////////////////////////////// 224 /// `MaxLenProducer` implementation 225 226 struct MaxLenProducer<P> { 227 base: P, 228 max: usize, 229 } 230 231 impl<P> Producer for MaxLenProducer<P> 232 where 233 P: Producer, 234 { 235 type Item = P::Item; 236 type IntoIter = P::IntoIter; 237 into_iter(self) -> Self::IntoIter238 fn into_iter(self) -> Self::IntoIter { 239 self.base.into_iter() 240 } 241 min_len(&self) -> usize242 fn min_len(&self) -> usize { 243 self.base.min_len() 244 } 245 max_len(&self) -> usize246 fn max_len(&self) -> usize { 247 Ord::min(self.max, self.base.max_len()) 248 } 249 split_at(self, index: usize) -> (Self, Self)250 fn split_at(self, index: usize) -> (Self, Self) { 251 let (left, right) = self.base.split_at(index); 252 ( 253 MaxLenProducer { 254 base: left, 255 max: self.max, 256 }, 257 MaxLenProducer { 258 base: right, 259 max: self.max, 260 }, 261 ) 262 } 263 fold_with<F>(self, folder: F) -> F where F: Folder<Self::Item>,264 fn fold_with<F>(self, folder: F) -> F 265 where 266 F: Folder<Self::Item>, 267 { 268 self.base.fold_with(folder) 269 } 270 } 271