summaryrefslogtreecommitdiffstats
path: root/vendor/itertools/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/itertools/src/lib.rs')
-rw-r--r--vendor/itertools/src/lib.rs902
1 files changed, 519 insertions, 383 deletions
diff --git a/vendor/itertools/src/lib.rs b/vendor/itertools/src/lib.rs
index c23a65db5..11b624d48 100644
--- a/vendor/itertools/src/lib.rs
+++ b/vendor/itertools/src/lib.rs
@@ -1,5 +1,5 @@
#![warn(missing_docs)]
-#![crate_name="itertools"]
+#![crate_name = "itertools"]
#![cfg_attr(not(feature = "use_std"), no_std)]
//! Extra iterator adaptors, functions and macros.
@@ -42,8 +42,8 @@
//!
//! ## Rust Version
//!
-//! This version of itertools requires Rust 1.32 or later.
-#![doc(html_root_url="https://docs.rs/itertools/0.8/")]
+//! This version of itertools requires Rust 1.43.1 or later.
+#![doc(html_root_url = "https://docs.rs/itertools/0.11/")]
#[cfg(not(feature = "use_std"))]
extern crate core as std;
@@ -52,28 +52,24 @@ extern crate core as std;
extern crate alloc;
#[cfg(feature = "use_alloc")]
-use alloc::{
- string::String,
- vec::Vec,
-};
+use alloc::{string::String, vec::Vec};
pub use either::Either;
use core::borrow::Borrow;
+use std::cmp::Ordering;
#[cfg(feature = "use_std")]
use std::collections::HashMap;
-use std::iter::{IntoIterator, once};
-use std::cmp::Ordering;
-use std::fmt;
#[cfg(feature = "use_std")]
use std::collections::HashSet;
-#[cfg(feature = "use_std")]
-use std::hash::Hash;
+use std::fmt;
#[cfg(feature = "use_alloc")]
use std::fmt::Write;
+#[cfg(feature = "use_std")]
+use std::hash::Hash;
+use std::iter::{once, IntoIterator};
#[cfg(feature = "use_alloc")]
type VecIntoIter<T> = alloc::vec::IntoIter<T>;
-#[cfg(feature = "use_alloc")]
use std::iter::FromIterator;
#[macro_use]
@@ -85,73 +81,55 @@ pub use std::iter as __std_iter;
/// The concrete iterator types.
pub mod structs {
+ #[cfg(feature = "use_alloc")]
+ pub use crate::adaptors::MultiProduct;
pub use crate::adaptors::{
- Dedup,
- DedupBy,
- DedupWithCount,
- DedupByWithCount,
- Interleave,
- InterleaveShortest,
- FilterMapOk,
- FilterOk,
- Product,
- PutBack,
- Batching,
- MapInto,
- MapOk,
- Merge,
- MergeBy,
- TakeWhileRef,
- WhileSome,
- Coalesce,
- TupleCombinations,
- Positions,
- Update,
+ Batching, Coalesce, Dedup, DedupBy, DedupByWithCount, DedupWithCount, FilterMapOk,
+ FilterOk, Interleave, InterleaveShortest, MapInto, MapOk, Positions, Product, PutBack,
+ TakeWhileRef, TupleCombinations, Update, WhileSome,
};
#[allow(deprecated)]
pub use crate::adaptors::{MapResults, Step};
#[cfg(feature = "use_alloc")]
- pub use crate::adaptors::MultiProduct;
- #[cfg(feature = "use_alloc")]
pub use crate::combinations::Combinations;
#[cfg(feature = "use_alloc")]
pub use crate::combinations_with_replacement::CombinationsWithReplacement;
pub use crate::cons_tuples_impl::ConsTuples;
+ #[cfg(feature = "use_std")]
+ pub use crate::duplicates_impl::{Duplicates, DuplicatesBy};
pub use crate::exactly_one_err::ExactlyOneError;
- pub use crate::format::{Format, FormatWith};
pub use crate::flatten_ok::FlattenOk;
+ pub use crate::format::{Format, FormatWith};
+ #[cfg(feature = "use_alloc")]
+ pub use crate::groupbylazy::{Chunk, Chunks, Group, GroupBy, Groups, IntoChunks};
#[cfg(feature = "use_std")]
pub use crate::grouping_map::{GroupingMap, GroupingMapBy};
- #[cfg(feature = "use_alloc")]
- pub use crate::groupbylazy::{IntoChunks, Chunk, Chunks, GroupBy, Group, Groups};
pub use crate::intersperse::{Intersperse, IntersperseWith};
#[cfg(feature = "use_alloc")]
pub use crate::kmerge_impl::{KMerge, KMergeBy};
- pub use crate::merge_join::MergeJoinBy;
+ pub use crate::merge_join::{Merge, MergeBy, MergeJoinBy};
#[cfg(feature = "use_alloc")]
pub use crate::multipeek_impl::MultiPeek;
+ pub use crate::pad_tail::PadUsing;
#[cfg(feature = "use_alloc")]
pub use crate::peek_nth::PeekNth;
- pub use crate::pad_tail::PadUsing;
pub use crate::peeking_take_while::PeekingTakeWhile;
#[cfg(feature = "use_alloc")]
pub use crate::permutations::Permutations;
- pub use crate::process_results_impl::ProcessResults;
#[cfg(feature = "use_alloc")]
pub use crate::powerset::Powerset;
+ pub use crate::process_results_impl::ProcessResults;
#[cfg(feature = "use_alloc")]
pub use crate::put_back_n_impl::PutBackN;
#[cfg(feature = "use_alloc")]
pub use crate::rciter_impl::RcIter;
pub use crate::repeatn::RepeatN;
#[allow(deprecated)]
- pub use crate::sources::{RepeatCall, Unfold, Iterate};
+ pub use crate::sources::{Iterate, RepeatCall, Unfold};
pub use crate::take_while_inclusive::TakeWhileInclusive;
#[cfg(feature = "use_alloc")]
pub use crate::tee::Tee;
- pub use crate::tuple_impl::{TupleBuffer, TupleWindows, CircularTupleWindows, Tuples};
- #[cfg(feature = "use_std")]
- pub use crate::duplicates_impl::{Duplicates, DuplicatesBy};
+ pub use crate::tuple_impl::{CircularTupleWindows, TupleBuffer, TupleWindows, Tuples};
#[cfg(feature = "use_std")]
pub use crate::unique_impl::{Unique, UniqueBy};
pub use crate::with_position::WithPosition;
@@ -165,22 +143,22 @@ pub mod traits {
pub use crate::tuple_impl::HomogeneousTuple;
}
-#[allow(deprecated)]
-pub use crate::structs::*;
pub use crate::concat_impl::concat;
pub use crate::cons_tuples_impl::cons_tuples;
pub use crate::diff::diff_with;
pub use crate::diff::Diff;
#[cfg(feature = "use_alloc")]
-pub use crate::kmerge_impl::{kmerge_by};
+pub use crate::kmerge_impl::kmerge_by;
pub use crate::minmax::MinMaxResult;
pub use crate::peeking_take_while::PeekingNext;
pub use crate::process_results_impl::process_results;
pub use crate::repeatn::repeat_n;
#[allow(deprecated)]
-pub use crate::sources::{repeat_call, unfold, iterate};
-pub use crate::with_position::Position;
+pub use crate::sources::{iterate, repeat_call, unfold};
+#[allow(deprecated)]
+pub use crate::structs::*;
pub use crate::unziptuple::{multiunzip, MultiUnzip};
+pub use crate::with_position::Position;
pub use crate::ziptuple::multizip;
mod adaptors;
mod either_or_both;
@@ -189,24 +167,26 @@ pub use crate::either_or_both::EitherOrBoth;
pub mod free;
#[doc(inline)]
pub use crate::free::*;
-mod concat_impl;
-mod cons_tuples_impl;
#[cfg(feature = "use_alloc")]
mod combinations;
#[cfg(feature = "use_alloc")]
mod combinations_with_replacement;
-mod exactly_one_err;
+mod concat_impl;
+mod cons_tuples_impl;
mod diff;
-mod flatten_ok;
#[cfg(feature = "use_std")]
+mod duplicates_impl;
+mod exactly_one_err;
+#[cfg(feature = "use_alloc")]
mod extrema_set;
+mod flatten_ok;
mod format;
-#[cfg(feature = "use_std")]
-mod grouping_map;
#[cfg(feature = "use_alloc")]
mod group_map;
#[cfg(feature = "use_alloc")]
mod groupbylazy;
+#[cfg(feature = "use_std")]
+mod grouping_map;
mod intersperse;
#[cfg(feature = "use_alloc")]
mod k_smallest;
@@ -239,8 +219,6 @@ mod take_while_inclusive;
mod tee;
mod tuple_impl;
#[cfg(feature = "use_std")]
-mod duplicates_impl;
-#[cfg(feature = "use_std")]
mod unique_impl;
mod unziptuple;
mod with_position;
@@ -430,7 +408,7 @@ macro_rules! chain {
/// 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 {
+pub trait Itertools: Iterator {
// adaptors
/// Alternate elements from two iterators until both have run out.
@@ -446,8 +424,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
/// ```
fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>
- where J: IntoIterator<Item = Self::Item>,
- Self: Sized
+ where
+ J: IntoIterator<Item = Self::Item>,
+ Self: Sized,
{
interleave(self, other)
}
@@ -464,8 +443,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![1, -1, 2, -2, 3]);
/// ```
fn interleave_shortest<J>(self, other: J) -> InterleaveShortest<Self, J::IntoIter>
- where J: IntoIterator<Item = Self::Item>,
- Self: Sized
+ where
+ J: IntoIterator<Item = Self::Item>,
+ Self: Sized,
{
adaptors::interleave_shortest(self, other.into_iter())
}
@@ -483,8 +463,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal((0..3).intersperse(8), vec![0, 8, 1, 8, 2]);
/// ```
fn intersperse(self, element: Self::Item) -> Intersperse<Self>
- where Self: Sized,
- Self::Item: Clone
+ where
+ Self: Sized,
+ Self::Item: Clone,
{
intersperse::intersperse(self, element)
}
@@ -504,8 +485,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(i, 8);
/// ```
fn intersperse_with<F>(self, element: F) -> IntersperseWith<Self, F>
- where Self: Sized,
- F: FnMut() -> Self::Item
+ where
+ Self: Sized,
+ F: FnMut() -> Self::Item,
{
intersperse::intersperse_with(self, element)
}
@@ -538,8 +520,9 @@ pub trait Itertools : Iterator {
/// ```
#[inline]
fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>
- where J: IntoIterator,
- Self: Sized
+ where
+ J: IntoIterator,
+ Self: Sized,
{
zip_longest::zip_longest(self, other.into_iter())
}
@@ -551,8 +534,9 @@ pub trait Itertools : Iterator {
/// lengths.
#[inline]
fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>
- where J: IntoIterator,
- Self: Sized
+ where
+ J: IntoIterator,
+ Self: Sized,
{
zip_eq(self, other)
}
@@ -581,8 +565,9 @@ pub trait Itertools : Iterator {
/// ```
///
fn batching<B, F>(self, f: F) -> Batching<Self, F>
- where F: FnMut(&mut Self) -> Option<B>,
- Self: Sized
+ where
+ F: FnMut(&mut Self) -> Option<B>,
+ Self: Sized,
{
adaptors::batching(self, f)
}
@@ -623,9 +608,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn group_by<K, F>(self, key: F) -> GroupBy<K, Self, F>
- where Self: Sized,
- F: FnMut(&Self::Item) -> K,
- K: PartialEq,
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item) -> K,
+ K: PartialEq,
{
groupbylazy::new(self, key)
}
@@ -659,7 +645,8 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn chunks(self, size: usize) -> IntoChunks<Self>
- where Self: Sized,
+ where
+ Self: Sized,
{
assert!(size != 0);
groupbylazy::new_chunks(self, size)
@@ -699,9 +686,10 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);
/// ```
fn tuple_windows<T>(self) -> TupleWindows<Self, T>
- where Self: Sized + Iterator<Item = T::Item>,
- T: traits::HomogeneousTuple,
- T::Item: Clone
+ where
+ Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple,
+ T::Item: Clone,
{
tuple_impl::tuple_windows(self)
}
@@ -734,9 +722,10 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 2)]);
/// ```
fn circular_tuple_windows<T>(self) -> CircularTupleWindows<Self, T>
- where Self: Sized + Clone + Iterator<Item = T::Item> + ExactSizeIterator,
- T: tuple_impl::TupleCollect + Clone,
- T::Item: Clone
+ where
+ Self: Sized + Clone + Iterator<Item = T::Item> + ExactSizeIterator,
+ T: tuple_impl::TupleCollect + Clone,
+ T::Item: Clone,
{
tuple_impl::circular_tuple_windows(self)
}
@@ -772,8 +761,9 @@ pub trait Itertools : Iterator {
///
/// See also [`Tuples::into_buffer`].
fn tuples<T>(self) -> Tuples<Self, T>
- where Self: Sized + Iterator<Item = T::Item>,
- T: traits::HomogeneousTuple
+ where
+ Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple,
{
tuple_impl::tuples(self)
}
@@ -797,8 +787,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn tee(self) -> (Tee<Self>, Tee<Self>)
- where Self: Sized,
- Self::Item: Clone
+ where
+ Self: Sized,
+ Self::Item: Clone,
{
tee::new(self)
}
@@ -819,10 +810,11 @@ pub trait Itertools : Iterator {
/// let it = (0..8).step(3);
/// itertools::assert_equal(it, vec![0, 3, 6]);
/// ```
- #[deprecated(note="Use std .step_by() instead", since="0.8.0")]
+ #[deprecated(note = "Use std .step_by() instead", since = "0.8.0")]
#[allow(deprecated)]
fn step(self, n: usize) -> Step<Self>
- where Self: Sized
+ where
+ Self: Sized,
{
adaptors::step(self, n)
}
@@ -835,17 +827,19 @@ pub trait Itertools : Iterator {
/// (1i32..42i32).map_into::<f64>().collect_vec();
/// ```
fn map_into<R>(self) -> MapInto<Self, R>
- where Self: Sized,
- Self::Item: Into<R>,
+ where
+ Self: Sized,
+ Self::Item: Into<R>,
{
adaptors::map_into(self)
}
/// See [`.map_ok()`](Itertools::map_ok).
- #[deprecated(note="Use .map_ok() instead", since="0.10.0")]
+ #[deprecated(note = "Use .map_ok() instead", since = "0.10.0")]
fn map_results<F, T, U, E>(self, f: F) -> MapOk<Self, F>
- where Self: Iterator<Item = Result<T, E>> + Sized,
- F: FnMut(T) -> U,
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(T) -> U,
{
self.map_ok(f)
}
@@ -862,8 +856,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
/// ```
fn map_ok<F, T, U, E>(self, f: F) -> MapOk<Self, F>
- where Self: Iterator<Item = Result<T, E>> + Sized,
- F: FnMut(T) -> U,
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(T) -> U,
{
adaptors::map_ok(self, f)
}
@@ -880,8 +875,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![Ok(22), Err(false)]);
/// ```
fn filter_ok<F, T, E>(self, f: F) -> FilterOk<Self, F>
- where Self: Iterator<Item = Result<T, E>> + Sized,
- F: FnMut(&T) -> bool,
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(&T) -> bool,
{
adaptors::filter_ok(self, f)
}
@@ -898,8 +894,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![Ok(44), Err(false)]);
/// ```
fn filter_map_ok<F, T, U, E>(self, f: F) -> FilterMapOk<Self, F>
- where Self: Iterator<Item = Result<T, E>> + Sized,
- F: FnMut(T) -> Option<U>,
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(T) -> Option<U>,
{
adaptors::filter_map_ok(self, f)
}
@@ -922,8 +919,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(output_result, Err(false));
/// ```
fn flatten_ok<T, E>(self) -> FlattenOk<Self, T, E>
- where Self: Iterator<Item = Result<T, E>> + Sized,
- T: IntoIterator
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ T: IntoIterator,
{
flatten_ok::flatten_ok(self)
}
@@ -959,8 +957,9 @@ pub trait Itertools : Iterator {
/// assert!(second_max.is_err());
/// ```
fn process_results<F, T, E, R>(self, processor: F) -> Result<R, E>
- where Self: Iterator<Item = Result<T, E>> + Sized,
- F: FnOnce(ProcessResults<Self, E>) -> R
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnOnce(ProcessResults<Self, E>) -> R,
{
process_results(self, processor)
}
@@ -980,9 +979,10 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![0, 0, 3, 5, 6, 9, 10]);
/// ```
fn merge<J>(self, other: J) -> Merge<Self, J::IntoIter>
- where Self: Sized,
- Self::Item: PartialOrd,
- J: IntoIterator<Item = Self::Item>
+ where
+ Self: Sized,
+ Self::Item: PartialOrd,
+ J: IntoIterator<Item = Self::Item>,
{
merge(self, other)
}
@@ -1004,11 +1004,12 @@ pub trait Itertools : Iterator {
/// ```
fn merge_by<J, F>(self, other: J, is_first: F) -> MergeBy<Self, J::IntoIter, F>
- where Self: Sized,
- J: IntoIterator<Item = Self::Item>,
- F: FnMut(&Self::Item, &Self::Item) -> bool
+ where
+ Self: Sized,
+ J: IntoIterator<Item = Self::Item>,
+ F: FnMut(&Self::Item, &Self::Item) -> bool,
{
- adaptors::merge_by_new(self, other.into_iter(), is_first)
+ merge_join::merge_by_new(self, other.into_iter(), is_first)
}
/// Create an iterator that merges items from both this and the specified
@@ -1070,10 +1071,10 @@ pub trait Itertools : Iterator {
/// ```
#[inline]
fn merge_join_by<J, F, T>(self, other: J, cmp_fn: F) -> MergeJoinBy<Self, J::IntoIter, F>
- where J: IntoIterator,
- F: FnMut(&Self::Item, &J::Item) -> T,
- T: merge_join::OrderingOrBool<Self::Item, J::Item>,
- Self: Sized
+ where
+ J: IntoIterator,
+ F: FnMut(&Self::Item, &J::Item) -> T,
+ Self: Sized,
{
merge_join_by(self, other, cmp_fn)
}
@@ -1096,9 +1097,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn kmerge(self) -> KMerge<<Self::Item as IntoIterator>::IntoIter>
- where Self: Sized,
- Self::Item: IntoIterator,
- <Self::Item as IntoIterator>::Item: PartialOrd,
+ where
+ Self: Sized,
+ Self::Item: IntoIterator,
+ <Self::Item as IntoIterator>::Item: PartialOrd,
{
kmerge(self)
}
@@ -1124,12 +1126,11 @@ pub trait Itertools : Iterator {
/// assert_eq!(it.last(), Some(-7.));
/// ```
#[cfg(feature = "use_alloc")]
- fn kmerge_by<F>(self, first: F)
- -> KMergeBy<<Self::Item as IntoIterator>::IntoIter, F>
- where Self: Sized,
- Self::Item: IntoIterator,
- F: FnMut(&<Self::Item as IntoIterator>::Item,
- &<Self::Item as IntoIterator>::Item) -> bool
+ fn kmerge_by<F>(self, first: F) -> KMergeBy<<Self::Item as IntoIterator>::IntoIter, F>
+ where
+ Self: Sized,
+ Self::Item: IntoIterator,
+ F: FnMut(&<Self::Item as IntoIterator>::Item, &<Self::Item as IntoIterator>::Item) -> bool,
{
kmerge_by(self, first)
}
@@ -1146,10 +1147,11 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![(0, 'α'), (0, 'β'), (1, 'α'), (1, 'β')]);
/// ```
fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>
- where Self: Sized,
- Self::Item: Clone,
- J: IntoIterator,
- J::IntoIter: Clone
+ where
+ Self: Sized,
+ Self::Item: Clone,
+ J: IntoIterator,
+ J::IntoIter: Clone,
{
adaptors::cartesian_product(self, other.into_iter())
}
@@ -1181,10 +1183,11 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn multi_cartesian_product(self) -> MultiProduct<<Self::Item as IntoIterator>::IntoIter>
- where Self: Sized,
- Self::Item: IntoIterator,
- <Self::Item as IntoIterator>::IntoIter: Clone,
- <Self::Item as IntoIterator>::Item: Clone
+ where
+ Self: Sized,
+ Self::Item: IntoIterator,
+ <Self::Item as IntoIterator>::IntoIter: Clone,
+ <Self::Item as IntoIterator>::Item: Clone,
{
adaptors::multi_cartesian_product(self)
}
@@ -1218,9 +1221,9 @@ pub trait Itertools : Iterator {
/// vec![-6., 4., -1.]);
/// ```
fn coalesce<F>(self, f: F) -> Coalesce<Self, F>
- where Self: Sized,
- F: FnMut(Self::Item, Self::Item)
- -> Result<Self::Item, (Self::Item, Self::Item)>
+ where
+ Self: Sized,
+ F: FnMut(Self::Item, Self::Item) -> Result<Self::Item, (Self::Item, Self::Item)>,
{
adaptors::coalesce(self, f)
}
@@ -1240,8 +1243,9 @@ pub trait Itertools : Iterator {
/// vec![1., 2., 3., 2.]);
/// ```
fn dedup(self) -> Dedup<Self>
- where Self: Sized,
- Self::Item: PartialEq,
+ where
+ Self: Sized,
+ Self::Item: PartialEq,
{
adaptors::dedup(self)
}
@@ -1262,8 +1266,9 @@ pub trait Itertools : Iterator {
/// vec![(0, 1.), (0, 2.), (0, 3.), (1, 2.)]);
/// ```
fn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp>
- where Self: Sized,
- Cmp: FnMut(&Self::Item, &Self::Item)->bool,
+ where
+ Self: Sized,
+ Cmp: FnMut(&Self::Item, &Self::Item) -> bool,
{
adaptors::dedup_by(self, cmp)
}
@@ -1330,8 +1335,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn duplicates(self) -> Duplicates<Self>
- where Self: Sized,
- Self::Item: Eq + Hash
+ where
+ Self: Sized,
+ Self::Item: Eq + Hash,
{
duplicates_impl::duplicates(self)
}
@@ -1355,9 +1361,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn duplicates_by<V, F>(self, f: F) -> DuplicatesBy<Self, V, F>
- where Self: Sized,
- V: Eq + Hash,
- F: FnMut(&Self::Item) -> V
+ where
+ Self: Sized,
+ V: Eq + Hash,
+ F: FnMut(&Self::Item) -> V,
{
duplicates_impl::duplicates_by(self, f)
}
@@ -1382,8 +1389,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn unique(self) -> Unique<Self>
- where Self: Sized,
- Self::Item: Clone + Eq + Hash
+ where
+ Self: Sized,
+ Self::Item: Clone + Eq + Hash,
{
unique_impl::unique(self)
}
@@ -1408,9 +1416,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn unique_by<V, F>(self, f: F) -> UniqueBy<Self, V, F>
- where Self: Sized,
- V: Eq + Hash,
- F: FnMut(&Self::Item) -> V
+ where
+ Self: Sized,
+ V: Eq + Hash,
+ F: FnMut(&Self::Item) -> V,
{
unique_impl::unique_by(self, f)
}
@@ -1428,8 +1437,9 @@ pub trait Itertools : Iterator {
/// See also [`.take_while_ref()`](Itertools::take_while_ref)
/// which is a similar adaptor.
fn peeking_take_while<F>(&mut self, accept: F) -> PeekingTakeWhile<Self, F>
- where Self: Sized + PeekingNext,
- F: FnMut(&Self::Item) -> bool,
+ where
+ Self: Sized + PeekingNext,
+ F: FnMut(&Self::Item) -> bool,
{
peeking_take_while::peeking_take_while(self, accept)
}
@@ -1453,8 +1463,9 @@ pub trait Itertools : Iterator {
///
/// ```
fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<Self, F>
- where Self: Clone,
- F: FnMut(&Self::Item) -> bool
+ where
+ Self: Clone,
+ F: FnMut(&Self::Item) -> bool,
{
adaptors::take_while_ref(self, accept)
}
@@ -1519,7 +1530,7 @@ pub trait Itertools : Iterator {
/// .collect();
/// let expected: Vec<_> = vec![1, 2, 3].into_iter().map(NoCloneImpl).collect();
/// assert_eq!(filtered, expected);
- fn take_while_inclusive<F>(&mut self, accept: F) -> TakeWhileInclusive<Self, F>
+ fn take_while_inclusive<F>(self, accept: F) -> TakeWhileInclusive<Self, F>
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
@@ -1542,7 +1553,8 @@ pub trait Itertools : Iterator {
///
/// ```
fn while_some<A>(self) -> WhileSome<Self>
- where Self: Sized + Iterator<Item = Option<A>>
+ where
+ Self: Sized + Iterator<Item = Option<A>>,
{
adaptors::while_some(self)
}
@@ -1581,9 +1593,10 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);
/// ```
fn tuple_combinations<T>(self) -> TupleCombinations<Self, T>
- where Self: Sized + Clone,
- Self::Item: Clone,
- T: adaptors::HasCombination<Self>,
+ where
+ Self: Sized + Clone,
+ Self::Item: Clone,
+ T: adaptors::HasCombination<Self>,
{
adaptors::tuple_combinations(self)
}
@@ -1619,8 +1632,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn combinations(self, k: usize) -> Combinations<Self>
- where Self: Sized,
- Self::Item: Clone
+ where
+ Self: Sized,
+ Self::Item: Clone,
{
combinations::combinations(self, k)
}
@@ -1662,6 +1676,9 @@ pub trait Itertools : Iterator {
/// If `k` is greater than the length of the input iterator, the resultant
/// iterator adaptor will be empty.
///
+ /// If you are looking for permutations with replacements,
+ /// use `repeat_n(iter, k).multi_cartesian_product()` instead.
+ ///
/// ```
/// use itertools::Itertools;
///
@@ -1692,8 +1709,9 @@ pub trait Itertools : Iterator {
/// re-iterated if the permutations adaptor is completed and re-iterated.
#[cfg(feature = "use_alloc")]
fn permutations(self, k: usize) -> Permutations<Self>
- where Self: Sized,
- Self::Item: Clone
+ where
+ Self: Sized,
+ Self::Item: Clone,
{
permutations::permutations(self, k)
}
@@ -1728,8 +1746,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn powerset(self) -> Powerset<Self>
- where Self: Sized,
- Self::Item: Clone,
+ where
+ Self: Sized,
+ Self::Item: Clone,
{
powerset::powerset(self)
}
@@ -1752,8 +1771,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![18, 16, 14, 12, 10, 4, 3, 2, 1, 0]);
/// ```
fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>
- where Self: Sized,
- F: FnMut(usize) -> Self::Item
+ where
+ Self: Sized,
+ F: FnMut(usize) -> Self::Item,
{
pad_tail::pad_using(self, min, f)
}
@@ -1778,7 +1798,8 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![(Position::Only, 0)]);
/// ```
fn with_position(self) -> WithPosition<Self>
- where Self: Sized,
+ where
+ Self: Sized,
{
with_position::with_position(self)
}
@@ -1797,8 +1818,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(data.iter().positions(|v| v % 2 == 1).rev(), vec![7, 6, 3, 2, 0]);
/// ```
fn positions<P>(self, predicate: P) -> Positions<Self, P>
- where Self: Sized,
- P: FnMut(Self::Item) -> bool,
+ where
+ Self: Sized,
+ P: FnMut(Self::Item) -> bool,
{
adaptors::positions(self, predicate)
}
@@ -1814,8 +1836,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(it, vec![vec![1, 0], vec![3, 2, 1, 0]]);
/// ```
fn update<F>(self, updater: F) -> Update<Self, F>
- where Self: Sized,
- F: FnMut(&mut Self::Item),
+ where
+ Self: Sized,
+ F: FnMut(&mut Self::Item),
{
adaptors::update(self, updater)
}
@@ -1835,8 +1858,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(Some((1, 2)), iter.next_tuple());
/// ```
fn next_tuple<T>(&mut self) -> Option<T>
- where Self: Sized + Iterator<Item = T::Item>,
- T: traits::HomogeneousTuple
+ where
+ Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple,
{
T::collect_from_iter_no_buf(self)
}
@@ -1860,19 +1884,19 @@ pub trait Itertools : Iterator {
/// }
/// ```
fn collect_tuple<T>(mut self) -> Option<T>
- where Self: Sized + Iterator<Item = T::Item>,
- T: traits::HomogeneousTuple
+ where
+ Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple,
{
match self.next_tuple() {
elt @ Some(_) => match self.next() {
Some(_) => None,
None => elt,
},
- _ => None
+ _ => None,
}
}
-
/// Find the position and value of the first element satisfying a predicate.
///
/// The iterator is not advanced past the first element found.
@@ -1884,7 +1908,8 @@ pub trait Itertools : Iterator {
/// assert_eq!(text.chars().find_position(|ch| ch.is_lowercase()), Some((1, 'α')));
/// ```
fn find_position<P>(&mut self, mut pred: P) -> Option<(usize, Self::Item)>
- where P: FnMut(&Self::Item) -> bool
+ where
+ P: FnMut(&Self::Item) -> bool,
{
for (index, elt) in self.enumerate() {
if pred(&elt) {
@@ -1906,12 +1931,20 @@ pub trait Itertools : Iterator {
/// assert_eq!(std::iter::empty::<i32>().find_or_last(|&x| x > 5), None);
/// ```
fn find_or_last<P>(mut self, mut predicate: P) -> Option<Self::Item>
- where Self: Sized,
- P: FnMut(&Self::Item) -> bool,
+ where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
{
let mut prev = None;
- self.find_map(|x| if predicate(&x) { Some(x) } else { prev = Some(x); None })
- .or(prev)
+ self.find_map(|x| {
+ if predicate(&x) {
+ Some(x)
+ } else {
+ prev = Some(x);
+ None
+ }
+ })
+ .or(prev)
}
/// Find the value of the first element satisfying a predicate or return the first element, if any.
///
@@ -1926,8 +1959,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(std::iter::empty::<i32>().find_or_first(|&x| x > 5), None);
/// ```
fn find_or_first<P>(mut self, mut predicate: P) -> Option<Self::Item>
- where Self: Sized,
- P: FnMut(&Self::Item) -> bool,
+ where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
{
let first = self.next()?;
Some(if predicate(&first) {
@@ -1987,8 +2021,9 @@ pub trait Itertools : Iterator {
/// assert!(data.into_iter().all_equal());
/// ```
fn all_equal(&mut self) -> bool
- where Self: Sized,
- Self::Item: PartialEq,
+ where
+ Self: Sized,
+ Self::Item: PartialEq,
{
match self.next() {
None => true,
@@ -2014,9 +2049,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(data.into_iter().all_equal_value(), Err(None));
/// ```
fn all_equal_value(&mut self) -> Result<Self::Item, Option<(Self::Item, Self::Item)>>
- where
- Self: Sized,
- Self::Item: PartialEq
+ where
+ Self: Sized,
+ Self::Item: PartialEq,
{
let first = self.next().ok_or(None)?;
let other = self.find(|x| x != &first);
@@ -2044,8 +2079,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn all_unique(&mut self) -> bool
- where Self: Sized,
- Self::Item: Eq + Hash
+ where
+ Self: Sized,
+ Self::Item: Eq + Hash,
{
let mut used = HashSet::new();
self.all(move |elt| used.insert(elt))
@@ -2067,7 +2103,8 @@ pub trait Itertools : Iterator {
/// *Fusing notes: if the iterator is exhausted by dropping,
/// the result of calling `.next()` again depends on the iterator implementation.*
fn dropping(mut self, n: usize) -> Self
- where Self: Sized
+ where
+ Self: Sized,
{
if n > 0 {
self.nth(n - 1);
@@ -2091,8 +2128,9 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(init, vec![0, 3, 6]);
/// ```
fn dropping_back(mut self, n: usize) -> Self
- where Self: Sized,
- Self: DoubleEndedIterator
+ where
+ Self: Sized,
+ Self: DoubleEndedIterator,
{
if n > 0 {
(&mut self).rev().nth(n - 1);
@@ -2117,10 +2155,11 @@ pub trait Itertools : Iterator {
///
/// itertools::assert_equal(rx.iter(), vec![1, 3, 5, 7, 9]);
/// ```
- #[deprecated(note="Use .for_each() instead", since="0.8.0")]
+ #[deprecated(note = "Use .for_each() instead", since = "0.8.0")]
fn foreach<F>(self, f: F)
- where F: FnMut(Self::Item),
- Self: Sized,
+ where
+ F: FnMut(Self::Item),
+ Self: Sized,
{
self.for_each(f);
}
@@ -2139,8 +2178,10 @@ pub trait Itertools : Iterator {
/// vec![1, 2, 3, 4, 5, 6]);
/// ```
fn concat(self) -> Self::Item
- where Self: Sized,
- Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default
+ where
+ Self: Sized,
+ Self::Item:
+ Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default,
{
concat(self)
}
@@ -2149,7 +2190,8 @@ pub trait Itertools : Iterator {
/// for convenience.
#[cfg(feature = "use_alloc")]
fn collect_vec(self) -> Vec<Self::Item>
- where Self: Sized
+ where
+ Self: Sized,
{
self.collect()
}
@@ -2174,7 +2216,6 @@ pub trait Itertools : Iterator {
/// Ok(())
/// }
/// ```
- #[cfg(feature = "use_alloc")]
fn try_collect<T, U, E>(self) -> Result<U, E>
where
Self: Sized + Iterator<Item = Result<T, E>>,
@@ -2200,8 +2241,9 @@ pub trait Itertools : Iterator {
/// ```
#[inline]
fn set_from<'a, A: 'a, J>(&mut self, from: J) -> usize
- where Self: Iterator<Item = &'a mut A>,
- J: IntoIterator<Item = A>
+ where
+ Self: Iterator<Item = &'a mut A>,
+ J: IntoIterator<Item = A>,
{
let mut count = 0;
for elt in from {
@@ -2226,7 +2268,8 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn join(&mut self, sep: &str) -> String
- where Self::Item: std::fmt::Display
+ where
+ Self::Item: std::fmt::Display,
{
match self.next() {
None => String::new(),
@@ -2260,7 +2303,8 @@ pub trait Itertools : Iterator {
/// "1.10, 2.72, -3.00");
/// ```
fn format(self, sep: &str) -> Format<Self>
- where Self: Sized,
+ where
+ Self: Sized,
{
format::new_format_default(self, sep)
}
@@ -2298,17 +2342,19 @@ pub trait Itertools : Iterator {
///
/// ```
fn format_with<F>(self, sep: &str, format: F) -> FormatWith<Self, F>
- where Self: Sized,
- F: FnMut(Self::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
+ where
+ Self: Sized,
+ F: FnMut(Self::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
{
format::new_format(self, sep, format)
}
/// See [`.fold_ok()`](Itertools::fold_ok).
- #[deprecated(note="Use .fold_ok() instead", since="0.10.0")]
+ #[deprecated(note = "Use .fold_ok() instead", since = "0.10.0")]
fn fold_results<A, E, B, F>(&mut self, start: B, f: F) -> Result<B, E>
- where Self: Iterator<Item = Result<A, E>>,
- F: FnMut(B, A) -> B
+ where
+ Self: Iterator<Item = Result<A, E>>,
+ F: FnMut(B, A) -> B,
{
self.fold_ok(start, f)
}
@@ -2327,7 +2373,9 @@ pub trait Itertools : Iterator {
/// For example the sequence *Ok(1), Ok(2), Ok(3)* will result in a
/// computation like this:
///
- /// ```ignore
+ /// ```no_run
+ /// # let start = 0;
+ /// # let f = |x, y| x + y;
/// let mut accum = start;
/// accum = f(accum, 1);
/// accum = f(accum, 2);
@@ -2356,8 +2404,9 @@ pub trait Itertools : Iterator {
/// );
/// ```
fn fold_ok<A, E, B, F>(&mut self, mut start: B, mut f: F) -> Result<B, E>
- where Self: Iterator<Item = Result<A, E>>,
- F: FnMut(B, A) -> B
+ where
+ Self: Iterator<Item = Result<A, E>>,
+ F: FnMut(B, A) -> B,
{
for elt in self {
match elt {
@@ -2388,8 +2437,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(more_values.next().unwrap(), Some(0));
/// ```
fn fold_options<A, B, F>(&mut self, mut start: B, mut f: F) -> Option<B>
- where Self: Iterator<Item = Option<A>>,
- F: FnMut(B, A) -> B
+ where
+ Self: Iterator<Item = Option<A>>,
+ F: FnMut(B, A) -> B,
{
for elt in self {
match elt {
@@ -2414,8 +2464,9 @@ pub trait Itertools : Iterator {
/// ```
#[deprecated(since = "0.10.2", note = "Use `Iterator::reduce` instead")]
fn fold1<F>(mut self, f: F) -> Option<Self::Item>
- where F: FnMut(Self::Item, Self::Item) -> Self::Item,
- Self: Sized,
+ where
+ F: FnMut(Self::Item, Self::Item) -> Self::Item,
+ Self: Sized,
{
self.next().map(move |x| self.fold(x, f))
}
@@ -2448,7 +2499,18 @@ pub trait Itertools : Iterator {
/// └─f─f─f─f─f─f
/// ```
///
- /// If `f` is associative, prefer the normal [`Iterator::reduce`] instead.
+ /// If `f` is associative you should also decide carefully:
+ ///
+ /// - if `f` is a trivial operation like `u32::wrapping_add`, prefer the normal
+ /// [`Iterator::reduce`] instead since it will most likely result in the generation of simpler
+ /// code because the compiler is able to optimize it
+ /// - otherwise if `f` is non-trivial like `format!`, you should use `tree_fold1` since it
+ /// reduces the number of operations from `O(n)` to `O(ln(n))`
+ ///
+ /// Here "non-trivial" means:
+ ///
+ /// - any allocating operation
+ /// - any function that is a composition of many operations
///
/// ```
/// use itertools::Itertools;
@@ -2469,44 +2531,48 @@ pub trait Itertools : Iterator {
/// (0..10).fold1(|x, y| x - y));
/// ```
fn tree_fold1<F>(mut self, mut f: F) -> Option<Self::Item>
- where F: FnMut(Self::Item, Self::Item) -> Self::Item,
- Self: Sized,
+ where
+ F: FnMut(Self::Item, Self::Item) -> Self::Item,
+ Self: Sized,
{
type State<T> = Result<T, Option<T>>;
fn inner0<T, II, FF>(it: &mut II, f: &mut FF) -> State<T>
- where
- II: Iterator<Item = T>,
- FF: FnMut(T, T) -> T
+ where
+ II: Iterator<Item = T>,
+ FF: FnMut(T, T) -> T,
{
// This function could be replaced with `it.next().ok_or(None)`,
// but half the useful tree_fold1 work is combining adjacent items,
// so put that in a form that LLVM is more likely to optimize well.
- let a =
- if let Some(v) = it.next() { v }
- else { return Err(None) };
- let b =
- if let Some(v) = it.next() { v }
- else { return Err(Some(a)) };
+ let a = if let Some(v) = it.next() {
+ v
+ } else {
+ return Err(None);
+ };
+ let b = if let Some(v) = it.next() {
+ v
+ } else {
+ return Err(Some(a));
+ };
Ok(f(a, b))
}
fn inner<T, II, FF>(stop: usize, it: &mut II, f: &mut FF) -> State<T>
- where
- II: Iterator<Item = T>,
- FF: FnMut(T, T) -> T
+ where
+ II: Iterator<Item = T>,
+ FF: FnMut(T, T) -> T,
{
let mut x = inner0(it, f)?;
for height in 0..stop {
// Try to get another tree the same size with which to combine it,
// creating a new tree that's twice as big for next time around.
- let next =
- if height == 0 {
- inner0(it, f)
- } else {
- inner(height, it, f)
- };
+ let next = if height == 0 {
+ inner0(it, f)
+ } else {
+ inner(height, it, f)
+ };
match next {
Ok(y) => x = f(x, y),
@@ -2567,19 +2633,19 @@ pub trait Itertools : Iterator {
/// `fold()` called the provided closure for every item of the callee iterator,
/// `fold_while()` actually stopped iterating as soon as it encountered `Fold::Done(_)`.
fn fold_while<B, F>(&mut self, init: B, mut f: F) -> FoldWhile<B>
- where Self: Sized,
- F: FnMut(B, Self::Item) -> FoldWhile<B>
- {
- use Result::{
- Ok as Continue,
- Err as Break,
- };
-
- let result = self.try_fold(init, #[inline(always)] |acc, v|
- match f(acc, v) {
- FoldWhile::Continue(acc) => Continue(acc),
- FoldWhile::Done(acc) => Break(acc),
- }
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> FoldWhile<B>,
+ {
+ use Result::{Err as Break, Ok as Continue};
+
+ let result = self.try_fold(
+ init,
+ #[inline(always)]
+ |acc, v| match f(acc, v) {
+ FoldWhile::Continue(acc) => Continue(acc),
+ FoldWhile::Done(acc) => Break(acc),
+ },
);
match result {
@@ -2610,11 +2676,11 @@ pub trait Itertools : Iterator {
/// assert_eq!(nonempty_sum, Some(55));
/// ```
fn sum1<S>(mut self) -> Option<S>
- where Self: Sized,
- S: std::iter::Sum<Self::Item>,
+ where
+ Self: Sized,
+ S: std::iter::Sum<Self::Item>,
{
- self.next()
- .map(|first| once(first).chain(self).sum())
+ self.next().map(|first| once(first).chain(self).sum())
}
/// Iterate over the entire iterator and multiply all the elements.
@@ -2638,11 +2704,11 @@ pub trait Itertools : Iterator {
/// assert_eq!(nonempty_product, Some(3628800));
/// ```
fn product1<P>(mut self) -> Option<P>
- where Self: Sized,
- P: std::iter::Product<Self::Item>,
+ where
+ Self: Sized,
+ P: std::iter::Product<Self::Item>,
{
- self.next()
- .map(|first| once(first).chain(self).product())
+ self.next().map(|first| once(first).chain(self).product())
}
/// Sort all iterator elements into a new iterator in ascending order.
@@ -2650,7 +2716,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_unstable`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is unstable (i.e., may reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2666,8 +2732,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_unstable(self) -> VecIntoIter<Self::Item>
- where Self: Sized,
- Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
// Use .sort_unstable() directly since it is not quite identical with
// .sort_by(Ord::cmp)
@@ -2681,7 +2748,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_unstable_by`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is unstable (i.e., may reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2703,8 +2770,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_unstable_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
- where Self: Sized,
- F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
let mut v = Vec::from_iter(self);
v.sort_unstable_by(cmp);
@@ -2716,7 +2784,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_unstable_by_key`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is unstable (i.e., may reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2738,9 +2806,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_unstable_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
- where Self: Sized,
- K: Ord,
- F: FnMut(&Self::Item) -> K,
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
{
let mut v = Vec::from_iter(self);
v.sort_unstable_by_key(f);
@@ -2752,7 +2821,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is stable (i.e., does not reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2768,8 +2837,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn sorted(self) -> VecIntoIter<Self::Item>
- where Self: Sized,
- Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
// Use .sort() directly since it is not quite identical with
// .sort_by(Ord::cmp)
@@ -2783,7 +2853,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_by`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is stable (i.e., does not reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2805,8 +2875,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
- where Self: Sized,
- F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
let mut v = Vec::from_iter(self);
v.sort_by(cmp);
@@ -2818,7 +2889,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_by_key`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is stable (i.e., does not reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2840,9 +2911,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn sorted_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
- where Self: Sized,
- K: Ord,
- F: FnMut(&Self::Item) -> K,
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
{
let mut v = Vec::from_iter(self);
v.sort_by_key(f);
@@ -2855,7 +2927,7 @@ pub trait Itertools : Iterator {
/// **Note:** This consumes the entire iterator, uses the
/// [`slice::sort_by_cached_key`] method and returns the result as a new
/// iterator that owns its elements.
- ///
+ ///
/// This sort is stable (i.e., does not reorder equal elements).
///
/// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -2916,8 +2988,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_alloc")]
fn k_smallest(self, k: usize) -> VecIntoIter<Self::Item>
- where Self: Sized,
- Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
crate::k_smallest::k_smallest(self, k)
.into_sorted_vec()
@@ -2946,10 +3019,11 @@ pub trait Itertools : Iterator {
/// assert_eq!(failures, [false, true]);
/// ```
fn partition_map<A, B, F, L, R>(self, mut predicate: F) -> (A, B)
- where Self: Sized,
- F: FnMut(Self::Item) -> Either<L, R>,
- A: Default + Extend<L>,
- B: Default + Extend<R>,
+ where
+ Self: Sized,
+ F: FnMut(Self::Item) -> Either<L, R>,
+ A: Default + Extend<L>,
+ B: Default + Extend<R>,
{
let mut left = A::default();
let mut right = B::default();
@@ -2978,10 +3052,10 @@ pub trait Itertools : Iterator {
/// assert_eq!(failures, [false, true]);
/// ```
fn partition_result<A, B, T, E>(self) -> (A, B)
- where
- Self: Iterator<Item = Result<T, E>> + Sized,
- A: Default + Extend<T>,
- B: Default + Extend<E>,
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ A: Default + Extend<T>,
+ B: Default + Extend<E>,
{
self.partition_map(|r| match r {
Ok(v) => Either::Left(v),
@@ -3007,8 +3081,9 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn into_group_map<K, V>(self) -> HashMap<K, Vec<V>>
- where Self: Iterator<Item=(K, V)> + Sized,
- K: Hash + Eq,
+ where
+ Self: Iterator<Item = (K, V)> + Sized,
+ K: Hash + Eq,
{
group_map::into_group_map(self)
}
@@ -3042,10 +3117,10 @@ pub trait Itertools : Iterator {
/// ```
#[cfg(feature = "use_std")]
fn into_group_map_by<K, V, F>(self, f: F) -> HashMap<K, Vec<V>>
- where
- Self: Iterator<Item=V> + Sized,
- K: Hash + Eq,
- F: Fn(&V) -> K,
+ where
+ Self: Iterator<Item = V> + Sized,
+ K: Hash + Eq,
+ F: Fn(&V) -> K,
{
group_map::into_group_map_by(self, f)
}
@@ -3061,8 +3136,9 @@ pub trait Itertools : Iterator {
/// on what operations are available.
#[cfg(feature = "use_std")]
fn into_grouping_map<K, V>(self) -> GroupingMap<Self>
- where Self: Iterator<Item=(K, V)> + Sized,
- K: Hash + Eq,
+ where
+ Self: Iterator<Item = (K, V)> + Sized,
+ K: Hash + Eq,
{
grouping_map::new(self)
}
@@ -3077,9 +3153,10 @@ pub trait Itertools : Iterator {
/// on what operations are available.
#[cfg(feature = "use_std")]
fn into_grouping_map_by<K, V, F>(self, key_mapper: F) -> GroupingMapBy<Self, F>
- where Self: Iterator<Item=V> + Sized,
- K: Hash + Eq,
- F: FnMut(&V) -> K
+ where
+ Self: Iterator<Item = V> + Sized,
+ K: Hash + Eq,
+ F: FnMut(&V) -> K,
{
grouping_map::new(grouping_map::MapForGrouping::new(self, key_mapper))
}
@@ -3106,9 +3183,11 @@ pub trait Itertools : Iterator {
///
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
- #[cfg(feature = "use_std")]
+ #[cfg(feature = "use_alloc")]
fn min_set(self) -> Vec<Self::Item>
- where Self: Sized, Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
extrema_set::min_set_impl(self, |_| (), |x, y, _, _| x.cmp(y))
}
@@ -3137,15 +3216,13 @@ pub trait Itertools : Iterator {
///
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
- #[cfg(feature = "use_std")]
+ #[cfg(feature = "use_alloc")]
fn min_set_by<F>(self, mut compare: F) -> Vec<Self::Item>
- where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
- extrema_set::min_set_impl(
- self,
- |_| (),
- |x, y, _, _| compare(x, y)
- )
+ extrema_set::min_set_impl(self, |_| (), |x, y, _, _| compare(x, y))
}
/// Return all minimum elements of an iterator, as determined by
@@ -3171,9 +3248,12 @@ pub trait Itertools : Iterator {
///
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
- #[cfg(feature = "use_std")]
+ #[cfg(feature = "use_alloc")]
fn min_set_by_key<K, F>(self, key: F) -> Vec<Self::Item>
- where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
{
extrema_set::min_set_impl(self, key, |_, _, kx, ky| kx.cmp(ky))
}
@@ -3200,9 +3280,11 @@ pub trait Itertools : Iterator {
///
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
- #[cfg(feature = "use_std")]
+ #[cfg(feature = "use_alloc")]
fn max_set(self) -> Vec<Self::Item>
- where Self: Sized, Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
extrema_set::max_set_impl(self, |_| (), |x, y, _, _| x.cmp(y))
}
@@ -3231,15 +3313,13 @@ pub trait Itertools : Iterator {
///
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
- #[cfg(feature = "use_std")]
+ #[cfg(feature = "use_alloc")]
fn max_set_by<F>(self, mut compare: F) -> Vec<Self::Item>
- where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
- extrema_set::max_set_impl(
- self,
- |_| (),
- |x, y, _, _| compare(x, y)
- )
+ extrema_set::max_set_impl(self, |_| (), |x, y, _, _| compare(x, y))
}
/// Return all maximum elements of an iterator, as determined by
@@ -3265,9 +3345,12 @@ pub trait Itertools : Iterator {
///
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
- #[cfg(feature = "use_std")]
+ #[cfg(feature = "use_alloc")]
fn max_set_by_key<K, F>(self, key: F) -> Vec<Self::Item>
- where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
{
extrema_set::max_set_impl(self, key, |_, _, kx, ky| kx.cmp(ky))
}
@@ -3308,7 +3391,9 @@ pub trait Itertools : Iterator {
/// The elements can be floats but no particular result is guaranteed
/// if an element is NaN.
fn minmax(self) -> MinMaxResult<Self::Item>
- where Self: Sized, Self::Item: PartialOrd
+ where
+ Self: Sized,
+ Self::Item: PartialOrd,
{
minmax::minmax_impl(self, |_| (), |x, y, _, _| x < y)
}
@@ -3325,7 +3410,10 @@ pub trait Itertools : Iterator {
/// The keys can be floats but no particular result is guaranteed
/// if a key is NaN.
fn minmax_by_key<K, F>(self, key: F) -> MinMaxResult<Self::Item>
- where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K
+ where
+ Self: Sized,
+ K: PartialOrd,
+ F: FnMut(&Self::Item) -> K,
{
minmax::minmax_impl(self, key, |_, _, xk, yk| xk < yk)
}
@@ -3339,13 +3427,11 @@ pub trait Itertools : Iterator {
/// the last maximal element wins. This matches the behavior of the standard
/// [`Iterator::min`] and [`Iterator::max`] methods.
fn minmax_by<F>(self, mut compare: F) -> MinMaxResult<Self::Item>
- where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
- minmax::minmax_impl(
- self,
- |_| (),
- |x, y, _, _| Ordering::Less == compare(x, y)
- )
+ minmax::minmax_impl(self, |_| (), |x, y, _, _| Ordering::Less == compare(x, y))
}
/// Return the position of the maximum element in the iterator.
@@ -3368,7 +3454,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_max(), Some(1));
/// ```
fn position_max(self) -> Option<usize>
- where Self: Sized, Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
self.enumerate()
.max_by(|x, y| Ord::cmp(&x.1, &y.1))
@@ -3396,7 +3484,10 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(3));
/// ```
fn position_max_by_key<K, F>(self, mut key: F) -> Option<usize>
- where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
{
self.enumerate()
.max_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
@@ -3424,7 +3515,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(1));
/// ```
fn position_max_by<F>(self, mut compare: F) -> Option<usize>
- where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
self.enumerate()
.max_by(|x, y| compare(&x.1, &y.1))
@@ -3451,7 +3544,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_min(), Some(2));
/// ```
fn position_min(self) -> Option<usize>
- where Self: Sized, Self::Item: Ord
+ where
+ Self: Sized,
+ Self::Item: Ord,
{
self.enumerate()
.min_by(|x, y| Ord::cmp(&x.1, &y.1))
@@ -3479,7 +3574,10 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(0));
/// ```
fn position_min_by_key<K, F>(self, mut key: F) -> Option<usize>
- where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
{
self.enumerate()
.min_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
@@ -3507,7 +3605,9 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(2));
/// ```
fn position_min_by<F>(self, mut compare: F) -> Option<usize>
- where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
self.enumerate()
.min_by(|x, y| compare(&x.1, &y.1))
@@ -3557,9 +3657,11 @@ pub trait Itertools : Iterator {
/// assert_eq!(a.iter().position_minmax(), MinMax(2, 1));
/// ```
fn position_minmax(self) -> MinMaxResult<usize>
- where Self: Sized, Self::Item: PartialOrd
+ where
+ Self: Sized,
+ Self::Item: PartialOrd,
{
- use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+ use crate::MinMaxResult::{MinMax, NoElements, OneElement};
match minmax::minmax_impl(self.enumerate(), |_| (), |x, y, _, _| x.1 < y.1) {
NoElements => NoElements,
OneElement(x) => OneElement(x.0),
@@ -3602,9 +3704,12 @@ pub trait Itertools : Iterator {
///
/// [`position_minmax`]: Self::position_minmax
fn position_minmax_by_key<K, F>(self, mut key: F) -> MinMaxResult<usize>
- where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K
+ where
+ Self: Sized,
+ K: PartialOrd,
+ F: FnMut(&Self::Item) -> K,
{
- use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+ use crate::MinMaxResult::{MinMax, NoElements, OneElement};
match self.enumerate().minmax_by_key(|e| key(&e.1)) {
NoElements => NoElements,
OneElement(x) => OneElement(x.0),
@@ -3644,9 +3749,11 @@ pub trait Itertools : Iterator {
///
/// [`position_minmax`]: Self::position_minmax
fn position_minmax_by<F>(self, mut compare: F) -> MinMaxResult<usize>
- where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
- use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+ use crate::MinMaxResult::{MinMax, NoElements, OneElement};
match self.enumerate().minmax_by(|x, y| compare(&x.1, &y.1)) {
NoElements => NoElements,
OneElement(x) => OneElement(x.0),
@@ -3676,16 +3783,13 @@ pub trait Itertools : Iterator {
Self: Sized,
{
match self.next() {
- Some(first) => {
- match self.next() {
- Some(second) => {
- Err(ExactlyOneError::new(Some(Either::Left([first, second])), self))
- }
- None => {
- Ok(first)
- }
- }
- }
+ Some(first) => match self.next() {
+ Some(second) => Err(ExactlyOneError::new(
+ Some(Either::Left([first, second])),
+ self,
+ )),
+ None => Ok(first),
+ },
None => Err(ExactlyOneError::new(None, self)),
}
}
@@ -3712,16 +3816,13 @@ pub trait Itertools : Iterator {
Self: Sized,
{
match self.next() {
- Some(first) => {
- match self.next() {
- Some(second) => {
- Err(ExactlyOneError::new(Some(Either::Left([first, second])), self))
- }
- None => {
- Ok(Some(first))
- }
- }
- }
+ Some(first) => match self.next() {
+ Some(second) => Err(ExactlyOneError::new(
+ Some(Either::Left([first, second])),
+ self,
+ )),
+ None => Ok(Some(first)),
+ },
None => Ok(None),
}
}
@@ -3840,9 +3941,33 @@ pub trait Itertools : Iterator {
{
MultiUnzip::multiunzip(self)
}
+
+ /// Returns the length of the iterator if one exists.
+ /// Otherwise return `self.size_hint()`.
+ ///
+ /// Fallible [`ExactSizeIterator::len`].
+ ///
+ /// Inherits guarantees and restrictions from [`Iterator::size_hint`].
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// assert_eq!([0; 10].iter().try_len(), Ok(10));
+ /// assert_eq!((10..15).try_len(), Ok(5));
+ /// assert_eq!((15..10).try_len(), Ok(0));
+ /// assert_eq!((10..).try_len(), Err((usize::MAX, None)));
+ /// assert_eq!((10..15).filter(|x| x % 2 == 0).try_len(), Err((0, Some(5))));
+ /// ```
+ fn try_len(&self) -> Result<usize, size_hint::SizeHint> {
+ let sh = self.size_hint();
+ match sh {
+ (lo, Some(hi)) if lo == hi => Ok(lo),
+ _ => Err(sh),
+ }
+ }
}
-impl<T: ?Sized> Itertools for T where T: Iterator { }
+impl<T: ?Sized> Itertools for T where T: Iterator {}
/// Return `true` if both iterables produce equal sequences
/// (elements pairwise equal and sequences of the same length),
@@ -3855,9 +3980,10 @@ impl<T: ?Sized> Itertools for T where T: Iterator { }
/// assert!(!itertools::equal(&[0, 0], &[0, 0, 0]));
/// ```
pub fn equal<I, J>(a: I, b: J) -> bool
- where I: IntoIterator,
- J: IntoIterator,
- I::Item: PartialEq<J::Item>
+where
+ I: IntoIterator,
+ J: IntoIterator,
+ I::Item: PartialEq<J::Item>,
{
a.into_iter().eq(b)
}
@@ -3868,15 +3994,17 @@ pub fn equal<I, J>(a: I, b: J) -> bool
/// **Panics** on assertion failure with a message that shows the
/// two iteration elements.
///
-/// ```ignore
+/// ```should_panic
+/// # use itertools::assert_equal;
/// assert_equal("exceed".split('c'), "excess".split('c'));
-/// // ^PANIC: panicked at 'Failed assertion Some("eed") == Some("ess") for iteration 1',
+/// // ^PANIC: panicked at 'Failed assertion Some("eed") == Some("ess") for iteration 1'.
/// ```
pub fn assert_equal<I, J>(a: I, b: J)
- where I: IntoIterator,
- J: IntoIterator,
- I::Item: fmt::Debug + PartialEq<J::Item>,
- J::Item: fmt::Debug,
+where
+ I: IntoIterator,
+ J: IntoIterator,
+ I::Item: fmt::Debug + PartialEq<J::Item>,
+ J::Item: fmt::Debug,
{
let mut ia = a.into_iter();
let mut ib = b.into_iter();
@@ -3889,8 +4017,13 @@ pub fn assert_equal<I, J>(a: I, b: J)
(&Some(ref a), &Some(ref b)) => a == b,
_ => false,
};
- assert!(equal, "Failed assertion {a:?} == {b:?} for iteration {i}",
- i=i, a=a, b=b);
+ assert!(
+ equal,
+ "Failed assertion {a:?} == {b:?} for iteration {i}",
+ i = i,
+ a = a,
+ b = b
+ );
i += 1;
}
}
@@ -3915,9 +4048,10 @@ pub fn assert_equal<I, J>(a: I, b: J)
/// assert_eq!(split_index, 3);
/// ```
pub fn partition<'a, A: 'a, I, F>(iter: I, mut pred: F) -> usize
- where I: IntoIterator<Item = &'a mut A>,
- I::IntoIter: DoubleEndedIterator,
- F: FnMut(&A) -> bool
+where
+ I: IntoIterator<Item = &'a mut A>,
+ I::IntoIter: DoubleEndedIterator,
+ F: FnMut(&A) -> bool,
{
let mut split_index = 0;
let mut iter = iter.into_iter();
@@ -3925,10 +4059,12 @@ pub fn partition<'a, A: 'a, I, F>(iter: I, mut pred: F) -> usize
if !pred(front) {
loop {
match iter.next_back() {
- Some(back) => if pred(back) {
- std::mem::swap(front, back);
- break;
- },
+ Some(back) => {
+ if pred(back) {
+ std::mem::swap(front, back);
+ break;
+ }
+ }
None => break 'main,
}
}