-
Notifications
You must be signed in to change notification settings - Fork 319
Merge multipeek peeknth #940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
756ba95
c130144
518c877
5a1f1a9
3fab1c2
4bf4e4b
3920dbe
4fc8456
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -115,10 +115,10 @@ pub mod structs { | |
pub use crate::kmerge_impl::{KMerge, KMergeBy}; | ||
pub use crate::merge_join::{Merge, MergeBy, MergeJoinBy}; | ||
#[cfg(feature = "use_alloc")] | ||
pub use crate::multipeek_impl::MultiPeek; | ||
pub use crate::pad_tail::PadUsing; | ||
pub use crate::multipeek_general::MultiPeek; | ||
#[cfg(feature = "use_alloc")] | ||
pub use crate::peek_nth::PeekNth; | ||
pub use crate::multipeek_general::PeekNth; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can merge those imports. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup - merged. |
||
pub use crate::pad_tail::PadUsing; | ||
pub use crate::peeking_take_while::PeekingTakeWhile; | ||
#[cfg(feature = "use_alloc")] | ||
pub use crate::permutations::Permutations; | ||
|
@@ -205,10 +205,8 @@ mod lazy_buffer; | |
mod merge_join; | ||
mod minmax; | ||
#[cfg(feature = "use_alloc")] | ||
mod multipeek_impl; | ||
mod multipeek_general; | ||
mod pad_tail; | ||
#[cfg(feature = "use_alloc")] | ||
mod peek_nth; | ||
mod peeking_take_while; | ||
#[cfg(feature = "use_alloc")] | ||
mod permutations; | ||
|
@@ -4115,7 +4113,7 @@ pub trait Itertools: Iterator { | |
where | ||
Self: Sized, | ||
{ | ||
multipeek_impl::multipeek(self) | ||
multipeek_general::multipeek(self) | ||
} | ||
|
||
/// Collect the items in this iterator and return a `HashMap` which | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,38 @@ | ||
use crate::size_hint; | ||
use crate::PeekingNext; | ||
#![allow(private_interfaces)] | ||
#![allow(private_bounds)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I discover those lints, or rather I probably usually fix what those lints tell me rather than allow them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right. Turns out it passes the clippy even the lints are removed. I've removed them |
||
|
||
use crate::{size_hint, PeekingNext}; | ||
use alloc::collections::VecDeque; | ||
use std::iter::Fuse; | ||
|
||
/// See [`peek_nth()`] for more information. | ||
#[derive(Clone, Debug)] | ||
/// See [`multipeek()`] for more information. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove, |
||
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] | ||
pub struct PeekNth<I> | ||
#[derive(Debug, Clone)] | ||
pub struct MultiPeekGeneral<I: Iterator, Idx> { | ||
pub iter: Fuse<I>, | ||
pub buf: VecDeque<I::Item>, | ||
pub index: Idx, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Almost missed this. The fields should remain private! If there is a need to access them from another module, you can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks - I've changed them to private fields |
||
} | ||
|
||
/// See [`multipeek()`] for more information. | ||
pub type MultiPeek<I> = MultiPeekGeneral<I, usize>; | ||
|
||
/// See [`peek_nth()`] for more information. | ||
pub type PeekNth<I> = MultiPeekGeneral<I, ()>; | ||
|
||
/// An iterator adaptor that allows the user to peek at multiple `.next()` | ||
/// values without advancing the base iterator. | ||
/// | ||
/// [`IntoIterator`] enabled version of [`crate::Itertools::multipeek`]. | ||
pub fn multipeek<I>(iterable: I) -> MultiPeek<I::IntoIter> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To avoid
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. I've revised to use
|
||
where | ||
I: Iterator, | ||
I: IntoIterator, | ||
{ | ||
iter: Fuse<I>, | ||
buf: VecDeque<I::Item>, | ||
MultiPeek { | ||
iter: iterable.into_iter().fuse(), | ||
buf: VecDeque::new(), | ||
index: 0, | ||
} | ||
} | ||
|
||
/// A drop-in replacement for [`std::iter::Peekable`] which adds a `peek_nth` | ||
|
@@ -28,18 +49,25 @@ | |
PeekNth { | ||
iter: iterable.into_iter().fuse(), | ||
buf: VecDeque::new(), | ||
index: (), | ||
} | ||
} | ||
|
||
impl<I> PeekNth<I> | ||
where | ||
I: Iterator, | ||
{ | ||
/// Works exactly like the `peek` method in [`std::iter::Peekable`]. | ||
pub fn peek(&mut self) -> Option<&I::Item> { | ||
self.peek_nth(0) | ||
pub trait PeekIndex { | ||
fn reset_index(&mut self); | ||
} | ||
|
||
impl PeekIndex for () { | ||
fn reset_index(&mut self) {} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mention elsewhere the need to add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. I've revised |
||
|
||
impl PeekIndex for usize { | ||
fn reset_index(&mut self) { | ||
*self = 0; | ||
} | ||
} | ||
|
||
impl<I: Iterator, Idx: PeekIndex> MultiPeekGeneral<I, Idx> { | ||
/// Works exactly like the `peek_mut` method in [`std::iter::Peekable`]. | ||
pub fn peek_mut(&mut self) -> Option<&mut I::Item> { | ||
self.peek_nth_mut(0) | ||
|
@@ -137,15 +165,64 @@ | |
{ | ||
self.next_if(|next| next == expected) | ||
} | ||
|
||
/// Works exactly like `next_if`, but for the `nth` value without advancing the iterator. | ||
pub fn nth_if(&mut self, n: usize, func: impl FnOnce(&I::Item) -> bool) -> Option<&I::Item> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What should we expect from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe with the merge we'd need to completely revise the doc to describe the API behaviour under |
||
match self.peek_nth(n) { | ||
Some(item) if func(item) => Some(item), | ||
_ => None, | ||
} | ||
} | ||
|
||
/// Works exactly like `next_if_eq`, but for the `nth` value without advancing the iterator. | ||
pub fn nth_if_eq<T>(&mut self, n: usize, expected: &T) -> Option<&I::Item> | ||
where | ||
T: ?Sized, | ||
I::Item: PartialEq<T>, | ||
{ | ||
self.nth_if(n, |item| item == expected) | ||
} | ||
} | ||
impl<I: Iterator> MultiPeek<I> { | ||
/// Reset the peeking “cursor” | ||
pub fn reset_peek(&mut self) { | ||
self.index = 0 | ||
} | ||
|
||
impl<I> Iterator for PeekNth<I> | ||
where | ||
I: Iterator, | ||
{ | ||
/// Works exactly like `.next()` with the only difference that it doesn't | ||
/// advance itself. `.peek()` can be called multiple times, to peek | ||
/// further ahead. | ||
/// When `.next()` is called, reset the peeking “cursor”. | ||
pub fn peek(&mut self) -> Option<&I::Item> { | ||
let ret = if self.index < self.buf.len() { | ||
Some(&self.buf[self.index]) | ||
} else { | ||
match self.iter.next() { | ||
Some(x) => { | ||
self.buf.push_back(x); | ||
Some(&self.buf[self.index]) | ||
} | ||
None => return None, | ||
} | ||
}; | ||
|
||
self.index += 1; | ||
ret | ||
} | ||
} | ||
|
||
impl<I: Iterator> PeekNth<I> { | ||
/// Works exactly like the `peek` method in [`std::iter::Peekable`]. | ||
pub fn peek(&mut self) -> Option<&I::Item> { | ||
self.peek_nth(0) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it could be merged into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes - I've merged |
||
} | ||
|
||
impl<I: Iterator, Idx: PeekIndex> Iterator for MultiPeekGeneral<I, Idx> { | ||
type Item = I::Item; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
self.index.reset_index(); | ||
self.buf.pop_front().or_else(|| self.iter.next()) | ||
} | ||
|
||
|
@@ -162,17 +239,17 @@ | |
} | ||
} | ||
|
||
impl<I> ExactSizeIterator for PeekNth<I> where I: ExactSizeIterator {} | ||
impl<I: ExactSizeIterator, Idx: PeekIndex> ExactSizeIterator for MultiPeekGeneral<I, Idx> {} | ||
|
||
impl<I> PeekingNext for PeekNth<I> | ||
impl<I: Iterator, Idx: PeekIndex> PeekingNext for MultiPeekGeneral<I, Idx> | ||
where | ||
I: Iterator, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Moved |
||
{ | ||
fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item> | ||
where | ||
F: FnOnce(&Self::Item) -> bool, | ||
{ | ||
self.peek().filter(|item| accept(item))?; | ||
self.peek_mut().filter(|item| accept(item))?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see why it would now need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Reverted to |
||
self.next() | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can merge those lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merged