[no description]
truly hilarious additions
| -rw-r--r-- | build.rs | 74 | ||||
| -rw-r--r-- | src/implementations.rs | 4 | ||||
| -rw-r--r-- | src/iterator.rs | 204 | ||||
| -rw-r--r-- | src/lib.rs | 43 |
4 files changed, 284 insertions, 41 deletions
@@ -10,15 +10,28 @@ fn main() { File::create(Path::new(&e).join("impl_rv.rs")).unwrap(); let mut impl_pk = File::create(Path::new(&e).join("impl_pk.rs")).unwrap(); + let mut impl_rf = + File::create(Path::new(&e).join("impl_rf.rs")).unwrap(); + let mut impl_mp = + File::create(Path::new(&e).join("impl_mp.rs")).unwrap(); + for n in 0..26 { let z = ('A'..='Z').take(n).collect::<Vec<_>>().into_iter(); - generate(z, &mut impl_td, &mut impl_rv, &mut impl_pk); + generate( + z, + &mut impl_td, + &mut impl_rv, + &mut impl_pk, + &mut impl_rf, + &mut impl_mp, + ); } } -fn tup(x: impl Iterator<Item = char>) -> String { +fn tup<D: std::fmt::Display>(x: impl Iterator<Item = D>) -> String { let mut s = String::default(); for lem in x { - s.push(lem); + use std::fmt::Write; + write!(&mut s, "{lem}").unwrap(); s.push(','); } @@ -32,6 +45,8 @@ fn generate( impl_td: &mut impl Write, impl_rv: &mut impl Write, impl_pk: &mut impl Write, + impl_rf: &mut impl Write, + impl_mp: &mut impl Write, ) { let tupl = tup(x.clone()); let n = x.clone().count(); @@ -108,12 +123,61 @@ fn generate( type Reversed = ({rev}); fn reverse(self) -> Self::Reversed {{ - let ({x}) = self; + let ({tupl}) = self; ({rev}) }} }} ", - x = tup(x.clone()), + ) + .unwrap(); + write!( + impl_rf, + " + impl<{tupl}> RefIze for ({tupl}) {{ + type AsRef<'a> = ({rtup}) where + ({tupl}): 'a + ; + type AsMut<'a> = ({mtup}) where + ({tupl}): 'a + ; + fn as_ref(&self) -> Self::AsRef<'_> {{ + let ({tupl}) = self; + ({tupl}) + }} + fn as_mut(&mut self) -> Self::AsMut<'_> {{ + let ({tupl}) = self; + ({tupl}) + }} + }} + ", + rtup = tup(x.clone().map(|x| format!("&'a {x}"))), + mtup = tup(x.clone().map(|x| format!("&'a mut {x}"))), + ) + .unwrap(); + write!( + impl_mp, + // type Fns = ({fns_}); + // type Mapped = ({lowr}); + " + impl<{tupl} {ret} {fns}> MapAll<({ret}), ({fns_})> for ({tupl}) \ + {{ + fn map_all(self, ({ret}): ({fns_})) -> ({ret}) {{ + let ({tupl}) = self; + ({mapped}) + }} + }} + impl<{tupl} {ret} {fns2}> MapAllMut<({ret}), ({fns_})> for \ + ({tupl}) {{ + fn map_all_mut(self, x: &mut ({fns_})) -> ({ret}) {{ + MapAll::map_all(self, x.as_mut()) + }} + }} + ", + ret = tup(x.clone().map(|x| format!("R{x}"))), + fns_ = tup(x.clone().map(|x| format!("F{x}"))), + fns = tup(x.clone().map(|x| format!("F{x}:FnOnce({x}) -> R{x}",))), + fns2 = tup(x.clone().map(|x| format!("F{x}:FnMut({x}) -> R{x}",))), + mapped = tup(x.clone().map(|x| format!("R{}({x})", x))) ) .unwrap(); } diff --git a/src/implementations.rs b/src/implementations.rs index 2f2eb54..a2ae4fe 100644 --- a/src/implementations.rs +++ b/src/implementations.rs @@ -1,8 +1,10 @@ -#![allow(non_snake_case)] +#![allow(nonstandard_style)] use super::*; include!(concat!(env!("OUT_DIR"), "/impl_td.rs")); include!(concat!(env!("OUT_DIR"), "/impl_rv.rs")); include!(concat!(env!("OUT_DIR"), "/impl_pk.rs")); +include!(concat!(env!("OUT_DIR"), "/impl_rf.rs")); +include!(concat!(env!("OUT_DIR"), "/impl_mp.rs")); macro_rules! generate {( $($Hd:tt $($T:tt)*)? diff --git a/src/iterator.rs b/src/iterator.rs index 3d3dd26..c32c516 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -1,64 +1,202 @@ -use crate::{Pick, RePick, Tupl}; -/// may add more later -pub trait IteratorOfTuples: Iterator<Item: Tupl> { +#![allow(nonstandard_style)] +use crate::{MapAllMut, Pick, RePick, RefIze, Tupl}; +pub trait IteratorOfTuplesWithF<retval>: + Iterator<Item: Tupl> + Sized +{ /// Map the item at: (|(x, y)| (f(x), y)) - fn map_at<const N: usize, U>( + fn map_at<const N: usize>( self, - f: impl FnMut(<Self::Item as Pick<N>>::At) -> U, - ) -> impl Iterator<Item = <Self::Item as RePick<N, U>>::New> + mut f: impl FnMut(<Self::Item as Pick<N>>::At) -> retval, + ) -> core::iter::Map< + Self, + impl FnMut(<Self>::Item) -> <<Self>::Item as RePick<N, retval>>::New, + > where - Self::Item: RePick<N, U>; - /// make it just one: (|x| x.0) - fn just<const N: usize>( + Self::Item: RePick<N, retval>, + { + self.map(move |x| { + let (l, at, r) = x.depict(); + let at = f(at); + Self::Item::unpick(l, at, r) + }) + } + /// filter map the item at: (|(x, y)| f(x).zip(Some(y)) + fn filter_map_at<const N: usize>( self, - ) -> impl Iterator<Item = <Self::Item as Pick<N>>::At> + mut f: impl FnMut(<Self::Item as Pick<N>>::At) -> Option<retval>, + ) -> core::iter::FilterMap< + Self, + impl FnMut( + <Self as Iterator>::Item, + ) -> Option< + <<Self as Iterator>::Item as RePick<N, retval>>::New, + >, + > where - Self::Item: Pick<N>; + Self::Item: RePick<N, retval>, + { + self.filter_map(move |x| { + let (l, at, r) = x.depict(); + f(at).map(|x| Self::Item::unpick(l, x, r)) + }) + } /// map the item to just one, then map that one: (|x| f(x.0)) - fn map_just<const N: usize, U>( + fn map_on<const N: usize>( self, - f: impl FnMut(<Self::Item as Pick<N>>::At) -> U, + f: impl FnMut(<Self::Item as Pick<N>>::At) -> retval, ) -> core::iter::Map< impl Iterator<Item = <Self::Item as Pick<N>>::At>, - impl FnMut(<Self::Item as Pick<N>>::At) -> U, + impl FnMut(<Self::Item as Pick<N>>::At) -> retval, > where Self: Iterator<Item: Pick<N>> + Sized, { - self.just().map(f) + self.on().map(f) + } + fn fmap_on<const N: usize>( + self, + f: impl FnMut(<Self::Item as Pick<N>>::At) -> retval, + ) -> core::iter::FlatMap< + core::iter::Map< + Self, + impl FnMut( + <Self as Iterator>::Item, + ) + -> <<Self as Iterator>::Item as Pick<N>>::At, + >, + retval, + impl FnMut(<<Self as Iterator>::Item as Pick<N>>::At) -> retval, + > + where + Self::Item: Pick<N>, + retval: IntoIterator, + { + self.on().flat_map(f) } } -impl<I: Iterator<Item: Tupl>> IteratorOfTuples for I { - #[expect(refining_impl_trait)] - fn map_at<const N: usize, U>( +pub trait IteratorOfReferencesToTupleWithF< + 'a, + T: Tupl + RefIze + 'a, + retval, +>: Iterator<Item = &'a T> + Sized +{ + /// Map the item at: (|(x, y)| (f(x), y)) + fn map_at<const N: usize>( self, - mut f: impl FnMut(<Self::Item as Pick<N>>::At) -> U, + f: impl FnMut(<T::AsRef<'a> as Pick<N>>::At) -> retval + 'a, + ) -> impl Iterator<Item = <T::AsRef<'a> as RePick<N, retval>>::New> + where + T::AsRef<'a>: RePick<N, retval>, + { + self.as_ref().map_at(f) + } + /// map the item to just one, then map that one: (|x| f(x.0)) + fn map_on<const N: usize, U>( + self, + f: impl FnMut(<T::AsRef<'a> as Pick<N>>::At) -> U, ) -> core::iter::Map< - I, - impl FnMut( - <I as Iterator>::Item, - ) -> <<I as Iterator>::Item as RePick<N, U>>::New, + impl Iterator<Item = <T::AsRef<'a> as Pick<N>>::At>, + impl FnMut(<T::AsRef<'a> as Pick<N>>::At) -> U, > where - Self::Item: RePick<N, U>, + T::AsRef<'a>: Pick<N>, { - self.map(move |x| { - let (l, at, r) = x.depict(); - let at = f(at); - Self::Item::unpick(l, at, r) - }) + self.on().map(f) } +} - #[expect(refining_impl_trait)] - fn just<const N: usize>( +/// may add more later +pub trait IteratorOfTuples: Iterator<Item: Tupl> + Sized { + /// make it just one: (|x| x.0) + fn on<const N: usize>( self, ) -> core::iter::Map< - I, - impl FnMut(<I>::Item) -> <<I>::Item as Pick<N>>::At, + Self, + impl FnMut( + <Self as Iterator>::Item, + ) -> <<Self as Iterator>::Item as Pick<N>>::At, > where Self::Item: Pick<N>, { self.map(|x| x.pick()) } + fn flatten_on<const N: usize>( + self, + ) -> core::iter::Flatten< + core::iter::Map< + Self, + impl FnMut( + <Self as Iterator>::Item, + ) + -> <<Self as Iterator>::Item as Pick<N>>::At, + >, + > + where + Self::Item: Pick<N, At: IntoIterator>, + { + self.on().flatten() + } + fn map_all<retval: Tupl, functions: Tupl>( + self, + mut fns: functions, + ) -> impl Iterator<Item = retval> + where + Self::Item: MapAllMut<retval, functions>, + { + self.map(move |x| x.map_all_mut(&mut fns)) + } +} + +/// may add more later +pub trait IteratorOfReferencesToTuple<'a, T: Tupl + RefIze + 'a>: + Iterator<Item = &'a T> + Sized +{ + fn as_ref( + self, + ) -> core::iter::Map<Self, fn(&T) -> <T as RefIze>::AsRef<'_>> { + self.map(T::as_ref) + } + + /// make it just one: (|x| x.0) + fn on<const N: usize>( + self, + ) -> impl Iterator<Item = <T::AsRef<'a> as Pick<N>>::At> + where + T::AsRef<'a>: Pick<N>, + { + self.as_ref().on() + } + fn map_all<retval: Tupl, functions: Tupl>( + self, + mut fns: functions, + ) -> impl Iterator<Item = retval> + where + T::AsRef<'a>: MapAllMut<retval, functions>, + { + self.map(move |x| x.as_ref().map_all_mut(&mut fns)) + } +} + +impl<I: Iterator<Item: Tupl>> IteratorOfTuples for I {} + +impl<U, I: Iterator<Item: Tupl>> IteratorOfTuplesWithF<U> for I {} + +impl<'a, T: Tupl + RefIze + 'a, I: Iterator<Item = &'a T>> + IteratorOfReferencesToTuple<'a, T> for I +{ +} + +impl<'a, U, T: Tupl + RefIze + 'a, I: Iterator<Item = &'a T>> + IteratorOfReferencesToTupleWithF<'a, T, U> for I +{ +} +#[test] +fn x() { + let x = [(1, 2), (3, 4)].iter().map_at::<0>(|x| x + 2); + let y = [(1, "a"), (2, "b")] + .iter() + .map_all((|x| x + 1, |x| x.to_uppercase())) + .next_chunk::<2>() + .unwrap(); } @@ -1,4 +1,9 @@ -#![feature(tuple_trait, import_trait_associated_functions, never_type)] +#![feature( + tuple_trait, + import_trait_associated_functions, + never_type, + iter_next_chunk +)] #![no_std] #![allow(mixed_script_confusables, confusable_idents)] //!  @@ -7,7 +12,10 @@ mod implementations; mod iterator; mod picks; -pub use iterator::IteratorOfTuples; +pub use iterator::{ + IteratorOfReferencesToTuple, IteratorOfReferencesToTupleWithF, + IteratorOfTuples, IteratorOfTuplesWithF, +}; /// Reverse a tuple. pub trait Reverse: Tupl { type Reversed: Tupl; @@ -89,10 +97,31 @@ pub trait Pick<const N: usize>: Tupl { fn depict(self) -> (Self::L, Self::At, Self::R); } +pub trait RefIze { + type AsRef<'a> + where + Self: 'a; + type AsMut<'a> + where + Self: 'a; + fn as_ref(&self) -> Self::AsRef<'_>; + fn as_mut(&mut self) -> Self::AsMut<'_>; +} + pub trait RePick<const N: usize, T>: Pick<N> + Sized { type New: Tupl; fn unpick(l: Self::L, at: T, r: Self::R) -> Self::New; } + +/// trait for mapping all elements of a tuple +pub trait MapAll<R: Tupl, Fns: Tupl>: Sized { + fn map_all(self, functions: Fns) -> R; +} +/// trait for mapping all elements of a tuple (FnMut edition). +pub trait MapAllMut<R: Tupl, Fns: Tupl> { + fn map_all_mut(self, functions: &mut Fns) -> R; +} + /// Main tuple trait. #[diagnostic::on_unimplemented( label = "this is not a tuple, or it is too big a tuple (>26 elements)" @@ -187,4 +216,14 @@ fn t() { .push(4) .push(0u8) .pick::<3>(); + + assert_eq!( + (1, 2u8, 3u16, "4").map_all(( + |_| {}, + |x| x + 1, + |x| x / 3, + |x| x.parse::<u32>().unwrap(), + )), + ((), 3, 1, 4) + ); } |