Fri, 13 Oct 2023 13:32:15 -0500
Update Cargo.lock to stop build failures with current nightly rust.
| 5 | 1 | /*! | 
| 2 | Iteration utilities. | |
| 3 | ||
| 4 | This includes | |
| 5 | * [Stateful][StatefulIterator] and [restartable][RestartableIterator] iterators. | |
| 6 | * Variants of [`Iterator::map`] and [`Iterator::filter_map`], etc., that work on functions | |
| 7 | instead of closures, forgoing exact closure type signature specification; see [`Mappable`]. | |
| 8 | ||
| 9 | */ | |
| 0 | 10 | |
| 11 | use crate::types::Integer; | |
| 12 | use std::marker::PhantomData; | |
| 13 | ||
| 14 | /// Trait for iterators that can be queried the current state without advancing. | |
| 15 | pub trait StatefulIterator : Iterator { | |
| 16 | /// Return current value of iterator. If the iterator has not yet started, | |
| 17 | /// `None` should be returned. | |
| 18 | fn current(&self) -> Option<Self::Item>; | |
| 19 | } | |
| 20 | ||
| 21 | /// Iterators that can be restarted and queried the current state without | |
| 22 | /// advancing to next state. | |
| 23 | pub trait RestartableIterator : StatefulIterator { | |
| 24 | /// Restart the iterator. Return the first item. | |
| 25 | fn restart(&mut self) -> Option<Self::Item>; | |
| 26 | } | |
| 27 | ||
| 28 | /// A variant of `std::iter::Map` that works for methods instead of closures, | |
| 29 | /// so can be returned from functions without `dyn`. | |
| 30 | /// Use [`Mappable::mapF`] to create this iterator. | |
| 31 | pub struct MapF<I,J> where I : Iterator { | |
| 32 | iter : I, | |
| 33 | func : fn(I::Item) -> J, | |
| 34 | } | |
| 35 | ||
| 36 | impl<I,J> Iterator for MapF<I,J> where I : Iterator { | |
| 37 | type Item = J; | |
| 38 | fn next(&mut self) -> Option<J> { | |
| 39 | self.iter.next().map(|item| (self.func)(item)) | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | /// A variant of [`MapF`] with extra data for the function stored as a reference. | |
| 44 | /// See also [`MapZ`] and use [`Mappable::mapX`] to create this iteartor. | |
| 45 | pub struct MapX<'a,I,T,J> where I : Iterator { | |
| 46 | iter : I, | |
| 47 | data : &'a T, | |
| 48 | func : fn(&'a T, I::Item) -> J, | |
| 49 | } | |
| 50 | ||
| 51 | impl<'a,I,T,J> Iterator for MapX<'a,I,T,J> where I : Iterator { | |
| 52 | type Item = J; | |
| 53 | fn next(&mut self) -> Option<J> { | |
| 54 | self.iter.next().map(|item| (self.func)(self.data, item)) | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | /// A variant of [`MapF`] and [`MapX`] with extra data for the function stored in the struct. | |
| 59 | /// Use [`Mappable::mapZ`] to create this iterator. | |
| 60 | pub struct MapZ<I,T,J> where I : Iterator { | |
| 61 | iter : I, | |
| 62 | data : T, | |
| 63 | func : fn(&T, I::Item) -> J, | |
| 64 | } | |
| 65 | ||
| 66 | impl<'a,I,T,J> Iterator for MapZ<I,T,J> where I : Iterator { | |
| 67 | type Item = J; | |
| 68 | fn next(&mut self) -> Option<J> { | |
| 69 | self.iter.next().map(|item| (self.func)(&self.data, item)) | |
| 70 | } | |
| 71 | } | |
| 72 | ||
| 73 | /// A variant of `std::iter::FilterMap` that works for methods instead of closures, | |
| 74 | /// so can be returned from functions without `dyn`. | |
| 75 | pub struct FilterMapX<'a,I,T,J> where I : Iterator { | |
| 76 | iter : I, | |
| 77 | data : &'a T, | |
| 78 | func : fn(&'a T, I::Item) -> Option<J>, | |
| 79 | } | |
| 80 | ||
| 81 | impl<'a,I,T,J> Iterator for FilterMapX<'a,I,T,J> where I : Iterator { | |
| 82 | type Item = J; | |
| 83 | fn next(&mut self) -> Option<J> { | |
| 84 | while let Some(item) = self.iter.next() { | |
| 85 | let v = (self.func)(self.data, item); | |
| 86 | if v.is_some() { | |
| 87 | return v | |
| 88 | } | |
| 89 | } | |
| 90 | None | |
| 91 | } | |
| 92 | } | |
| 93 | ||
| 94 | /// Helper for [`Mappable::filter_zip`]. | |
| 95 | pub struct FilterZip<I, J> | |
| 96 | where I : Iterator, | |
| 97 | J : Iterator<Item=bool> { | |
| 98 | iter : I, | |
| 99 | filter : J, | |
| 100 | } | |
| 101 | ||
| 102 | impl<I,J> Iterator for FilterZip<I, J> | |
| 103 | where I : Iterator, | |
| 104 | J : Iterator<Item=bool> { | |
| 105 | type Item = I::Item; | |
| 106 | #[inline] | |
| 107 | fn next(&mut self) -> Option<I::Item> { | |
| 108 | while let (v@Some(..), Some(filt)) = (self.iter.next(), self.filter.next()) { | |
| 109 | if filt { | |
| 110 | return v | |
| 111 | } | |
| 112 | } | |
| 113 | None | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | /// This trait implements several mapping methods on iterators. | |
| 118 | pub trait Mappable : Iterator + Sized { | |
| 119 | /// Apply `func` to the output of the iterator. | |
| 120 | #[allow(non_snake_case)] | |
| 121 | fn mapF<J>(self, func : fn(Self::Item) -> J) -> MapF<Self,J>; | |
| 122 | /// Apply `func` to the output of the iterator, passing also `d` to it. | |
| 123 | #[allow(non_snake_case)] | |
| 124 | fn mapX<'a,T,J>(self, d : &'a T, func : fn(&'a T, Self::Item) -> J) -> MapX<'a,Self,T,J>; | |
| 125 | /// Apply `func` to the output of the iterator, passing also `d` to it. | |
| 126 | #[allow(non_snake_case)] | |
| 127 | fn mapZ<T,J>(self, d : T, func : fn(&T, Self::Item) -> J) -> MapZ<Self,T,J>; | |
| 128 | /// Apply `func` to the output of the iterator, filtering based on the result. | |
| 129 | /// The data `d` is passed to `func`. | |
| 130 | #[allow(non_snake_case)] | |
| 131 | fn filter_mapX<'a,T,J>(self, d : &'a T, func : fn(&'a T, Self::Item) -> Option<J>) -> FilterMapX<'a,Self,T,J>; | |
| 132 | ||
| 133 | /// Filter `self` based on another iterator `iter` with `bool` items. | |
| 134 | fn filter_zip<J>(self, filter : J) -> FilterZip<Self, J> where J : Iterator<Item=bool>; | |
| 135 | } | |
| 136 | ||
| 137 | impl<I> Mappable for I where I : Iterator + Sized { | |
| 138 | #[inline] | |
| 139 | fn mapF<J>(self, func : fn(Self::Item) -> J) -> MapF<Self,J> { | |
| 140 | MapF{ iter : self, func : func } | |
| 141 | } | |
| 142 | #[inline] | |
| 143 | fn mapX<'a,T,J>(self, d : &'a T, func : fn(&'a T, Self::Item) -> J) -> MapX<'a,Self,T,J> { | |
| 144 | MapX{ iter : self, data : d, func : func } | |
| 145 | } | |
| 146 | #[inline] | |
| 147 | fn mapZ<T,J>(self, d : T, func : fn(&T, Self::Item) -> J) -> MapZ<Self,T,J> { | |
| 148 | MapZ{ iter : self, data : d, func : func } | |
| 149 | } | |
| 150 | #[inline] | |
| 151 | fn filter_mapX<'a,T,J>(self, d : &'a T, func : fn(&'a T, Self::Item) -> Option<J>) | |
| 152 | -> FilterMapX<'a,Self,T,J> { | |
| 153 | FilterMapX{ iter : self, data : d, func : func } | |
| 154 | } | |
| 155 | ||
| 156 | #[inline] | |
| 157 | fn filter_zip<J>(self, filter : J) -> FilterZip<Self, J> | |
| 158 | where J : Iterator<Item=bool> { | |
| 159 | FilterZip{ iter : self, filter : filter } | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 163 | /// A [`RestartableIterator`] over the range ´[start, end)`. | |
| 164 | #[derive(Clone,Copy,Debug)] | |
| 165 | pub struct RangeIter<T> { | |
| 166 | start : T, | |
| 167 | end : T, | |
| 168 | value : Option<T>, | |
| 169 | } | |
| 170 | ||
| 171 | pub trait StepNext : Ord + Copy { | |
| 172 | fn step_next(&self) -> Self; | |
| 173 | fn dist_to(&self, other : &Self) -> usize; | |
| 174 | } | |
| 175 | ||
| 176 | impl<T : Integer + Into<usize>> StepNext for T { | |
| 177 | #[inline] | |
| 178 | fn step_next(&self) -> Self { *self + Self::ONE } | |
| 179 | ||
| 180 | #[inline] | |
| 181 | fn dist_to(&self, other : &Self) -> usize { | |
| 182 | if *other >= *self { | |
| 183 | (*other - *self).into() | |
| 184 | } else { | |
| 185 | 0 | |
| 186 | } | |
| 187 | } | |
| 188 | } | |
| 189 | ||
| 190 | impl<T : StepNext> RangeIter<T> { | |
| 191 | /// Create a new [`RangeIter`]. | |
| 192 | pub fn new(start : T, end : T) -> Self { | |
| 193 | RangeIter{ start : start.min(end), end : end, value : None } | |
| 194 | } | |
| 195 | } | |
| 196 | ||
| 197 | impl<T : StepNext> Iterator for RangeIter<T> { | |
| 198 | type Item = T; | |
| 199 | ||
| 200 | #[inline] | |
| 201 | fn next(&mut self) -> Option<Self::Item> { | |
| 202 | match self.value { | |
| 203 | None => { | |
| 204 | if self.start < self.end { | |
| 205 | self.value = Some(self.start); | |
| 206 | self.value | |
| 207 | } else { | |
| 208 | None | |
| 209 | } | |
| 210 | } | |
| 211 | Some(v) => { | |
| 212 | let vn = v.step_next(); | |
| 213 | if vn < self.end { | |
| 214 | self.value = Some(vn); | |
| 215 | self.value | |
| 216 | } else { | |
| 217 | None | |
| 218 | } | |
| 219 | } | |
| 220 | } | |
| 221 | } | |
| 222 | } | |
| 223 | ||
| 224 | impl<T : StepNext> ExactSizeIterator for RangeIter<T> { | |
| 225 | #[inline] | |
| 226 | fn len(&self) -> usize { self.start.dist_to(&self.end) } | |
| 227 | } | |
| 228 | ||
| 229 | impl<T : StepNext> StatefulIterator for RangeIter<T> { | |
| 230 | #[inline] | |
| 231 | fn current(&self) -> Option<Self::Item> { | |
| 232 | self.value | |
| 233 | } | |
| 234 | } | |
| 235 | ||
| 236 | impl<T : StepNext> RestartableIterator for RangeIter<T> { | |
| 237 | fn restart(&mut self) -> Option<Self::Item> { | |
| 238 | if self.start < self.end { | |
| 239 | self.value = Some(self.start); | |
| 240 | self.value | |
| 241 | } else { | |
| 242 | None | |
| 243 | } | |
| 244 | } | |
| 245 | } | |
| 246 | ||
| 5 | 247 | /// A restartable slice iterator. | 
| 248 | pub struct RestartableSliceIter<'a, T> { | |
| 0 | 249 | inner : RangeIter<*const T>, | 
| 250 | _phantom : PhantomData<&'a[T]> | |
| 251 | } | |
| 252 | ||
| 253 | impl<T> StepNext for *const T { | |
| 254 | #[inline] | |
| 255 | fn step_next(&self) -> Self { unsafe { self.add(1) } } | |
| 256 | ||
| 257 | #[inline] | |
| 258 | fn dist_to(&self, other : &Self) -> usize { | |
| 259 | unsafe { other.offset_from(*self).max(0) as usize } | |
| 260 | } | |
| 261 | } | |
| 262 | ||
| 5 | 263 | impl<'a, T : 'a> RestartableSliceIter<'a, T> { | 
| 264 | /// Converts `Some` pointer to `Some` reference | |
| 0 | 265 | fn map_result(result : Option<*const T>) -> Option<&'a T> { | 
| 266 | match result { | |
| 267 | None => { None } | |
| 268 | Some(ptr) => { Some(unsafe{ &*ptr }) } | |
| 269 | } | |
| 270 | } | |
| 271 | ||
| 5 | 272 | /// Creates a restartable iterator over `slice`. | 
| 0 | 273 | pub fn new(slice : &'a [T]) -> Self { | 
| 274 | let ptr_range = slice.as_ptr_range(); | |
| 275 | let inner = RangeIter::new(ptr_range.start, ptr_range.end); | |
| 5 | 276 | RestartableSliceIter{ inner : inner, _phantom : PhantomData } | 
| 0 | 277 | } | 
| 278 | } | |
| 279 | ||
| 5 | 280 | impl<'a, T : 'a> Iterator for RestartableSliceIter<'a, T> { | 
| 0 | 281 | type Item = &'a T; | 
| 282 | #[inline] | |
| 283 | fn next(&mut self) -> Option<&'a T> { | |
| 284 | Self::map_result(self.inner.next()) | |
| 285 | } | |
| 286 | } | |
| 287 | ||
| 5 | 288 | impl<'a, T : 'a> ExactSizeIterator for RestartableSliceIter<'a, T> { | 
| 0 | 289 | #[inline] | 
| 290 | fn len(&self) -> usize { self.inner.len() } | |
| 291 | } | |
| 292 | ||
| 5 | 293 | impl<'a, T : 'a> StatefulIterator for RestartableSliceIter<'a, T> { | 
| 0 | 294 | #[inline] | 
| 295 | fn current(&self) -> Option<Self::Item> { | |
| 296 | Self::map_result(self.inner.current()) | |
| 297 | } | |
| 298 | } | |
| 299 | ||
| 5 | 300 | impl<'a, T : 'a> RestartableIterator for RestartableSliceIter<'a, T> { | 
| 0 | 301 | fn restart(&mut self) -> Option<Self::Item> { | 
| 302 | Self::map_result(self.inner.current()) | |
| 303 | } | |
| 304 | } | |
| 305 | ||
| 5 | 306 | /// A restartable variant of [`std::iter::Cloned`]. | 
| 0 | 307 | pub struct RestartableCloned<I : Iterator> { | 
| 308 | inner : I, | |
| 309 | } | |
| 310 | ||
| 311 | impl<'a, T : Clone + 'a , I : Iterator<Item=&'a T>> RestartableCloned<I> { | |
| 312 | fn map_result(result : Option<I::Item>) -> Option<T> { | |
| 313 | match result { | |
| 314 | None => { None } | |
| 315 | Some(v) => { Some(v.clone()) } | |
| 316 | } | |
| 317 | } | |
| 318 | ||
| 319 | pub fn new(inner : I) -> Self { | |
| 320 | RestartableCloned{ inner : inner } | |
| 321 | } | |
| 322 | } | |
| 323 | ||
| 324 | impl<'a, T : Clone + 'a , I : Iterator<Item=&'a T>> Iterator | |
| 325 | for RestartableCloned<I> { | |
| 326 | type Item = T; | |
| 327 | fn next(&mut self) -> Option<Self::Item> { | |
| 328 | Self::map_result(self.inner.next()) | |
| 329 | } | |
| 330 | } | |
| 331 | ||
| 332 | impl<'a, T : Clone + 'a , I : ExactSizeIterator<Item=&'a T>> ExactSizeIterator | |
| 333 | for RestartableCloned<I> { | |
| 334 | fn len(&self) -> usize { | |
| 335 | self.inner.len() | |
| 336 | } | |
| 337 | } | |
| 338 | ||
| 339 | impl<'a, T : Clone + 'a , I : StatefulIterator<Item=&'a T>> StatefulIterator | |
| 340 | for RestartableCloned<I> { | |
| 341 | fn current(&self) -> Option<Self::Item> { | |
| 342 | Self::map_result(self.inner.current()) | |
| 343 | } | |
| 344 | } | |
| 345 | ||
| 346 | impl<'a, T : Clone + 'a , I : RestartableIterator<Item=&'a T>> RestartableIterator | |
| 347 | for RestartableCloned<I> { | |
| 348 | fn restart(&mut self) -> Option<Self::Item> { | |
| 349 | Self::map_result(self.inner.restart()) | |
| 350 | } | |
| 351 | } |