Skip to content

Commit

Permalink
Merge branch 'master' into comm
Browse files Browse the repository at this point in the history
  • Loading branch information
phimuemue authored Sep 18, 2024
2 parents 84ce7cc + 91f9618 commit 0326b4b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 39 deletions.
45 changes: 13 additions & 32 deletions src/cons_tuples_impl.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,39 @@
use crate::adaptors::map::{MapSpecialCase, MapSpecialCaseFn};

macro_rules! impl_cons_iter(
($_A:ident, $_B:ident, ) => (); // stop

($A:ident, $($B:ident,)*) => (
impl_cons_iter!($($B,)*);
#[allow(non_snake_case)]
impl<X, Iter, $($B),*> Iterator for ConsTuples<Iter, (($($B,)*), X)>
where Iter: Iterator<Item = (($($B,)*), X)>,
{
type Item = ($($B,)* X, );
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, ))
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn fold<Acc, Fold>(self, accum: Acc, mut f: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(accum, move |acc, (($($B,)*), x)| f(acc, ($($B,)* x, )))
impl<$($B),*, X> MapSpecialCaseFn<(($($B,)*), X)> for ConsTuplesFn {
type Out = ($($B,)* X, );
fn call(&mut self, (($($B,)*), X): (($($B,)*), X)) -> Self::Out {
($($B,)* X, )
}
}
);
);

impl_cons_iter!(A, B, C, D, E, F, G, H, I, J, K, L,);

#[derive(Debug, Clone)]
pub struct ConsTuplesFn;

/// An iterator that maps an iterator of tuples like
/// `((A, B), C)` to an iterator of `(A, B, C)`.
///
/// Used by the `iproduct!()` macro.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
#[derive(Debug)]
pub struct ConsTuples<I, J>
where
I: Iterator<Item = J>,
{
iter: I,
}

impl<I, J> Clone for ConsTuples<I, J>
where
I: Clone + Iterator<Item = J>,
{
clone_fields!(iter);
}
pub type ConsTuples<I> = MapSpecialCase<I, ConsTuplesFn>;

/// Create an iterator that maps for example iterators of
/// `((A, B), C)` to `(A, B, C)`.
pub fn cons_tuples<I, J>(iterable: I) -> ConsTuples<I::IntoIter, J>
pub fn cons_tuples<I>(iterable: I) -> ConsTuples<I::IntoIter>
where
I: IntoIterator<Item = J>,
I: IntoIterator,
{
ConsTuples {
iter: iterable.into_iter(),
f: ConsTuplesFn,
}
}
2 changes: 1 addition & 1 deletion src/diff.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! "Diff"ing iterators for caching elements to sequential collections without requiring the new
//! elements' iterator to be `Clone`.
//!
//! - [`Diff`] (produced by the [`diff_with`] function)
//! [`Diff`] (produced by the [`diff_with`] function)
//! describes the difference between two non-`Clone` iterators `I` and `J` after breaking ASAP from
//! a lock-step comparison.

Expand Down
31 changes: 25 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,13 +427,13 @@ macro_rules! chain {
/// This trait defines a number of methods. They are divided into two groups:
///
/// * *Adaptors* take an iterator and parameter as input, and return
/// a new iterator value. These are listed first in the trait. An example
/// of an adaptor is [`.interleave()`](Itertools::interleave)
/// a new iterator value. These are listed first in the trait. An example
/// of an adaptor is [`.interleave()`](Itertools::interleave)
///
/// * *Regular methods* are those that don't return iterators and instead
/// return a regular value of some other kind.
/// [`.next_tuple()`](Itertools::next_tuple) is an example and the first regular
/// method in the list.
/// return a regular value of some other kind.
/// [`.next_tuple()`](Itertools::next_tuple) is an example and the first regular
/// method in the list.
pub trait Itertools: Iterator {
// adaptors

Expand Down Expand Up @@ -1597,6 +1597,7 @@ pub trait Itertools: Iterator {
/// .collect();
/// let expected: Vec<_> = vec![1, 2, 3].into_iter().map(NoCloneImpl).collect();
/// assert_eq!(filtered, expected);
#[doc(alias = "take_until")]
fn take_while_inclusive<F>(self, accept: F) -> TakeWhileInclusive<Self, F>
where
Self: Sized,
Expand Down Expand Up @@ -2001,6 +2002,15 @@ pub trait Itertools: Iterator {
/// assert_eq!(numbers.iter().find_or_last(|&&x| x > 5), Some(&4));
/// assert_eq!(numbers.iter().find_or_last(|&&x| x > 2), Some(&3));
/// assert_eq!(std::iter::empty::<i32>().find_or_last(|&x| x > 5), None);
///
/// // An iterator of Results can return the first Ok or the last Err:
/// let input = vec![Err(()), Ok(11), Err(()), Ok(22)];
/// assert_eq!(input.into_iter().find_or_last(Result::is_ok), Some(Ok(11)));
///
/// let input: Vec<Result<(), i32>> = vec![Err(11), Err(22)];
/// assert_eq!(input.into_iter().find_or_last(Result::is_ok), Some(Err(22)));
///
/// assert_eq!(std::iter::empty::<Result<(), i32>>().find_or_last(Result::is_ok), None);
/// ```
fn find_or_last<P>(mut self, mut predicate: P) -> Option<Self::Item>
where
Expand Down Expand Up @@ -2029,6 +2039,15 @@ pub trait Itertools: Iterator {
/// assert_eq!(numbers.iter().find_or_first(|&&x| x > 5), Some(&1));
/// assert_eq!(numbers.iter().find_or_first(|&&x| x > 2), Some(&3));
/// assert_eq!(std::iter::empty::<i32>().find_or_first(|&x| x > 5), None);
///
/// // An iterator of Results can return the first Ok or the first Err:
/// let input = vec![Err(()), Ok(11), Err(()), Ok(22)];
/// assert_eq!(input.into_iter().find_or_first(Result::is_ok), Some(Ok(11)));
///
/// let input: Vec<Result<(), i32>> = vec![Err(11), Err(22)];
/// assert_eq!(input.into_iter().find_or_first(Result::is_ok), Some(Err(11)));
///
/// assert_eq!(std::iter::empty::<Result<(), i32>>().find_or_first(Result::is_ok), None);
/// ```
fn find_or_first<P>(mut self, mut predicate: P) -> Option<Self::Item>
where
Expand Down Expand Up @@ -2071,7 +2090,7 @@ pub trait Itertools: Iterator {
where
Self: Sized,
Self::Item: Borrow<Q>,
Q: PartialEq,
Q: PartialEq + ?Sized,
{
self.any(|x| x.borrow() == query)
}
Expand Down

0 comments on commit 0326b4b

Please sign in to comment.