peek-again

Crates.iopeek-again
lib.rspeek-again
version0.1.1
sourcesrc
created_at2024-11-09 02:27:55.802859
updated_at2024-11-09 20:59:53.771626
descriptionA performant iterator providing double peek functionality.
homepagehttps://github.com/CleveGreen/peek-again
repositoryhttps://github.com/CleveGreen/peek-again
max_upload_size
id1441774
size66,959
Cleve Green (CleveGreen)

documentation

https://docs.rs/peek_again/latest/peek_again

README

A performant iterator providing double peek functionality.

This crate provides a Peekable iterator adapter that allows looking ahead by up to two elements without advancing the iterator. It maintains performance parity with core::iter::Peekable for single peek operations, with only a minimal 90 picosecond overhead for double peek operations.

Key Features

  • Double Peek: Look ahead by up to two elements while maintaining iterator position.
  • Performance: Single peek operations are as fast or faster than core::iter::Peekable.
  • Greater Control: Enhanced functionality for conditional iteration and element consumption.

Basic Usage

use peek_again::Peekable;

let mut iter = Peekable::new([1, 2, 3].into_iter());

assert_eq!(iter.peek().get(), Some(&1));  // Look at next element
assert_eq!(iter.peek_2(), Some(&2));      // Look two elements ahead
assert_eq!(iter.next(), Some(1));         // Iterator position unchanged

Enhanced Peek Control

The Peek type returned by peek provides additional control over iteration:

# use peek_again::Peekable;
let mut iter = Peekable::new([1, 2, 3].into_iter());
let mut peek = iter.peek();

// Examine current and next elements
assert_eq!(peek, Some(&1));
assert_eq!(peek.peek(), Some(&2));

// Conditionally consume elements (moving the iterator forward)
if peek == Some(&1) {
    assert_eq!(peek.consume(), Some(1));
}

Conditional Draining

The drain_if method allows consuming multiple elements based on lookahead:

# use peek_again::Peekable;
let mut iter = Peekable::new([1, 2, 3].into_iter());
let peek = iter.peek();

peek.drain_if(|&next| next == 2)
    .map_or_else(
        |_peek| unreachable!("The second element is two."),
        |(curr, next)| {
            assert_eq!(curr, Some(1));
            assert_eq!(next, 2);
        }
    );

Performance Considerations

  • Single peek operations (peek()) are optimized to match or exceed the performance of core::iter::Peekable.
  • Double peek operations (peek_2()) incur only a 90 picosecond overhead compared to single peek operations.
  • State transitions and element storage are designed to minimize memory operations.

Safety

This crate is marked with #![forbid(unsafe_code)] and employs design by contract principles, making the property tests far more meaningful.

Commit count: 7

cargo fmt