Skip to content

Commit

Permalink
feat(corelib): Iterator::advance_by
Browse files Browse the repository at this point in the history
  • Loading branch information
MagisterDallis committed Jan 12, 2025
1 parent a15f9b0 commit a779289
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
40 changes: 40 additions & 0 deletions corelib/src/iter/traits/iterator.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,44 @@ pub trait Iterator<T> {
/// assert_eq!(Option::None, iter.next());
/// ```
fn next(ref self: T) -> Option<Self::Item>;

/// Advances the iterator by `n` elements.
///
/// This method will eagerly skip `n` elements by calling [`next`] up to `n`
/// times until [`None`] is encountered.
///
/// `advance_by(n)` will return `Ok(())` if the iterator successfully advances by
/// `n` elements, or a `Err(NonZero<usize>)` with value `k` if [`None`] is encountered,
/// where `k` is remaining number of steps that could not be advanced because the iterator ran
/// out.
/// If `self` is empty and `n` is non-zero, then this returns `Err(n)`.
/// Otherwise, `k` is always less than `n`.
///
/// [`None`]: Option::None
/// [`next`]: Iterator::next
///
/// # Examples
///
/// ```
/// let mut iter = array![1_u8, 2, 3, 4].into_iter();
///
/// assert_eq!(iter.advance_by(2), Result::Ok(()));
/// assert_eq!(iter.next(), Option::Some(3));
/// assert_eq!(iter.advance_by(0), Result::Ok(()));
/// assert_eq!(iter.advance_by(100), Result::Err(99));
/// ```
fn advance_by<+Destruct<T>, +Drop<Self::Item>>(
ref self: T, n: usize,
) -> Result<
(), NonZero<usize>,
> {
let mut res = Result::Ok(());
for i in 0..n {
if Self::next(ref self).is_none() {
res = Result::Err((n - i).try_into().unwrap());
break;
}
};
res
}
}
1 change: 1 addition & 0 deletions corelib/src/test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod felt_test;
mod fmt_test;
mod hash_test;
mod integer_test;
mod iter_test;
mod keccak_test;
mod math_test;
mod nullable_test;
Expand Down
9 changes: 9 additions & 0 deletions corelib/src/test/iter_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[test]
fn test_advance_by() {
let mut iter = array![1_u8, 2, 3, 4].into_iter();

assert_eq!(iter.advance_by(2), Result::Ok(()));
assert_eq!(iter.next(), Option::Some(3));
assert_eq!(iter.advance_by(0), Result::Ok(()));
assert_eq!(iter.advance_by(100), Result::Err(99));
}

0 comments on commit a779289

Please sign in to comment.