diff options
Diffstat (limited to 'vendor/itertools/src/lib.rs')
-rw-r--r-- | vendor/itertools/src/lib.rs | 902 |
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, } } |