size_hinter
Iterator adaptors for overriding or specifying exact size hints in Rust.
Overview
size_hinter provides two iterator adaptors, an extension trait, and a foundational type for working with iterator size hints.
SizeHint: An immutable type representing a size hint with strong guarantees about bounds validity (lower <= upper), providing additional functionality and conversions.ExactLen: Wraps an iterator to provide an exact length viaExactSizeIterator::len()and a corespondingIterator::size_hint(). This is useful when you know the exact length of an iterator that doesn't normally implementExactSizeIterator(likeFilter).HintSize: Wraps anIteratorin an adaptor that provides a customIterator::size_hint()implementation only. This is primarily useful for implementing a fixed universal size hint(0, None)for testing.TestIterator: An test iterator that can not be iterated over, but has an arbitrary size hint.InvalidIterator: An iterator that reports an invalid size hint(lower > upper).SizeHinter: An extension trait for fluently creating these adaptors.
This crate is no_std compatible and contains no unsafe code.
Installation
It's on crates.io.
Usage
ExactLen - Adding Exact Length to Iterators
ExactLen provides an exact length via ExactSizeIterator::len() and a coresponding Iterator::size_hint(). This is useful when you know the exact length of an iterator that doesn't normally implement ExactSizeIterator (like Filter), and may allow for some performance optimizations.
use SizeHinter;
// Filter doesn't implement ExactSizeIterator, but we know there are 3 odd numbers
let mut nums = .filter.exact_len;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
HintSize - Overrides Size Hints
HintSize provides a custom Iterator::size_hint() implementation. This is primarily useful for implementing a fixed universal size hint (0, None) for testing, but any valid size hint can be provided.
use SizeHinter;
// Hide the size hint completely (returns (0, None))
let mut hidden = vec!.into_iter.hide_size;
assert_eq!;
assert_eq!;
assert_eq!;
// Provide a custom size hint
let mut custom = vec!.into_iter.hint_size;
assert_eq!;
assert_eq!;
assert_eq!;
SizeHint - Working with Size Hints Directly
SizeHint is a type-safe wrapper around the standard iterator size hint tuple (usize, Option<usize>). It provides strong guarantees about bound validity and offers additional functionality for working with size hints.
use SizeHint;
// Create a bounded size hint (min 2, max 10 elements)
let hint = bounded;
assert_eq!;
assert_eq!;
// Create an exact size hint
let exact = exact;
assert_eq!;
assert_eq!;
// Create an unbounded size hint (at least 3 elements, no upper limit)
let unbounded = unbounded;
assert_eq!;
assert_eq!;
// Check if two size hints overlap
assert!;
assert!;
Adaptor Performance Considerations
Wrapping an iterator that does not provide a detailed size hint or implement ExactSizeIterator may allow for some optimizations or performance improvements. However, it may lead to performance penalties if the wrapped iterator already implements TrustedLen, even if it does not implement ExactSizeIterator. For example, std::iter::Chain. Since this adaptor hides that implementation.
Safety
ExactLen and HintSize are always safe to use - they will never cause undefined behavior or memory unsafety, regardless of the values provided.
Both adaptors validate that provided hints/lengths are logical (lower bound <= upper bound) and don't contradict the wrapped iterator's stated bounds. An adaptor can provide a hint or length that introduces new information, such as a new lower bound that is higher than provided one, but cannot claim a new lower bound higher than the wrapped iterator's max bound (if present).
It is still the caller's responsibility to ensure that the provided hints/lengths are accurate. Inaccurate values may prevent optimizations or cause issues in code that relies on these values for allocation or other decisions.