# HG changeset patch # User Tuomo Valkonen # Date 1666466884 -10800 # Node ID ac84e995e119eb4c6f34eba3bdeb55088f7d946b # Parent df3901ec2f5d2bee96ef263be39adfb0b4c9df53 Convert iteration utilities to GATs diff -r df3901ec2f5d -r ac84e995e119 src/maputil.rs --- a/src/maputil.rs Sat Oct 22 18:12:49 2022 +0300 +++ b/src/maputil.rs Sat Oct 22 22:28:04 2022 +0300 @@ -101,7 +101,7 @@ macro_rules! make_mapmany_mut{ ($name:ident, $name_indexed:ident, $var0:ident $($var:ident)* ; $etype0:ident $($etype:ident)*, $ctype0:ident $($ctype:ident)*) => { - /// Map over multiple [`FixedLength`] container inserting the result in the first. + /// Map over [`FixedLength`] container(s) with mutable references to the first container. #[inline] pub fn $name< $etype0, @@ -118,8 +118,8 @@ zipit.for_each(|tuple_or_singleton!($var0, $($var),*)| f($var0, $($var),*)); } - /// Map over multiple [`FixedLength`] container inserting the result in the first. - /// This version also passes the index to the mapping function. + /// Map over [`FixedLength`] container(s) and element indices + /// with mutable references to the first container. #[inline] pub fn $name_indexed< $etype0, @@ -161,6 +161,7 @@ // } +/// Iterator returned by [`foldmap`][FoldMappable::foldmap] applied to an iterator. pub struct FoldMap, A, B, J : Copy, F : Fn(J, A) -> (J, B)> { iter : I, f : F, @@ -179,6 +180,7 @@ } } +/// Iterator returned by [`indexmap`][IndexMappable::indexmap] applied to an iterator. pub struct IndexMap, A, B, F : Fn(usize, A) -> B> { iter : I, f : F, @@ -197,50 +199,63 @@ } } -pub trait FoldMappable (J, B)> : Sized { - type Output; - /// Fold and map over an array; typically used to count the element while traversing a map - fn foldmap(self, j : J, f : F) -> Self::Output; +/// Trait for things that can be foldmapped. +/// +/// `A` is the type of elements of `Self`, and `J` the accumulator type for the folding. +pub trait FoldMappable : Sized { + type Output where F : Fn(J, A) -> (J, B); + /// Fold and map over `self` with `f`. `j` is the initial accumulator for folding. + /// + /// The output type depends on the implementation, but will generally have elements of + /// type `B`. + fn foldmap (J, B)>(self, j : J, f : F) -> Self::Output; } -pub trait IndexMappable B> : Sized { - type Output; - fn indexmap(self, f : F) -> Self::Output; +/// Trait for things that can be indexmapped. +/// +/// `A` is the type of elements of `Self`. +pub trait IndexMappable : Sized { + type Output where F : Fn(usize, A) -> B; + /// Map over element indices and elements of `self`. + /// + /// The output type depends on the implementation, but will generally have elements of + /// type `B`. + fn indexmap B>(self, f : F) -> Self::Output; } -impl<'a, A, B, J : Copy, F : Fn(J, &'a A) -> (J, B)> FoldMappable<&'a A, B, J, F> +impl<'a, A, J : Copy> FoldMappable<&'a A, J> for std::slice::Iter<'a, A> { - type Output = FoldMap; + type Output = FoldMap where F : Fn(J, &'a A) -> (J, B); #[inline] - fn foldmap(self, j : J, f : F) -> Self::Output { + fn foldmap (J, B)>(self, j : J, f : F) -> Self::Output { FoldMap { iter : self, j, f } } } -impl<'a, A, B, F : Fn(usize, &'a A) -> B> IndexMappable<&'a A, B, F> +impl<'a, A> IndexMappable<&'a A> for std::slice::Iter<'a, A> { - type Output = IndexMap; + type Output = IndexMap where F : Fn(usize, &'a A) -> B; #[inline] - fn indexmap(self, f : F) -> Self::Output { + fn indexmap B>(self, f : F) -> Self::Output { IndexMap { iter : self, j : 0, f } } } -impl (J, B), const N : usize> FoldMappable +impl FoldMappable for std::array::IntoIter { - type Output = FoldMap; + type Output = FoldMap where F : Fn(J, A) -> (J, B); #[inline] - fn foldmap(self, j : J, f : F) -> Self::Output { + fn foldmap (J, B)>(self, j : J, f : F) -> Self::Output { FoldMap { iter : self, j, f } } } -impl<'a, A, B, F : Fn(usize, A) -> B, const N : usize> IndexMappable +impl<'a, A, const N : usize> IndexMappable for std::array::IntoIter { - type Output = IndexMap; + type Output = IndexMap where F : Fn(usize, A) -> B; #[inline] - fn indexmap(self, f : F) -> Self::Output { + fn indexmap B>(self, f : F) -> Self::Output { IndexMap { iter : self, j : 0, f } } } @@ -248,10 +263,10 @@ -impl (J, B), const N : usize> FoldMappable for [A; N] { - type Output = [B; N]; +impl FoldMappable for [A; N] { + type Output = [B; N] where F : Fn(J, A) -> (J, B); #[inline] - fn foldmap(self, j : J, f : F) -> [B; N] { + fn foldmap (J, B)>(self, j : J, f : F) -> [B; N] { // //let mut res : [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; // let mut res = MaybeUninit::uninit_array::(); // for (a, i) in self.into_iter().zip(0..N) { @@ -266,10 +281,10 @@ } } -impl B, const N : usize> IndexMappable for [A; N] { - type Output= [B; N]; +impl IndexMappable for [A; N] { + type Output = [B; N] where F : Fn(usize, A) -> B; #[inline] - fn indexmap(self, f : F) -> [B; N] { + fn indexmap B>(self, f : F) -> [B; N] { // //let mut res : [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; // let mut res = MaybeUninit::uninit_array::(); // for (a, i) in self.into_iter().zip(0..N) {