diff --git a/src/iter.rs b/src/iter.rs index 4c26a8f..fb54567 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -31,11 +31,11 @@ pub trait NonEmptyIterator { /// Each `NonEmptyIterator` knows about a possibly-empty variant of itself, /// likely from `std`. Critically, they share an `Item`. - type Iter: Iterator; + type IntoIter: IntoIterator; /// A `NonEmptyIterator` can, by consuming itself, reliably produce its /// first element, alongside its possibly-empty variant. - fn first(self) -> (Self::Item, Self::Iter); + fn first(self) -> (Self::Item, Self::IntoIter); /// Advances the iterator and returns the next value. /// @@ -201,7 +201,17 @@ pub trait NonEmptyIterator { // Differs from the implementation of `Iterator::count` to absolutely // ensure that `count` returns at least 1. let (_, rest) = self.first(); - 1 + rest.count() + 1 + rest.into_iter().count() + } + + /// Repeats a non-empty iterator endlessly. + /// + /// See also [`Iterator::cycle`]. + fn cycle(self) -> Cycle + where + Self: Sized + Clone, + { + Cycle::new(self) } /// Creates a non-empty iterator which gives the current iteration count as @@ -450,14 +460,14 @@ where { type Item = U; - type Iter = std::iter::Map; + type IntoIter = std::iter::Map<::IntoIter, F>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { let (i, iter) = self.iter.first(); let mut fun = self.f; // Reconstruct the `Map` we broke open. - (fun(i), iter.map(fun)) + (fun(i), iter.into_iter().map(fun)) } fn next(&mut self) -> Option { @@ -498,12 +508,12 @@ where { type Item = T; - type Iter = std::iter::Cloned; + type IntoIter = std::iter::Cloned<::IntoIter>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { let (i, iter) = self.iter.first(); - (i.clone(), iter.cloned()) + (i.clone(), iter.into_iter().cloned()) } fn next(&mut self) -> Option { @@ -539,12 +549,12 @@ where { type Item = (usize, I::Item); - type Iter = std::iter::Enumerate; + type IntoIter = std::iter::Enumerate<::IntoIter>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { let (head, rest) = self.iter.first(); - ((0, head), rest.enumerate()) + ((0, head), rest.into_iter().enumerate()) } fn next(&mut self) -> Option { @@ -582,15 +592,15 @@ where { type Item = I::Item; - type Iter = std::iter::Take; + type IntoIter = std::iter::Take<::IntoIter>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { let (head, rest) = self.iter.first(); if self.n < 2 { - (head, rest.take(0)) + (head, rest.into_iter().take(0)) } else { - (head, rest.take(self.n - 1)) + (head, rest.into_iter().take(self.n - 1)) } } @@ -630,12 +640,12 @@ where { type Item = A::Item; - type Iter = std::iter::Chain; + type IntoIter = std::iter::Chain<::IntoIter, B>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { let (head, a_rest) = self.a.first(); - (head, a_rest.chain(self.b)) + (head, a_rest.into_iter().chain(self.b)) } fn next(&mut self) -> Option { @@ -676,9 +686,9 @@ where { type Item = T; - type Iter = std::option::IntoIter; + type IntoIter = std::option::IntoIter; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { (self.once, None.into_iter()) } @@ -718,12 +728,12 @@ where { type Item = T; - type Iter = std::iter::Copied; + type IntoIter = std::iter::Copied<::IntoIter>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { let (head, rest) = self.iter.first(); - (head.clone(), rest.copied()) + (head.clone(), rest.into_iter().copied()) } fn next(&mut self) -> Option { @@ -744,3 +754,52 @@ where self.iter.into_iter().copied() } } + +/// An iterator that repeats endlessly. +/// +/// See also [`std::iter::Cycle`]. +pub struct Cycle { + orig: I, + iter: I, +} + +impl Cycle { + fn new(iter: I) -> Self { + Self { + orig: iter.clone(), + iter, + } + } +} + +impl NonEmptyIterator for Cycle +where + I: NonEmptyIterator, + Self: IntoIterator, +{ + type Item = T; + + type IntoIter = Self; + + fn first(self) -> (Self::Item, Self::IntoIter) { + todo!() + } + + fn next(&mut self) -> Option { + todo!() + } +} + +impl IntoIterator for Cycle +where + I: IntoIterator, + J: Clone + Iterator, +{ + type Item = T; + + type IntoIter = std::iter::Cycle; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} diff --git a/src/set.rs b/src/set.rs index a6e0a92..d0c5551 100644 --- a/src/set.rs +++ b/src/set.rs @@ -464,9 +464,9 @@ impl<'a, T> IntoIterator for &'a NESet { impl<'a, T> NonEmptyIterator for Iter<'a, T> { type Item = &'a T; - type Iter = Skip, std::collections::hash_set::Iter<'a, T>>>; + type IntoIter = Skip, std::collections::hash_set::Iter<'a, T>>>; - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { (self.head, self.iter.skip(1)) } @@ -513,7 +513,7 @@ where { type Item = &'a T; - type Iter = std::collections::hash_set::Union<'a, T, S>; + type IntoIter = std::collections::hash_set::Union<'a, T, S>; fn next(&mut self) -> Option { match self.orig_iter.next() { @@ -527,7 +527,7 @@ where } } - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { (&self.orig.head, self.orig.tail.union(&self.other.tail)) } diff --git a/src/vector.rs b/src/vector.rs index 3c92a58..06d25b8 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -822,13 +822,13 @@ pub struct Iter<'a, T: 'a> { impl<'a, T> NonEmptyIterator for Iter<'a, T> { type Item = &'a T; - type Iter = Skip, std::slice::Iter<'a, T>>>; + type IntoIter = Skip, std::slice::Iter<'a, T>>>; fn next(&mut self) -> Option { self.iter.next() } - fn first(self) -> (Self::Item, Self::Iter) { + fn first(self) -> (Self::Item, Self::IntoIter) { (self.head, self.iter.skip(1)) } }