peek-again 0.2.0

A performant iterator providing double peek functionality.
Documentation
A performant iterator providing double peek functionality.

This crate provides a [`Peekable`](https://docs.rs/peek_again/latest/peek_again/struct.Peekable.html) 
iterator adapter that allows looking ahead by up to two elements without advancing the 
iterator. It maintains performance parity with [`core::iter::Peekable`](https://doc.rust-lang.org/core/iter/struct.Peekable.html) 
for most single peek operations as well as `next` invocations.

# Key Features

- **Double Peek**: Look ahead by up to two elements while maintaining iterator position.
- **Performance**: Most single peek operations are as fast as `core::iter::Peekable`.
- **Greater Control**: Enhanced functionality for conditional iteration and element consumption.

# Basic Usage

```rust
use peek_again::Peekable;

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

assert_eq!(iter.peek(), 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`](https://docs.rs/peek_again/latest/peek_again/struct.Peek.html) type returned by 
[`peek`](https://docs.rs/peek_again/latest/peek_again/struct.Peekable.html#method.peek) provides 
additional control over iteration:

```rust
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`](https://docs.rs/peek_again/latest/peek_again/struct.Peek.html#method.drain_if) method 
allows consuming multiple elements based on lookahead:

```rust
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);
        }
    );
```

# Safety

This crate is marked with `#![forbid(unsafe_code)]` and employs design by contract 
principles, making the property tests far more meaningful. These contracts are also
checked via `kani`.

This crate does have an `allow-unsafe` feature flag, this is not enabled by default,
when enabled this crate will use `core::hint::unreachable_unchecked` for states 
that are guaranteed to be unreachable, offering a 15% performance improvement for 
certain operations.