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