Change advance(_back)_by to return usize instead of Result<(), usize>

A successful advance is now signalled by returning `0` and other values now represent the remaining number
of steps that couldn't be advanced as opposed to the amount of steps that have been advanced during a partial advance_by.

This simplifies adapters a bit, replacing some `match`/`if` with arithmetic. Whether this is beneficial overall depends
on whether `advance_by` is mostly used as a building-block for other iterator methods and adapters or whether
we also see uses by users where `Result` might be more useful.
This commit is contained in:
The 8472
2021-12-26 03:21:54 +01:00
parent 7a0600714a
commit 69db91b8b2
30 changed files with 313 additions and 350 deletions

View File

@@ -284,12 +284,11 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
self.next_back()
}
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
let original_len = self.len();
fn advance_by(&mut self, n: usize) -> usize {
// This also moves the start, which marks them as conceptually "dropped",
// so if anything goes bad then our drop impl won't double-free them.
let range_to_drop = self.alive.take_prefix(n);
let remaining = n - range_to_drop.len();
// SAFETY: These elements are currently initialized, so it's fine to drop them.
unsafe {
@@ -297,7 +296,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
}
if n > original_len { Err(original_len) } else { Ok(()) }
remaining
}
}
@@ -334,12 +333,11 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
})
}
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
let original_len = self.len();
fn advance_back_by(&mut self, n: usize) -> usize {
// This also moves the end, which marks them as conceptually "dropped",
// so if anything goes bad then our drop impl won't double-free them.
let range_to_drop = self.alive.take_suffix(n);
let remaining = n - range_to_drop.len();
// SAFETY: These elements are currently initialized, so it's fine to drop them.
unsafe {
@@ -347,7 +345,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
}
if n > original_len { Err(original_len) } else { Ok(()) }
remaining
}
}