Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 83 additions & 24 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Item = Self::Item>;
type IntoIter: IntoIterator<Item = Self::Item>;

/// 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.
///
Expand Down Expand Up @@ -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<Self>
where
Self: Sized + Clone,
{
Cycle::new(self)
}

/// Creates a non-empty iterator which gives the current iteration count as
Expand Down Expand Up @@ -450,14 +460,14 @@ where
{
type Item = U;

type Iter = std::iter::Map<I::Iter, F>;
type IntoIter = std::iter::Map<<I::IntoIter as IntoIterator>::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<Self::Item> {
Expand Down Expand Up @@ -498,12 +508,12 @@ where
{
type Item = T;

type Iter = std::iter::Cloned<I::Iter>;
type IntoIter = std::iter::Cloned<<I::IntoIter as IntoIterator>::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<Self::Item> {
Expand Down Expand Up @@ -539,12 +549,12 @@ where
{
type Item = (usize, I::Item);

type Iter = std::iter::Enumerate<I::Iter>;
type IntoIter = std::iter::Enumerate<<I::IntoIter as IntoIterator>::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<Self::Item> {
Expand Down Expand Up @@ -582,15 +592,15 @@ where
{
type Item = I::Item;

type Iter = std::iter::Take<I::Iter>;
type IntoIter = std::iter::Take<<I::IntoIter as IntoIterator>::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))
}
}

Expand Down Expand Up @@ -630,12 +640,12 @@ where
{
type Item = A::Item;

type Iter = std::iter::Chain<A::Iter, B>;
type IntoIter = std::iter::Chain<<A::IntoIter as IntoIterator>::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<Self::Item> {
Expand Down Expand Up @@ -676,9 +686,9 @@ where
{
type Item = T;

type Iter = std::option::IntoIter<T>;
type IntoIter = std::option::IntoIter<T>;

fn first(self) -> (Self::Item, Self::Iter) {
fn first(self) -> (Self::Item, Self::IntoIter) {
(self.once, None.into_iter())
}

Expand Down Expand Up @@ -718,12 +728,12 @@ where
{
type Item = T;

type Iter = std::iter::Copied<I::Iter>;
type IntoIter = std::iter::Copied<<I::IntoIter as IntoIterator>::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<Self::Item> {
Expand All @@ -744,3 +754,52 @@ where
self.iter.into_iter().copied()
}
}

/// An iterator that repeats endlessly.
///
/// See also [`std::iter::Cycle`].
pub struct Cycle<I> {
orig: I,
iter: I,
}

impl<I: Clone> Cycle<I> {
fn new(iter: I) -> Self {
Self {
orig: iter.clone(),
iter,
}
}
}

impl<I, T> NonEmptyIterator for Cycle<I>
where
I: NonEmptyIterator<Item = T>,
Self: IntoIterator<Item = T>,
{
type Item = T;

type IntoIter = Self;

fn first(self) -> (Self::Item, Self::IntoIter) {
todo!()
}

fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}

impl<I, J, T> IntoIterator for Cycle<I>
where
I: IntoIterator<Item = T, IntoIter = J>,
J: Clone + Iterator<Item = T>,
{
type Item = T;

type IntoIter = std::iter::Cycle<I::IntoIter>;

fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
8 changes: 4 additions & 4 deletions src/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,9 @@ impl<'a, T> IntoIterator for &'a NESet<T> {
impl<'a, T> NonEmptyIterator for Iter<'a, T> {
type Item = &'a T;

type Iter = Skip<Chain<Once<&'a T>, std::collections::hash_set::Iter<'a, T>>>;
type IntoIter = Skip<Chain<Once<&'a T>, 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))
}

Expand Down Expand Up @@ -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<Self::Item> {
match self.orig_iter.next() {
Expand All @@ -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))
}

Expand Down
4 changes: 2 additions & 2 deletions src/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Chain<Once<&'a T>, std::slice::Iter<'a, T>>>;
type IntoIter = Skip<Chain<Once<&'a T>, std::slice::Iter<'a, T>>>;

fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}

fn first(self) -> (Self::Item, Self::Iter) {
fn first(self) -> (Self::Item, Self::IntoIter) {
(self.head, self.iter.skip(1))
}
}
Expand Down