mod coalesce; mod map; mod multi_product; pubuseself::coalesce::*; pubuseself::map::{map_into, map_ok, MapInto, MapOk}; #[allow(deprecated)] pubuseself::map::MapResults; #[cfg(feature = "use_alloc")] pubuseself::multi_product::*;
use std::fmt; use std::iter::{Fuse, Peekable, FromIterator, FusedIterator}; use std::marker::PhantomData; usecrate::size_hint;
/// An iterator adaptor that alternates elements from two iterators until both /// run out. /// /// This iterator is *fused*. /// /// See [`.interleave()`](crate::Itertools::interleave) for more information. #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Interleave<I, J> {
a: Fuse<I>,
b: Fuse<J>,
flag: bool,
}
/// Create an iterator that interleaves elements in `i` and `j`. /// /// [`IntoIterator`] enabled version of `[Itertools::interleave]`. pubfn interleave<I, J>(i: I, j: J) -> Interleave<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter> where I: IntoIterator,
J: IntoIterator<Item = I::Item>
{
Interleave {
a: i.into_iter().fuse(),
b: j.into_iter().fuse(),
flag: false,
}
}
impl<I, J> FusedIterator for Interleave<I, J> where I: Iterator,
J: Iterator<Item = I::Item>
{}
/// An iterator adaptor that alternates elements from the two iterators until /// one of them runs out. /// /// This iterator is *fused*. /// /// See [`.interleave_shortest()`](crate::Itertools::interleave_shortest) /// for more information. #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct InterleaveShortest<I, J> where I: Iterator,
J: Iterator<Item = I::Item>
{
it0: I,
it1: J,
phase: bool, // false ==> it0, true ==> it1
}
/// Create a new `InterleaveShortest` iterator. pubfn interleave_shortest<I, J>(a: I, b: J) -> InterleaveShortest<I, J> where I: Iterator,
J: Iterator<Item = I::Item>
{
InterleaveShortest {
it0: a,
it1: b,
phase: false,
}
}
impl<I, J> Iterator for InterleaveShortest<I, J> where I: Iterator,
J: Iterator<Item = I::Item>
{ type Item = I::Item;
#[inline] fn next(&mutself) -> Option<Self::Item> { let e = ifself.phase { self.it1.next() } else { self.it0.next() }; if e.is_some() { self.phase = !self.phase;
}
e
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { let (curr_hint, next_hint) = { let it0_hint = self.it0.size_hint(); let it1_hint = self.it1.size_hint(); ifself.phase {
(it1_hint, it0_hint)
} else {
(it0_hint, it1_hint)
}
}; let (curr_lower, curr_upper) = curr_hint; let (next_lower, next_upper) = next_hint; let (combined_lower, combined_upper) =
size_hint::mul_scalar(size_hint::min(curr_hint, next_hint), 2); let lower = if curr_lower > next_lower {
combined_lower + 1
} else {
combined_lower
}; let upper = { let extra_elem = match (curr_upper, next_upper) {
(_, None) => false,
(None, Some(_)) => true,
(Some(curr_max), Some(next_max)) => curr_max > next_max,
}; if extra_elem {
combined_upper.and_then(|x| x.checked_add(1))
} else {
combined_upper
}
};
(lower, upper)
}
}
impl<I, J> FusedIterator for InterleaveShortest<I, J> where I: FusedIterator,
J: FusedIterator<Item = I::Item>
{}
#[derive(Clone, Debug)] /// An iterator adaptor that allows putting back a single /// item to the front of the iterator. /// /// Iterator element type is `I::Item`. pubstruct PutBack<I> where I: Iterator
{
top: Option<I::Item>,
iter: I,
}
/// Create an iterator where you can put back a single item pubfn put_back<I>(iterable: I) -> PutBack<I::IntoIter> where I: IntoIterator
{
PutBack {
top: None,
iter: iterable.into_iter(),
}
}
impl<I> PutBack<I> where I: Iterator
{ /// put back value `value` (builder method) pubfn with_value(mutself, value: I::Item) -> Self { self.put_back(value); self
}
/// Split the `PutBack` into its parts. #[inline] pubfn into_parts(self) -> (Option<I::Item>, I) { let PutBack{top, iter} = self;
(top, iter)
}
/// Put back a single value to the front of the iterator. /// /// If a value is already in the put back slot, it is overwritten. #[inline] pubfn put_back(&mutself, x: I::Item) { self.top = Some(x);
}
}
impl<I> Iterator for PutBack<I> where I: Iterator
{ type Item = I::Item; #[inline] fn next(&mutself) -> Option<Self::Item> { matchself.top {
None => self.iter.next(), refmut some => some.take(),
}
} #[inline] fn size_hint(&self) -> (usize, Option<usize>) { // Not ExactSizeIterator because size may be larger than usize
size_hint::add_scalar(self.iter.size_hint(), self.top.is_some() as usize)
}
#[derive(Debug, Clone)] /// An iterator adaptor that iterates over the cartesian product of /// the element sets of two iterators `I` and `J`. /// /// Iterator element type is `(I::Item, J::Item)`. /// /// See [`.cartesian_product()`](crate::Itertools::cartesian_product) for more information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Product<I, J> where I: Iterator
{
a: I,
a_cur: Option<I::Item>,
b: J,
b_orig: J,
}
/// Create a new cartesian product iterator /// /// Iterator element type is `(I::Item, J::Item)`. pubfn cartesian_product<I, J>(mut i: I, j: J) -> Product<I, J> where I: Iterator,
J: Clone + Iterator,
I::Item: Clone
{
Product {
a_cur: i.next(),
a: i,
b: j.clone(),
b_orig: j,
}
}
impl<I, J> Iterator for Product<I, J> where I: Iterator,
J: Clone + Iterator,
I::Item: Clone
{ type Item = (I::Item, J::Item);
fn size_hint(&self) -> (usize, Option<usize>) { let has_cur = self.a_cur.is_some() as usize; // Not ExactSizeIterator because size may be larger than usize let (b_min, b_max) = self.b.size_hint();
// Compute a * b_orig + b for both lower and upper bound
size_hint::add(
size_hint::mul(self.a.size_hint(), self.b_orig.size_hint()),
(b_min * has_cur, b_max.map(move |x| x * has_cur)))
}
fn fold<Acc, G>(mutself, mut accum: Acc, mut f: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc,
{ // use a split loop to handle the loose a_cur as well as avoiding to // clone b_orig at the end. iflet Some(mut a) = self.a_cur.take() { letmut b = self.b; loop {
accum = b.fold(accum, |acc, elt| f(acc, (a.clone(), elt)));
// we can only continue iterating a if we had a first element; iflet Some(next_a) = self.a.next() {
b = self.b_orig.clone();
a = next_a;
} else { break;
}
}
}
accum
}
}
impl<I, J> FusedIterator for Product<I, J> where I: FusedIterator,
J: Clone + FusedIterator,
I::Item: Clone
{}
/// A “meta iterator adaptor”. Its closure receives a reference to the iterator /// and may pick off as many elements as it likes, to produce the next iterator element. /// /// Iterator element type is *X*, if the return type of `F` is *Option\<X\>*. /// /// See [`.batching()`](crate::Itertools::batching) for more information. #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Batching<I, F> {
f: F,
iter: I,
}
impl<I, F> fmt::Debug for Batching<I, F> where I: fmt::Debug {
debug_fmt_fields!(Batching, iter);
}
/// Create a new Batching iterator. pubfn batching<I, F>(iter: I, f: F) -> Batching<I, F> {
Batching { f, iter }
}
impl<B, F, I> Iterator for Batching<I, F> where I: Iterator,
F: FnMut(&mut I) -> Option<B>
{ type Item = B; #[inline] fn next(&mutself) -> Option<Self::Item> {
(self.f)(&mutself.iter)
}
}
/// An iterator adaptor that steps a number elements in the base iterator /// for each iteration. /// /// The iterator steps by yielding the next element from the base iterator, /// then skipping forward *n-1* elements. /// /// See [`.step()`](crate::Itertools::step) for more information. #[deprecated(note="Use std .step_by() instead", since="0.8.0")] #[allow(deprecated)] #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Step<I> {
iter: Fuse<I>,
skip: usize,
}
/// Create a `Step` iterator. /// /// **Panics** if the step is 0. #[allow(deprecated)] pubfn step<I>(iter: I, step: usize) -> Step<I> where I: Iterator
{
assert!(step != 0);
Step {
iter: iter.fuse(),
skip: step - 1,
}
}
#[allow(deprecated)] impl<I> Iterator for Step<I> where I: Iterator
{ type Item = I::Item; #[inline] fn next(&mutself) -> Option<Self::Item> { let elt = self.iter.next(); ifself.skip > 0 { self.iter.nth(self.skip - 1);
}
elt
}
fn size_hint(&self) -> (usize, Option<usize>) { let (low, high) = self.iter.size_hint(); let div = |x: usize| { if x == 0 { 0
} else { 1 + (x - 1) / (self.skip + 1)
}
};
(div(low), high.map(div))
}
}
// known size #[allow(deprecated)] impl<I> ExactSizeIterator for Step<I> where I: ExactSizeIterator
{}
impl<T: PartialOrd> MergePredicate<T> for MergeLte { fn merge_pred(&mutself, a: &T, b: &T) -> bool {
a <= b
}
}
/// An iterator adaptor that merges the two base iterators in ascending order. /// If both base iterators are sorted (ascending), the result is sorted. /// /// Iterator element type is `I::Item`. /// /// See [`.merge()`](crate::Itertools::merge_by) for more information. pubtype Merge<I, J> = MergeBy<I, J, MergeLte>;
/// Create an iterator that merges elements in `i` and `j`. /// /// [`IntoIterator`] enabled version of [`Itertools::merge`](crate::Itertools::merge). /// /// ``` /// use itertools::merge; /// /// for elt in merge(&[1, 2, 3], &[2, 3, 4]) { /// /* loop body */ /// } /// ``` pubfn merge<I, J>(i: I, j: J) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter> where I: IntoIterator,
J: IntoIterator<Item = I::Item>,
I::Item: PartialOrd
{
merge_by_new(i, j, MergeLte)
}
/// An iterator adaptor that merges the two base iterators in ascending order. /// If both base iterators are sorted (ascending), the result is sorted. /// /// Iterator element type is `I::Item`. /// /// See [`.merge_by()`](crate::Itertools::merge_by) for more information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct MergeBy<I, J, F> where I: Iterator,
J: Iterator<Item = I::Item>
{
a: Peekable<I>,
b: Peekable<J>,
fused: Option<bool>,
cmp: F,
}
impl<I, J, F> fmt::Debug for MergeBy<I, J, F> where I: Iterator + fmt::Debug, J: Iterator<Item = I::Item> + fmt::Debug,
I::Item: fmt::Debug,
{
debug_fmt_fields!(MergeBy, a, b);
}
impl<T, F: FnMut(&T, &T)->bool> MergePredicate<T> for F { fn merge_pred(&mutself, a: &T, b: &T) -> bool { self(a, b)
}
}
fn size_hint(&self) -> (usize, Option<usize>) { // Not ExactSizeIterator because size may be larger than usize
size_hint::add(self.a.size_hint(), self.b.size_hint())
}
}
impl<I, J, F> FusedIterator for MergeBy<I, J, F> where I: FusedIterator,
J: FusedIterator<Item = I::Item>,
F: MergePredicate<I::Item>
{}
/// An iterator adaptor that borrows from a `Clone`-able iterator /// to only pick off elements while the predicate returns `true`. /// /// See [`.take_while_ref()`](crate::Itertools::take_while_ref) for more information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct TakeWhileRef<'a, I: 'a, F> {
iter: &'a mut I,
f: F,
}
impl<'a, I, F> fmt::Debug for TakeWhileRef<'a, I, F> where I: Iterator + fmt::Debug,
{
debug_fmt_fields!(TakeWhileRef, iter);
}
/// Create a new `TakeWhileRef` from a reference to clonable iterator. pubfn take_while_ref<I, F>(iter: &mut I, f: F) -> TakeWhileRef<I, F> where I: Iterator + Clone
{
TakeWhileRef { iter, f }
}
impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F> where I: Iterator + Clone,
F: FnMut(&I::Item) -> bool
{ type Item = I::Item;
/// An iterator adaptor that filters `Option<A>` iterator elements /// and produces `A`. Stops on the first `None` encountered. /// /// See [`.while_some()`](crate::Itertools::while_some) for more information. #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct WhileSome<I> {
iter: I,
}
/// Create a new `WhileSome<I>`. pubfn while_some<I>(iter: I) -> WhileSome<I> {
WhileSome { iter }
}
impl<I, A> Iterator for WhileSome<I> where I: Iterator<Item = Option<A>>
{ type Item = A;
/// An iterator to iterate through all combinations in a `Clone`-able iterator that produces tuples /// of a specific size. /// /// See [`.tuple_combinations()`](crate::Itertools::tuple_combinations) for more /// information. #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct TupleCombinations<I, T> where I: Iterator,
T: HasCombination<I>
{
iter: T::Combination,
_mi: PhantomData<I>,
}
impl<I, A> HasCombination<I> for (A, $(ignore_ident!($X, A)),*) where I: Iterator<Item = A> + Clone,
I::Item: Clone
{ type Combination = $C<Fuse<I>>;
}
)
}
// This snippet generates the twelve `impl_tuple_combination!` invocations: // use core::iter; // use itertools::Itertools; // // for i in 2..=12 { // println!("impl_tuple_combination!(Tuple{arity}Combination Tuple{prev}Combination; {idents});", // arity = i, // prev = i - 1, // idents = ('a'..'z').take(i - 1).join(" "), // ); // } // It could probably be replaced by a bit more macro cleverness.
impl_tuple_combination!(Tuple2Combination Tuple1Combination; a);
impl_tuple_combination!(Tuple3Combination Tuple2Combination; a b);
impl_tuple_combination!(Tuple4Combination Tuple3Combination; a b c);
impl_tuple_combination!(Tuple5Combination Tuple4Combination; a b c d);
impl_tuple_combination!(Tuple6Combination Tuple5Combination; a b c d e);
impl_tuple_combination!(Tuple7Combination Tuple6Combination; a b c d e f);
impl_tuple_combination!(Tuple8Combination Tuple7Combination; a b c d e f g);
impl_tuple_combination!(Tuple9Combination Tuple8Combination; a b c d e f g h);
impl_tuple_combination!(Tuple10Combination Tuple9Combination; a b c d e f g h i);
impl_tuple_combination!(Tuple11Combination Tuple10Combination; a b c d e f g h i j);
impl_tuple_combination!(Tuple12Combination Tuple11Combination; a b c d e f g h i j k);
/// An iterator adapter to filter values within a nested `Result::Ok`. /// /// See [`.filter_ok()`](crate::Itertools::filter_ok) for more information. #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct FilterOk<I, F> {
iter: I,
f: F
}
impl<I, F> fmt::Debug for FilterOk<I, F> where
I: fmt::Debug,
{
debug_fmt_fields!(FilterOk, iter);
}
/// Create a new `FilterOk` iterator. pubfn filter_ok<I, F, T, E>(iter: I, f: F) -> FilterOk<I, F> where I: Iterator<Item = Result<T, E>>,
F: FnMut(&T) -> bool,
{
FilterOk {
iter,
f,
}
}
impl<I, F, T, E> Iterator for FilterOk<I, F> where I: Iterator<Item = Result<T, E>>,
F: FnMut(&T) -> bool,
{ type Item = Result<T, E>;
fn collect<C>(self) -> C where C: FromIterator<Self::Item>
{ letmut f = self.f; self.iter.filter(|v| {
v.as_ref().map(&mut f).unwrap_or(true)
}).collect()
}
}
impl<I, F, T, E> FusedIterator for FilterOk<I, F> where I: FusedIterator<Item = Result<T, E>>,
F: FnMut(&T) -> bool,
{}
/// An iterator adapter to filter and apply a transformation on values within a nested `Result::Ok`. /// /// See [`.filter_map_ok()`](crate::Itertools::filter_map_ok) for more information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct FilterMapOk<I, F> {
iter: I,
f: F
}
impl<I, F> fmt::Debug for FilterMapOk<I, F> where
I: fmt::Debug,
{
debug_fmt_fields!(FilterMapOk, iter);
}
fn collect<C>(self) -> C where C: FromIterator<Self::Item>
{ letmut f = self.f; self.iter.filter_map(|v| {
transpose_result(v.map(&mut f))
}).collect()
}
}
impl<I, F, T, U, E> FusedIterator for FilterMapOk<I, F> where I: FusedIterator<Item = Result<T, E>>,
F: FnMut(T) -> Option<U>,
{}
/// An iterator adapter to get the positions of each element that matches a predicate. /// /// See [`.positions()`](crate::Itertools::positions) for more information. #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Positions<I, F> {
iter: I,
f: F,
count: usize,
}
impl<I, F> fmt::Debug for Positions<I, F> where
I: fmt::Debug,
{
debug_fmt_fields!(Positions, iter, count);
}
/// Create a new `Positions` iterator. pubfn positions<I, F>(iter: I, f: F) -> Positions<I, F> where I: Iterator,
F: FnMut(I::Item) -> bool,
{
Positions {
iter,
f,
count: 0
}
}
impl<I, F> Iterator for Positions<I, F> where I: Iterator,
F: FnMut(I::Item) -> bool,
{ type Item = usize;
fn next(&mutself) -> Option<Self::Item> { whilelet Some(v) = self.iter.next() { let i = self.count; self.count = i + 1; if (self.f)(v) { return Some(i);
}
}
None
}
impl<I, F> FusedIterator for Positions<I, F> where I: FusedIterator,
F: FnMut(I::Item) -> bool,
{}
/// An iterator adapter to apply a mutating function to each element before yielding it. /// /// See [`.update()`](crate::Itertools::update) for more information. #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Update<I, F> {
iter: I,
f: F,
}
impl<I, F> fmt::Debug for Update<I, F> where
I: fmt::Debug,
{
debug_fmt_fields!(Update, iter);
}
/// Create a new `Update` iterator. pubfn update<I, F>(iter: I, f: F) -> Update<I, F> where
I: Iterator,
F: FnMut(&mut I::Item),
{
Update { iter, f }
}
impl<I, F> Iterator for Update<I, F> where
I: Iterator,
F: FnMut(&mut I::Item),
{ type Item = I::Item;
impl<I, F> FusedIterator for Update<I, F> where
I: FusedIterator,
F: FnMut(&mut I::Item),
{}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.32Bemerkung:
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.