use std::iter::Fuse; use std::iter::FusedIterator; use std::iter::Take; use std::iter::Cycle; use std::marker::PhantomData;
// `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 12. pubtrait HomogeneousTuple
: TupleCollect
{}
impl<T: TupleCollect> HomogeneousTuple for T {}
/// An iterator over a incomplete tuple. /// /// See [`.tuples()`](crate::Itertools::tuples) and /// [`Tuples::into_buffer()`]. #[derive(Clone, Debug)] pubstruct TupleBuffer<T> where T: HomogeneousTuple
{
cur: usize,
buf: T::Buffer,
}
fn size_hint(&self) -> (usize, Option<usize>) { let buffer = &self.buf.as_ref()[self.cur..]; let len = if buffer.is_empty() { 0
} else {
buffer.iter()
.position(|x| x.is_none())
.unwrap_or_else(|| buffer.len())
};
(len, Some(len))
}
}
impl<T> ExactSizeIterator for TupleBuffer<T> where T: HomogeneousTuple
{
}
/// An iterator that groups the items in tuples of a specific size. /// /// See [`.tuples()`](crate::Itertools::tuples) for more information. #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pubstruct Tuples<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple
{
iter: Fuse<I>,
buf: T::Buffer,
}
/// Create a new tuples iterator. pubfn tuples<I, T>(iter: I) -> Tuples<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple
{
Tuples {
iter: iter.fuse(),
buf: Default::default(),
}
}
impl<I, T> Iterator for Tuples<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple
{ type Item = T;
impl<I, T> Tuples<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple
{ /// Return a buffer with the produced items that was not enough to be grouped in a tuple. /// /// ``` /// use itertools::Itertools; /// /// let mut iter = (0..5).tuples(); /// assert_eq!(Some((0, 1, 2)), iter.next()); /// assert_eq!(None, iter.next()); /// itertools::assert_equal(vec![3, 4], iter.into_buffer()); /// ``` pubfn into_buffer(self) -> TupleBuffer<T> {
TupleBuffer::new(self.buf)
}
}
/// An iterator over all contiguous windows that produces tuples of a specific size. /// /// See [`.tuple_windows()`](crate::Itertools::tuple_windows) for more /// information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Clone, Debug)] pubstruct TupleWindows<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple
{
iter: I,
last: Option<T>,
}
/// Create a new tuple windows iterator. pubfn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple,
T::Item: Clone
{ use std::iter::once;
letmut last = None; if T::num_items() != 1 { // put in a duplicate item in front of the tuple; this simplifies // .next() function. iflet Some(item) = iter.next() { let iter = once(item.clone()).chain(once(item)).chain(&mut iter);
last = T::collect_from_iter_no_buf(iter);
}
}
TupleWindows {
iter,
last,
}
}
impl<I, T> Iterator for TupleWindows<I, T> where I: Iterator<Item = T::Item>,
T: HomogeneousTuple + Clone,
T::Item: Clone
{ type Item = T;
impl<I, T> FusedIterator for TupleWindows<I, T> where I: FusedIterator<Item = T::Item>,
T: HomogeneousTuple + Clone,
T::Item: Clone
{}
/// An iterator over all windows,wrapping back to the first elements when the /// window would otherwise exceed the length of the iterator, producing tuples /// of a specific size. /// /// See [`.circular_tuple_windows()`](crate::Itertools::circular_tuple_windows) for more /// information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Debug)] pubstruct CircularTupleWindows<I, T: Clone> where I: Iterator<Item = T::Item> + Clone,
T: TupleCollect + Clone
{
iter: Take<TupleWindows<Cycle<I>, T>>,
phantom_data: PhantomData<T>
}
pubfn circular_tuple_windows<I, T>(iter: I) -> CircularTupleWindows<I, T> where I: Iterator<Item = T::Item> + Clone + ExactSizeIterator,
T: TupleCollect + Clone,
T::Item: Clone
{ let len = iter.len(); let iter = tuple_windows(iter.cycle()).take(len);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.