#iterator #peekable #iterator-adapter #peek #lookahead #no-alloc #no-std

no-std double-ended-peekable

An adapter providing peeking features to double-ended iterators

4 releases

0.1.0 Jan 28, 2024
0.1.0-alpha.1 Mar 24, 2023
0.0.2 Mar 12, 2023
0.0.1 Mar 12, 2023

#357 in Algorithms

34 downloads per month

MIT license

45KB
724 lines

Double-Ended Peekable

version checks docs coverage licence

A very small crate providing an additional abstraction over Iterator, in order to lift the concepts introduced by Peekable over DoubleEndedIterator.

The reason

With Peekable you can use peek in order to get a reference to the upcoming element from the iterator, and you can also use next_if/next_if_eq in order to advance the iterator only when the upcoming element satisfies some conditions.

However, this abstraction does not work well when you need to perform these operations from both the start and the end of a double-ended iterator. For instance, you cannot just do .by_ref().rev().peekable().peek().next() on the fly, because even if this approach seems to work, the implementation need to store the next element (the corresponding of next_back, to be clearer) inside the instance of Peekable, which means that the peeked element is going to be dropped using the snippet just shown.

How to use

You just need to import the extension trait DoubleEndedPeekableExt in order to easily use the double_ended_peekable:

use double_ended_peekable::DoubleEndedPeekableExt;
                                                                    
let mut iter = [0, 1, 2, 3, 4].into_iter().double_ended_peekable();
assert_eq!(
    iter.next_front_back_if(|a, b| a % 2 == 0 && b % 2 == 0),
    Some((0, 4))
);
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next_back(), Some(3));
assert_eq!(iter.peek(), Some(&2));
assert_eq!(iter.peek_back(), Some(&2));
assert_eq!(iter.next_front_back_if_eq(&2, &2), None);
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);

Keep in mind that DoubleEndedPeekableExt is implemented for every Iterator, but some of the methods of DoubleEndedPeekable are only implemented for types that implement DoubleEndedIterator.

Features

  • All the abstractions from Peekable.

  • The *_back_* variants of the methods provided by Peekable:

    All these methods work like their front version, except they operate from the end to the beginning of the iterator (just like DoubleEndedIterator does).

  • next_front_back_if: it advances both forward and backward sides of the iterator if a condition is satisfied. The condition is expressed by a function that takes a reference to the next and the next-back elements and it returns a boolean, which indicates whether the sides of the iterator need to be advanced.

  • next_front_back_if_eq: similar to next_front_back_if, except it directly takes the references to the next and the next-back elements instead of a function.

No runtime deps