Skip to content
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

Add HomogeneousTuple trait. #389

Merged
merged 1 commit into from Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/lib.rs
Expand Up @@ -137,6 +137,12 @@ pub mod structs {
pub use zip_longest::ZipLongest;
pub use ziptuple::Zip;
}

/// Traits helpful for using certain `Itertools` methods in generic contexts.
pub mod traits {
pub use ::tuple_impl::HomogeneousTuple;
}

#[allow(deprecated)]
pub use structs::*;
pub use concat_impl::concat;
Expand Down Expand Up @@ -588,7 +594,7 @@ pub trait Itertools : Iterator {
/// ```
fn tuple_windows<T>(self) -> TupleWindows<Self, T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect,
T: traits::HomogeneousTuple,
T::Item: Clone
{
tuple_impl::tuple_windows(self)
Expand Down Expand Up @@ -627,7 +633,7 @@ pub trait Itertools : Iterator {
/// See also [`Tuples::into_buffer`](structs/struct.Tuples.html#method.into_buffer).
fn tuples<T>(self) -> Tuples<Self, T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
T: traits::HomogeneousTuple
{
tuple_impl::tuples(self)
}
Expand Down Expand Up @@ -1352,7 +1358,7 @@ pub trait Itertools : Iterator {
/// ```
fn next_tuple<T>(&mut self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
T: traits::HomogeneousTuple
{
T::collect_from_iter_no_buf(self)
}
Expand All @@ -1377,7 +1383,7 @@ pub trait Itertools : Iterator {
/// ```
fn collect_tuple<T>(mut self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
T: traits::HomogeneousTuple
{
match self.next_tuple() {
elt @ Some(_) => match self.next() {
Expand Down
34 changes: 23 additions & 11 deletions src/tuple_impl.rs
Expand Up @@ -2,20 +2,32 @@

use std::iter::Fuse;

// `HomogeneousTuple` is a public facade for `TupleCollect`, allowing
// tuple-related methods to be used by clients in generic contexts, while
// hiding the implementation details of `TupleCollect`.
// See https://github.com/rust-itertools/itertools/issues/387

/// Implemented for homogeneous tuples of size up to 4.
pub trait HomogeneousTuple
: TupleCollect
{}

impl<T: TupleCollect> HomogeneousTuple for T {}

/// An iterator over a incomplete tuple.
///
/// See [`.tuples()`](../trait.Itertools.html#method.tuples) and
/// [`Tuples::into_buffer()`](struct.Tuples.html#method.into_buffer).
#[derive(Debug)]
pub struct TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
cur: usize,
buf: T::Buffer,
}

impl<T> TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
fn new(buf: T::Buffer) -> Self {
TupleBuffer {
Expand All @@ -26,7 +38,7 @@ impl<T> TupleBuffer<T>
}

impl<T> Iterator for TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
type Item = T::Item;

Expand Down Expand Up @@ -54,7 +66,7 @@ impl<T> Iterator for TupleBuffer<T>
}

impl<T> ExactSizeIterator for TupleBuffer<T>
where T: TupleCollect
where T: HomogeneousTuple
{
}

Expand All @@ -64,7 +76,7 @@ impl<T> ExactSizeIterator for TupleBuffer<T>
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
iter: Fuse<I>,
buf: T::Buffer,
Expand All @@ -73,7 +85,7 @@ pub struct Tuples<I, T>
/// Create a new tuples iterator.
pub fn tuples<I, T>(iter: I) -> Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
Tuples {
iter: iter.fuse(),
Expand All @@ -83,7 +95,7 @@ pub fn tuples<I, T>(iter: I) -> Tuples<I, T>

impl<I, T> Iterator for Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
type Item = T;

Expand All @@ -94,7 +106,7 @@ impl<I, T> Iterator for Tuples<I, T>

impl<I, T> Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
/// Return a buffer with the produced items that was not enough to be grouped in a tuple.
///
Expand All @@ -120,7 +132,7 @@ impl<I, T> Tuples<I, T>
#[derive(Debug)]
pub struct TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
T: HomogeneousTuple
{
iter: I,
last: Option<T>,
Expand All @@ -129,7 +141,7 @@ pub struct TupleWindows<I, T>
/// Create a new tuple windows iterator.
pub fn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect,
T: HomogeneousTuple,
T::Item: Clone
{
use std::iter::once;
Expand All @@ -152,7 +164,7 @@ pub fn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T>

impl<I, T> Iterator for TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect + Clone,
T: HomogeneousTuple + Clone,
T::Item: Clone
{
type Item = T;
Expand Down