replace advance_by returning usize with Result<(), NonZeroUsize>
This commit is contained in:
parent
69db91b8b2
commit
e29b27b4a4
31 changed files with 340 additions and 271 deletions
|
@ -1,4 +1,5 @@
|
|||
use core::iter::{FusedIterator, TrustedLen};
|
||||
use core::num::NonZeroUsize;
|
||||
use core::{array, fmt, mem::MaybeUninit, ops::Try, ptr};
|
||||
|
||||
use crate::alloc::{Allocator, Global};
|
||||
|
@ -54,15 +55,16 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
if self.inner.len < n {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let rem = if self.inner.len < n {
|
||||
let len = self.inner.len;
|
||||
self.inner.clear();
|
||||
len - n
|
||||
} else {
|
||||
self.inner.drain(..n);
|
||||
0
|
||||
}
|
||||
};
|
||||
NonZeroUsize::new(rem).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -182,15 +184,16 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let len = self.inner.len;
|
||||
if len >= n {
|
||||
let rem = if len >= n {
|
||||
self.inner.truncate(len - n);
|
||||
0
|
||||
} else {
|
||||
self.inner.clear();
|
||||
n - len
|
||||
}
|
||||
};
|
||||
NonZeroUsize::new(rem).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
fn try_rfold<B, F, R>(&mut self, mut init: B, mut f: F) -> R
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
||||
use core::num::NonZeroUsize;
|
||||
use core::ops::Try;
|
||||
use core::{fmt, mem, slice};
|
||||
|
||||
|
@ -55,13 +56,15 @@ impl<'a, T> Iterator for Iter<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let remaining = self.i1.advance_by(n);
|
||||
if remaining == 0 {
|
||||
return 0;
|
||||
match remaining {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(n) => {
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i1.advance_by(n.get())
|
||||
}
|
||||
}
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i1.advance_by(remaining)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -125,13 +128,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
let remaining = self.i2.advance_back_by(n);
|
||||
if remaining == 0 {
|
||||
return 0;
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
match self.i2.advance_back_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(n) => {
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i2.advance_back_by(n.get())
|
||||
}
|
||||
}
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i2.advance_back_by(remaining)
|
||||
}
|
||||
|
||||
fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
||||
use core::num::NonZeroUsize;
|
||||
use core::ops::Try;
|
||||
use core::{fmt, mem, slice};
|
||||
|
||||
|
@ -47,13 +48,14 @@ impl<'a, T> Iterator for IterMut<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
let remaining = self.i1.advance_by(n);
|
||||
if remaining == 0 {
|
||||
return 0;
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
match self.i1.advance_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(remaining) => {
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i1.advance_by(remaining.get())
|
||||
}
|
||||
}
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i1.advance_by(remaining)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -117,13 +119,14 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
let remaining = self.i2.advance_back_by(n);
|
||||
if remaining == 0 {
|
||||
return 0;
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
match self.i2.advance_back_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(remaining) => {
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i2.advance_back_by(remaining.get())
|
||||
}
|
||||
}
|
||||
mem::swap(&mut self.i1, &mut self.i2);
|
||||
self.i2.advance_back_by(remaining)
|
||||
}
|
||||
|
||||
fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc
|
||||
|
|
|
@ -11,6 +11,7 @@ use core::iter::{
|
|||
};
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
|
||||
use core::num::NonZeroUsize;
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
use core::ops::Deref;
|
||||
use core::ptr::{self, NonNull};
|
||||
|
@ -213,7 +214,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let step_size = self.len().min(n);
|
||||
let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
|
||||
if T::IS_ZST {
|
||||
|
@ -227,7 +228,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
|||
unsafe {
|
||||
ptr::drop_in_place(to_drop);
|
||||
}
|
||||
n - step_size
|
||||
NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -310,7 +311,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let step_size = self.len().min(n);
|
||||
if T::IS_ZST {
|
||||
// SAFETY: same as for advance_by()
|
||||
|
@ -324,7 +325,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
|
|||
unsafe {
|
||||
ptr::drop_in_place(to_drop);
|
||||
}
|
||||
n - step_size
|
||||
NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use core::alloc::{Allocator, Layout};
|
||||
use core::assert_eq;
|
||||
use core::iter::IntoIterator;
|
||||
use core::num::NonZeroUsize;
|
||||
use core::ptr::NonNull;
|
||||
use std::alloc::System;
|
||||
use std::assert_matches::assert_matches;
|
||||
|
@ -1064,20 +1065,20 @@ fn test_into_iter_leak() {
|
|||
#[test]
|
||||
fn test_into_iter_advance_by() {
|
||||
let mut i = vec![1, 2, 3, 4, 5].into_iter();
|
||||
assert_eq!(i.advance_by(0), 0);
|
||||
assert_eq!(i.advance_back_by(0), 0);
|
||||
assert_eq!(i.advance_by(0), Ok(()));
|
||||
assert_eq!(i.advance_back_by(0), Ok(()));
|
||||
assert_eq!(i.as_slice(), [1, 2, 3, 4, 5]);
|
||||
|
||||
assert_eq!(i.advance_by(1), 0);
|
||||
assert_eq!(i.advance_back_by(1), 0);
|
||||
assert_eq!(i.advance_by(1), Ok(()));
|
||||
assert_eq!(i.advance_back_by(1), Ok(()));
|
||||
assert_eq!(i.as_slice(), [2, 3, 4]);
|
||||
|
||||
assert_eq!(i.advance_back_by(usize::MAX), usize::MAX - 3);
|
||||
assert_eq!(i.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 3).unwrap()));
|
||||
|
||||
assert_eq!(i.advance_by(usize::MAX), usize::MAX);
|
||||
assert_eq!(i.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap()));
|
||||
|
||||
assert_eq!(i.advance_by(0), 0);
|
||||
assert_eq!(i.advance_back_by(0), 0);
|
||||
assert_eq!(i.advance_by(0), Ok(()));
|
||||
assert_eq!(i.advance_back_by(0), Ok(()));
|
||||
|
||||
assert_eq!(i.len(), 0);
|
||||
}
|
||||
|
@ -1125,7 +1126,7 @@ fn test_into_iter_zst() {
|
|||
for _ in vec![C; 5].into_iter().rev() {}
|
||||
|
||||
let mut it = vec![C, C].into_iter();
|
||||
assert_eq!(it.advance_by(1), 0);
|
||||
assert_eq!(it.advance_by(1), Ok(()));
|
||||
drop(it);
|
||||
|
||||
let mut it = vec![C, C].into_iter();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Defines the `IntoIter` owned iterator for arrays.
|
||||
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::{
|
||||
fmt,
|
||||
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
|
||||
|
@ -284,7 +285,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
self.next_back()
|
||||
}
|
||||
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
// 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);
|
||||
|
@ -296,7 +297,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
|
||||
}
|
||||
|
||||
remaining
|
||||
NonZeroUsize::new(remaining).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,7 +334,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
|
|||
})
|
||||
}
|
||||
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
// 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);
|
||||
|
@ -345,7 +346,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
|
|||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
|
||||
}
|
||||
|
||||
remaining
|
||||
NonZeroUsize::new(remaining).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{NeverShortCircuit, Try};
|
||||
|
||||
/// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics.
|
||||
|
@ -26,7 +27,7 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
I::advance_by(self.0, n)
|
||||
}
|
||||
|
||||
|
@ -62,7 +63,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
I::advance_back_by(self.0, n)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::Try;
|
||||
|
||||
/// An iterator that links two iterators together, in a chain.
|
||||
|
@ -95,32 +96,32 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, mut n: usize) -> usize {
|
||||
fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
|
||||
if let Some(ref mut a) = self.a {
|
||||
n = a.advance_by(n);
|
||||
if n == 0 {
|
||||
return n;
|
||||
}
|
||||
n = match a.advance_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(k) => k.get(),
|
||||
};
|
||||
self.a = None;
|
||||
}
|
||||
|
||||
if let Some(ref mut b) = self.b {
|
||||
n = b.advance_by(n);
|
||||
return b.advance_by(n);
|
||||
// we don't fuse the second iterator
|
||||
}
|
||||
|
||||
n
|
||||
NonZeroUsize::new(n).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
|
||||
if let Some(ref mut a) = self.a {
|
||||
n = match a.advance_by(n) {
|
||||
0 => match a.next() {
|
||||
Ok(()) => match a.next() {
|
||||
None => 0,
|
||||
x => return x,
|
||||
},
|
||||
k => k,
|
||||
Err(k) => k.get(),
|
||||
};
|
||||
|
||||
self.a = None;
|
||||
|
@ -181,32 +182,32 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, mut n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
|
||||
if let Some(ref mut b) = self.b {
|
||||
n = b.advance_back_by(n);
|
||||
if n == 0 {
|
||||
return n;
|
||||
}
|
||||
n = match b.advance_back_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(k) => k.get(),
|
||||
};
|
||||
self.b = None;
|
||||
}
|
||||
|
||||
if let Some(ref mut a) = self.a {
|
||||
n = a.advance_back_by(n);
|
||||
return a.advance_back_by(n);
|
||||
// we don't fuse the second iterator
|
||||
}
|
||||
|
||||
n
|
||||
NonZeroUsize::new(n).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
|
||||
if let Some(ref mut b) = self.b {
|
||||
n = match b.advance_back_by(n) {
|
||||
0 => match b.next_back() {
|
||||
Ok(()) => match b.next_back() {
|
||||
None => 0,
|
||||
x => return x,
|
||||
},
|
||||
k => k,
|
||||
Err(k) => k.get(),
|
||||
};
|
||||
|
||||
self.b = None;
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::iter::adapters::{
|
|||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::mem::SizedTypeProperties;
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::Try;
|
||||
use crate::{array, ptr};
|
||||
|
||||
|
@ -89,7 +90,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.it.advance_by(n)
|
||||
}
|
||||
|
||||
|
@ -130,7 +131,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.it.advance_back_by(n)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::num::NonZeroUsize;
|
||||
use crate::{iter::FusedIterator, ops::Try};
|
||||
|
||||
/// An iterator that repeats endlessly.
|
||||
|
@ -81,22 +82,22 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
let mut n = self.iter.advance_by(n);
|
||||
if n == 0 {
|
||||
return n;
|
||||
}
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let mut n = match self.iter.advance_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(rem) => rem.get(),
|
||||
};
|
||||
|
||||
while n > 0 {
|
||||
self.iter = self.orig.clone();
|
||||
let rem = self.iter.advance_by(n);
|
||||
if rem == n {
|
||||
return n;
|
||||
}
|
||||
n = rem;
|
||||
n = match self.iter.advance_by(n) {
|
||||
Ok(()) => return Ok(()),
|
||||
e @ Err(rem) if rem.get() == n => return e,
|
||||
Err(rem) => rem.get(),
|
||||
};
|
||||
}
|
||||
|
||||
0
|
||||
NonZeroUsize::new(n).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
// No `fold` override, because `fold` doesn't make much sense for `Cycle`,
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::iter::adapters::{
|
|||
zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
|
||||
};
|
||||
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::Try;
|
||||
|
||||
/// An iterator that yields the current count and the element during iteration.
|
||||
|
@ -114,10 +115,14 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
let n = self.iter.advance_by(n);
|
||||
self.count += n;
|
||||
n
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let remaining = self.iter.advance_by(n);
|
||||
let advanced = match remaining {
|
||||
Ok(()) => n,
|
||||
Err(rem) => n - rem.get(),
|
||||
};
|
||||
self.count += advanced;
|
||||
remaining
|
||||
}
|
||||
|
||||
#[rustc_inherit_overflow_checks]
|
||||
|
@ -201,7 +206,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
// we do not need to update the count since that only tallies the number of items
|
||||
// consumed from the front. consuming items from the back can never reduce that.
|
||||
self.iter.advance_back_by(n)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::fmt;
|
||||
use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
/// An iterator that maps each element to an iterator, and yields the elements
|
||||
|
@ -75,7 +76,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.inner.advance_by(n)
|
||||
}
|
||||
|
||||
|
@ -120,7 +121,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.inner.advance_back_by(n)
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +237,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.inner.advance_by(n)
|
||||
}
|
||||
|
||||
|
@ -281,7 +282,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.inner.advance_back_by(n)
|
||||
}
|
||||
}
|
||||
|
@ -552,19 +553,19 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
|
||||
match iter.advance_by(n) {
|
||||
0 => ControlFlow::Break(()),
|
||||
remaining => ControlFlow::Continue(remaining),
|
||||
Ok(()) => ControlFlow::Break(()),
|
||||
Err(remaining) => ControlFlow::Continue(remaining.get()),
|
||||
}
|
||||
}
|
||||
|
||||
match self.iter_try_fold(n, advance) {
|
||||
ControlFlow::Continue(remaining) => remaining,
|
||||
_ => 0,
|
||||
ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,19 +643,19 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
|
||||
match iter.advance_back_by(n) {
|
||||
0 => ControlFlow::Break(()),
|
||||
remaining => ControlFlow::Continue(remaining),
|
||||
Ok(()) => ControlFlow::Break(()),
|
||||
Err(remaining) => ControlFlow::Continue(remaining.get()),
|
||||
}
|
||||
}
|
||||
|
||||
match self.iter_try_rfold(n, advance) {
|
||||
ControlFlow::Continue(remaining) => remaining,
|
||||
_ => 0,
|
||||
ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::Try;
|
||||
|
||||
/// A double-ended iterator with the direction inverted.
|
||||
|
@ -38,7 +39,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.iter.advance_back_by(n)
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.iter.advance_by(n)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::intrinsics::unlikely;
|
||||
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable};
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
/// An iterator that skips over `n` elements of `iter`.
|
||||
|
@ -128,21 +129,27 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_by(&mut self, mut n: usize) -> usize {
|
||||
fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
|
||||
let skip_inner = self.n;
|
||||
let skip_and_advance = skip_inner.saturating_add(n);
|
||||
|
||||
let remainder = self.iter.advance_by(skip_and_advance);
|
||||
let remainder = match self.iter.advance_by(skip_and_advance) {
|
||||
Ok(()) => 0,
|
||||
Err(n) => n.get(),
|
||||
};
|
||||
let advanced_inner = skip_and_advance - remainder;
|
||||
n -= advanced_inner.saturating_sub(skip_inner);
|
||||
self.n = self.n.saturating_sub(advanced_inner);
|
||||
|
||||
// skip_and_advance may have saturated
|
||||
if unlikely(remainder == 0 && n > 0) {
|
||||
n = self.iter.advance_by(n);
|
||||
n = match self.iter.advance_by(n) {
|
||||
Ok(()) => 0,
|
||||
Err(n) => n.get(),
|
||||
}
|
||||
}
|
||||
|
||||
n
|
||||
NonZeroUsize::new(n).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,13 +203,11 @@ where
|
|||
impl_fold_via_try_fold! { rfold -> try_rfold }
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let min = crate::cmp::min(self.len(), n);
|
||||
let rem = self.iter.advance_back_by(min);
|
||||
if rem != 0 {
|
||||
panic!("ExactSizeIterator contract violation");
|
||||
};
|
||||
n - min
|
||||
assert!(rem.is_ok(), "ExactSizeIterator contract violation");
|
||||
NonZeroUsize::new(n - min).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::cmp;
|
||||
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
/// An iterator that only iterates over the first `n` iterations of `iter`.
|
||||
|
@ -121,12 +122,15 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let min = self.n.min(n);
|
||||
let rem = self.iter.advance_by(min);
|
||||
let rem = match self.iter.advance_by(min) {
|
||||
Ok(()) => 0,
|
||||
Err(rem) => rem.get(),
|
||||
};
|
||||
let advanced = min - rem;
|
||||
self.n -= advanced;
|
||||
n - advanced
|
||||
NonZeroUsize::new(n - advanced).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +221,7 @@ where
|
|||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
// The amount by which the inner iterator needs to be shortened for it to be
|
||||
// at most as long as the take() amount.
|
||||
let trim_inner = self.iter.len().saturating_sub(self.n);
|
||||
|
@ -226,11 +230,14 @@ where
|
|||
// about having to advance more than usize::MAX here.
|
||||
let advance_by = trim_inner.saturating_add(n);
|
||||
|
||||
let remainder = self.iter.advance_back_by(advance_by);
|
||||
let remainder = match self.iter.advance_back_by(advance_by) {
|
||||
Ok(()) => 0,
|
||||
Err(rem) => rem.get(),
|
||||
};
|
||||
let advanced_by_inner = advance_by - remainder;
|
||||
let advanced_by = advanced_by_inner - trim_inner;
|
||||
self.n -= advanced_by;
|
||||
n - advanced_by
|
||||
NonZeroUsize::new(n - advanced_by).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::convert::TryFrom;
|
||||
use crate::marker::Destruct;
|
||||
use crate::mem;
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{self, Try};
|
||||
|
||||
use super::{
|
||||
|
@ -530,12 +531,12 @@ trait RangeIteratorImpl {
|
|||
// Iterator
|
||||
fn spec_next(&mut self) -> Option<Self::Item>;
|
||||
fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
|
||||
fn spec_advance_by(&mut self, n: usize) -> usize;
|
||||
fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>;
|
||||
|
||||
// DoubleEndedIterator
|
||||
fn spec_next_back(&mut self) -> Option<Self::Item>;
|
||||
fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>;
|
||||
fn spec_advance_back_by(&mut self, n: usize) -> usize;
|
||||
fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>;
|
||||
}
|
||||
|
||||
impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> {
|
||||
|
@ -567,7 +568,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A>
|
|||
}
|
||||
|
||||
#[inline]
|
||||
default fn spec_advance_by(&mut self, n: usize) -> usize {
|
||||
default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let available = if self.start <= self.end {
|
||||
Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
|
||||
} else {
|
||||
|
@ -579,7 +580,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A>
|
|||
self.start =
|
||||
Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld");
|
||||
|
||||
n - taken
|
||||
NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -608,7 +609,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A>
|
|||
}
|
||||
|
||||
#[inline]
|
||||
default fn spec_advance_back_by(&mut self, n: usize) -> usize {
|
||||
default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let available = if self.start <= self.end {
|
||||
Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
|
||||
} else {
|
||||
|
@ -620,7 +621,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A>
|
|||
self.end =
|
||||
Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld");
|
||||
|
||||
n - taken
|
||||
NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,7 +652,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn spec_advance_by(&mut self, n: usize) -> usize {
|
||||
fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let available = if self.start <= self.end {
|
||||
Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
|
||||
} else {
|
||||
|
@ -666,7 +667,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R
|
|||
// Otherwise 0 is returned which always safe to use.
|
||||
self.start = unsafe { Step::forward_unchecked(self.start.clone(), taken) };
|
||||
|
||||
n - taken
|
||||
NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -695,7 +696,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn spec_advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let available = if self.start <= self.end {
|
||||
Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX)
|
||||
} else {
|
||||
|
@ -707,7 +708,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R
|
|||
// SAFETY: same as the spec_advance_by() implementation
|
||||
self.end = unsafe { Step::backward_unchecked(self.end.clone(), taken) };
|
||||
|
||||
n - taken
|
||||
NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -757,7 +758,7 @@ impl<A: ~const Step + ~const Destruct> const Iterator for ops::Range<A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.spec_advance_by(n)
|
||||
}
|
||||
|
||||
|
@ -836,7 +837,7 @@ impl<A: ~const Step + ~const Destruct> const DoubleEndedIterator for ops::Range<
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.spec_advance_back_by(n)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
|
||||
/// Creates a new iterator that endlessly repeats a single element.
|
||||
///
|
||||
|
@ -80,10 +81,10 @@ impl<A: Clone> Iterator for Repeat<A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
// Advancing an infinite iterator of a single element is a no-op.
|
||||
let _ = n;
|
||||
0
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -109,10 +110,10 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
// Advancing an infinite iterator of a single element is a no-op.
|
||||
let _ = n;
|
||||
0
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::mem::ManuallyDrop;
|
||||
use crate::num::NonZeroUsize;
|
||||
|
||||
/// Creates a new iterator that repeats a single element a given number of times.
|
||||
///
|
||||
|
@ -137,7 +138,7 @@ impl<A: Clone> Iterator for RepeatN<A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, skip: usize) -> usize {
|
||||
fn advance_by(&mut self, skip: usize) -> Result<(), NonZeroUsize> {
|
||||
let len = self.count;
|
||||
|
||||
if skip >= len {
|
||||
|
@ -145,10 +146,11 @@ impl<A: Clone> Iterator for RepeatN<A> {
|
|||
}
|
||||
|
||||
if skip > len {
|
||||
skip - len
|
||||
// SAFETY: we just checked that the difference is positive
|
||||
Err(unsafe { NonZeroUsize::new_unchecked(skip - len) })
|
||||
} else {
|
||||
self.count = len - skip;
|
||||
0
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +180,7 @@ impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
self.advance_by(n)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::marker::Destruct;
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{ControlFlow, Try};
|
||||
|
||||
/// An iterator able to yield elements from both ends.
|
||||
|
@ -120,29 +121,31 @@ pub trait DoubleEndedIterator: Iterator {
|
|||
/// ```
|
||||
/// #![feature(iter_advance_by)]
|
||||
///
|
||||
/// use std::num::NonZeroUsize;
|
||||
/// let a = [3, 4, 5, 6];
|
||||
/// let mut iter = a.iter();
|
||||
///
|
||||
/// assert_eq!(iter.advance_back_by(2), 0);
|
||||
/// assert_eq!(iter.advance_back_by(2), Ok(()));
|
||||
/// assert_eq!(iter.next_back(), Some(&4));
|
||||
/// assert_eq!(iter.advance_back_by(0), 0);
|
||||
/// assert_eq!(iter.advance_back_by(100), 99); // only `&3` was skipped
|
||||
/// assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
/// assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(99).unwrap())); // only `&3` was skipped
|
||||
/// ```
|
||||
///
|
||||
/// [`Ok(())`]: Ok
|
||||
/// [`Err(k)`]: Err
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>
|
||||
where
|
||||
Self::Item: ~const Destruct,
|
||||
{
|
||||
for i in 0..n {
|
||||
if self.next_back().is_none() {
|
||||
return n - i;
|
||||
// SAFETY: `i` is always less than `n`.
|
||||
return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
|
||||
}
|
||||
}
|
||||
0
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the `n`th element from the end of the iterator.
|
||||
|
@ -190,7 +193,7 @@ pub trait DoubleEndedIterator: Iterator {
|
|||
#[stable(feature = "iter_nth_back", since = "1.37.0")]
|
||||
#[rustc_do_not_const_check]
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
if self.advance_back_by(n) > 0 {
|
||||
if self.advance_back_by(n).is_err() {
|
||||
return None;
|
||||
}
|
||||
self.next_back()
|
||||
|
@ -378,7 +381,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
|
|||
fn next_back(&mut self) -> Option<I::Item> {
|
||||
(**self).next_back()
|
||||
}
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
(**self).advance_back_by(n)
|
||||
}
|
||||
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::array;
|
||||
use crate::cmp::{self, Ordering};
|
||||
use crate::marker::Destruct;
|
||||
use crate::num::NonZeroUsize;
|
||||
use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
|
||||
|
||||
use super::super::try_process;
|
||||
|
@ -327,26 +328,28 @@ pub trait Iterator {
|
|||
/// ```
|
||||
/// #![feature(iter_advance_by)]
|
||||
///
|
||||
/// use std::num::NonZeroUsize;
|
||||
/// let a = [1, 2, 3, 4];
|
||||
/// let mut iter = a.iter();
|
||||
///
|
||||
/// assert_eq!(iter.advance_by(2), 0);
|
||||
/// assert_eq!(iter.advance_by(2), Ok(()));
|
||||
/// assert_eq!(iter.next(), Some(&3));
|
||||
/// assert_eq!(iter.advance_by(0), 0);
|
||||
/// assert_eq!(iter.advance_by(100), 99); // only `&4` was skipped
|
||||
/// assert_eq!(iter.advance_by(0), Ok(()));
|
||||
/// assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(99).unwrap())); // only `&4` was skipped
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
|
||||
fn advance_by(&mut self, n: usize) -> usize
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>
|
||||
where
|
||||
Self::Item: ~const Destruct,
|
||||
{
|
||||
for i in 0..n {
|
||||
if self.next().is_none() {
|
||||
return n - i;
|
||||
// SAFETY: `i` is always less than `n`.
|
||||
return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
|
||||
}
|
||||
}
|
||||
0
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the `n`th element of the iterator.
|
||||
|
@ -394,9 +397,7 @@ pub trait Iterator {
|
|||
where
|
||||
Self::Item: ~const Destruct,
|
||||
{
|
||||
if self.advance_by(n) > 0 {
|
||||
return None;
|
||||
}
|
||||
self.advance_by(n).ok()?;
|
||||
self.next()
|
||||
}
|
||||
|
||||
|
@ -4017,7 +4018,7 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
|
|||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(**self).size_hint()
|
||||
}
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
(**self).advance_by(n)
|
||||
}
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::intrinsics::{assert_unsafe_precondition, unchecked_add, unchecked_sub};
|
||||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::num::NonZeroUsize;
|
||||
|
||||
/// Like a `Range<usize>`, but with a safety invariant that `start <= end`.
|
||||
///
|
||||
|
@ -132,9 +133,9 @@ impl Iterator for IndexRange {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let taken = self.take_prefix(n);
|
||||
n - taken.len()
|
||||
NonZeroUsize::new(n - taken.len()).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,9 +151,9 @@ impl DoubleEndedIterator for IndexRange {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let taken = self.take_suffix(n);
|
||||
n - taken.len()
|
||||
NonZeroUsize::new(n - taken.len()).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -176,11 +176,11 @@ macro_rules! iterator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_by(&mut self, n: usize) -> usize {
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let advance = cmp::min(len!(self), n);
|
||||
// SAFETY: By construction, `advance` does not exceed `self.len()`.
|
||||
unsafe { self.post_inc_start(advance) };
|
||||
n - advance
|
||||
NonZeroUsize::new(n - advance).map_or(Ok(()), Err)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -371,11 +371,11 @@ macro_rules! iterator {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn advance_back_by(&mut self, n: usize) -> usize {
|
||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
|
||||
let advance = cmp::min(len!(self), n);
|
||||
// SAFETY: By construction, `advance` does not exceed `self.len()`.
|
||||
unsafe { self.pre_dec_end(advance) };
|
||||
n - advance
|
||||
NonZeroUsize::new(n - advance).map_or(Ok(()), Err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use core::{array, assert_eq};
|
||||
use core::convert::TryFrom;
|
||||
use core::num::NonZeroUsize;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
#[test]
|
||||
|
@ -535,17 +536,17 @@ fn array_intoiter_advance_by() {
|
|||
let mut it = IntoIterator::into_iter(a);
|
||||
|
||||
let r = it.advance_by(1);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 99);
|
||||
assert_eq!(counter.get(), 1);
|
||||
|
||||
let r = it.advance_by(0);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 99);
|
||||
assert_eq!(counter.get(), 1);
|
||||
|
||||
let r = it.advance_by(11);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 88);
|
||||
assert_eq!(counter.get(), 12);
|
||||
|
||||
|
@ -557,17 +558,17 @@ fn array_intoiter_advance_by() {
|
|||
assert_eq!(counter.get(), 13);
|
||||
|
||||
let r = it.advance_by(123456);
|
||||
assert_eq!(r, 123456 - 87);
|
||||
assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap()));
|
||||
assert_eq!(it.len(), 0);
|
||||
assert_eq!(counter.get(), 100);
|
||||
|
||||
let r = it.advance_by(0);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 0);
|
||||
assert_eq!(counter.get(), 100);
|
||||
|
||||
let r = it.advance_by(10);
|
||||
assert_eq!(r, 10);
|
||||
assert_eq!(r, Err(NonZeroUsize::new(10).unwrap()));
|
||||
assert_eq!(it.len(), 0);
|
||||
assert_eq!(counter.get(), 100);
|
||||
}
|
||||
|
@ -588,17 +589,17 @@ fn array_intoiter_advance_back_by() {
|
|||
let mut it = IntoIterator::into_iter(a);
|
||||
|
||||
let r = it.advance_back_by(1);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 99);
|
||||
assert_eq!(counter.get(), 1);
|
||||
|
||||
let r = it.advance_back_by(0);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 99);
|
||||
assert_eq!(counter.get(), 1);
|
||||
|
||||
let r = it.advance_back_by(11);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 88);
|
||||
assert_eq!(counter.get(), 12);
|
||||
|
||||
|
@ -610,17 +611,17 @@ fn array_intoiter_advance_back_by() {
|
|||
assert_eq!(counter.get(), 13);
|
||||
|
||||
let r = it.advance_back_by(123456);
|
||||
assert_eq!(r, 123456 - 87);
|
||||
assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap()));
|
||||
assert_eq!(it.len(), 0);
|
||||
assert_eq!(counter.get(), 100);
|
||||
|
||||
let r = it.advance_back_by(0);
|
||||
assert_eq!(r, 0);
|
||||
assert_eq!(r, Ok(()));
|
||||
assert_eq!(it.len(), 0);
|
||||
assert_eq!(counter.get(), 100);
|
||||
|
||||
let r = it.advance_back_by(10);
|
||||
assert_eq!(r, 10);
|
||||
assert_eq!(r, Err(NonZeroUsize::new(10).unwrap()));
|
||||
assert_eq!(it.len(), 0);
|
||||
assert_eq!(counter.get(), 100);
|
||||
}
|
||||
|
@ -679,8 +680,8 @@ fn array_into_iter_fold() {
|
|||
|
||||
let a = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = a.into_iter();
|
||||
assert_eq!(it.advance_by(1), 0);
|
||||
assert_eq!(it.advance_back_by(2), 0);
|
||||
assert_eq!(it.advance_by(1), Ok(()));
|
||||
assert_eq!(it.advance_back_by(2), Ok(()));
|
||||
let s = it.fold(10, |a, b| 10 * a + b);
|
||||
assert_eq!(s, 10234);
|
||||
}
|
||||
|
@ -695,8 +696,8 @@ fn array_into_iter_rfold() {
|
|||
|
||||
let a = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = a.into_iter();
|
||||
assert_eq!(it.advance_by(1), 0);
|
||||
assert_eq!(it.advance_back_by(2), 0);
|
||||
assert_eq!(it.advance_by(1), Ok(()));
|
||||
assert_eq!(it.advance_back_by(2), Ok(()));
|
||||
let s = it.rfold(10, |a, b| 10 * a + b);
|
||||
assert_eq!(s, 10432);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::*;
|
||||
use core::iter::*;
|
||||
use core::num::NonZeroUsize;
|
||||
|
||||
#[test]
|
||||
fn test_iterator_chain() {
|
||||
|
@ -31,28 +32,28 @@ fn test_iterator_chain_advance_by() {
|
|||
|
||||
for i in 0..xs.len() {
|
||||
let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
|
||||
assert_eq!(0, iter.advance_by(i));
|
||||
assert_eq!(iter.advance_by(i), Ok(()));
|
||||
assert_eq!(iter.next(), Some(&xs[i]));
|
||||
assert_eq!(iter.advance_by(100), 100 - (len - i - 1));
|
||||
assert_eq!(0, iter.advance_by(0));
|
||||
assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (len - i - 1)).unwrap()));
|
||||
assert_eq!(iter.advance_by(0), Ok(()));
|
||||
}
|
||||
|
||||
for i in 0..ys.len() {
|
||||
let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
|
||||
assert_eq!(iter.advance_by(xs.len() + i), 0);
|
||||
assert_eq!(iter.advance_by(xs.len() + i), Ok(()));
|
||||
assert_eq!(iter.next(), Some(&ys[i]));
|
||||
assert_eq!(iter.advance_by(100), 100 - (ys.len() - i - 1));
|
||||
assert_eq!(iter.advance_by(0), 0);
|
||||
assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (ys.len() - i - 1)).unwrap()));
|
||||
assert_eq!(iter.advance_by(0), Ok(()));
|
||||
}
|
||||
|
||||
let mut iter = xs.iter().chain(ys);
|
||||
assert_eq!(iter.advance_by(len), 0);
|
||||
assert_eq!(iter.advance_by(len), Ok(()));
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(iter.advance_by(0), 0);
|
||||
assert_eq!(iter.advance_by(0), Ok(()));
|
||||
|
||||
let mut iter = xs.iter().chain(ys);
|
||||
assert_eq!(iter.advance_by(len + 1), 1);
|
||||
assert_eq!(iter.advance_by(0), 0);
|
||||
assert_eq!(iter.advance_by(len + 1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!(iter.advance_by(0), Ok(()));
|
||||
}
|
||||
|
||||
test_chain(&[], &[]);
|
||||
|
@ -68,28 +69,28 @@ fn test_iterator_chain_advance_back_by() {
|
|||
|
||||
for i in 0..ys.len() {
|
||||
let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
|
||||
assert_eq!(iter.advance_back_by(i), 0);
|
||||
assert_eq!(iter.advance_back_by(i), Ok(()));
|
||||
assert_eq!(iter.next_back(), Some(&ys[ys.len() - i - 1]));
|
||||
assert_eq!(iter.advance_back_by(100), 100 - (len - i - 1));
|
||||
assert_eq!(iter.advance_back_by(0), 0);
|
||||
assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (len - i - 1)).unwrap()));
|
||||
assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
}
|
||||
|
||||
for i in 0..xs.len() {
|
||||
let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys));
|
||||
assert_eq!(iter.advance_back_by(ys.len() + i), 0);
|
||||
assert_eq!(iter.advance_back_by(ys.len() + i), Ok(()));
|
||||
assert_eq!(iter.next_back(), Some(&xs[xs.len() - i - 1]));
|
||||
assert_eq!(iter.advance_back_by(100), 100 - (xs.len() - i - 1));
|
||||
assert_eq!(iter.advance_back_by(0), 0);
|
||||
assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (xs.len() - i - 1)).unwrap()));
|
||||
assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
}
|
||||
|
||||
let mut iter = xs.iter().chain(ys);
|
||||
assert_eq!(iter.advance_back_by(len), 0);
|
||||
assert_eq!(iter.advance_back_by(len), Ok(()));
|
||||
assert_eq!(iter.next_back(), None);
|
||||
assert_eq!(iter.advance_back_by(0), 0);
|
||||
assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
|
||||
let mut iter = xs.iter().chain(ys);
|
||||
assert_eq!(iter.advance_back_by(len + 1), 1);
|
||||
assert_eq!(iter.advance_back_by(0), 0);
|
||||
assert_eq!(iter.advance_back_by(len + 1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
}
|
||||
|
||||
test_chain(&[], &[]);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use core::iter::*;
|
||||
use core::num::NonZeroUsize;
|
||||
|
||||
#[test]
|
||||
fn test_iterator_enumerate() {
|
||||
|
@ -55,6 +56,20 @@ fn test_iterator_enumerate_count() {
|
|||
assert_eq!(xs.iter().enumerate().count(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_enumerate_advance_by() {
|
||||
let xs = [0, 1, 2, 3, 4, 5];
|
||||
let mut it = xs.iter().enumerate();
|
||||
assert_eq!(it.advance_by(0), Ok(()));
|
||||
assert_eq!(it.next(), Some((0, &0)));
|
||||
assert_eq!(it.advance_by(1), Ok(()));
|
||||
assert_eq!(it.next(), Some((2, &2)));
|
||||
assert_eq!(it.advance_by(2), Ok(()));
|
||||
assert_eq!(it.next(), Some((5, &5)));
|
||||
assert_eq!(it.advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_enumerate_fold() {
|
||||
let xs = [0, 1, 2, 3, 4, 5];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use core::assert_eq;
|
||||
use super::*;
|
||||
use core::iter::*;
|
||||
use core::num::NonZeroUsize;
|
||||
|
||||
#[test]
|
||||
fn test_iterator_flatten() {
|
||||
|
@ -62,19 +63,19 @@ fn test_flatten_try_folds() {
|
|||
fn test_flatten_advance_by() {
|
||||
let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
|
||||
|
||||
assert_eq!(it.advance_by(5), 0);
|
||||
assert_eq!(it.advance_by(5), Ok(()));
|
||||
assert_eq!(it.next(), Some(5));
|
||||
assert_eq!(it.advance_by(9), 0);
|
||||
assert_eq!(it.advance_by(9), Ok(()));
|
||||
assert_eq!(it.next(), Some(15));
|
||||
assert_eq!(it.advance_back_by(4), 0);
|
||||
assert_eq!(it.advance_back_by(4), Ok(()));
|
||||
assert_eq!(it.next_back(), Some(35));
|
||||
assert_eq!(it.advance_back_by(9), 0);
|
||||
assert_eq!(it.advance_back_by(9), Ok(()));
|
||||
assert_eq!(it.next_back(), Some(25));
|
||||
|
||||
assert_eq!(it.advance_by(usize::MAX), usize::MAX - 9);
|
||||
assert_eq!(it.advance_back_by(usize::MAX), usize::MAX);
|
||||
assert_eq!(it.advance_by(0), 0);
|
||||
assert_eq!(it.advance_back_by(0), 0);
|
||||
assert_eq!(it.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 9).unwrap()));
|
||||
assert_eq!(it.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap()));
|
||||
assert_eq!(it.advance_by(0), Ok(()));
|
||||
assert_eq!(it.advance_back_by(0), Ok(()));
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
}
|
||||
|
||||
|
@ -175,19 +176,19 @@ fn test_flatten_count() {
|
|||
let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
|
||||
|
||||
assert_eq!(it.clone().count(), 40);
|
||||
assert_eq!(it.advance_by(5), 0);
|
||||
assert_eq!(it.advance_by(5), Ok(()));
|
||||
assert_eq!(it.clone().count(), 35);
|
||||
assert_eq!(it.advance_back_by(5), 0);
|
||||
assert_eq!(it.advance_back_by(5), Ok(()));
|
||||
assert_eq!(it.clone().count(), 30);
|
||||
assert_eq!(it.advance_by(10), 0);
|
||||
assert_eq!(it.advance_by(10), Ok(()));
|
||||
assert_eq!(it.clone().count(), 20);
|
||||
assert_eq!(it.advance_back_by(8), 0);
|
||||
assert_eq!(it.advance_back_by(8), Ok(()));
|
||||
assert_eq!(it.clone().count(), 12);
|
||||
assert_eq!(it.advance_by(4), 0);
|
||||
assert_eq!(it.advance_by(4), Ok(()));
|
||||
assert_eq!(it.clone().count(), 8);
|
||||
assert_eq!(it.advance_back_by(5), 0);
|
||||
assert_eq!(it.advance_back_by(5), Ok(()));
|
||||
assert_eq!(it.clone().count(), 3);
|
||||
assert_eq!(it.advance_by(3), 0);
|
||||
assert_eq!(it.advance_by(3), Ok(()));
|
||||
assert_eq!(it.clone().count(), 0);
|
||||
}
|
||||
|
||||
|
@ -196,18 +197,18 @@ fn test_flatten_last() {
|
|||
let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten();
|
||||
|
||||
assert_eq!(it.clone().last(), Some(39));
|
||||
assert_eq!(it.advance_by(5), 0); // 5..40
|
||||
assert_eq!(it.advance_by(5), Ok(())); // 5..40
|
||||
assert_eq!(it.clone().last(), Some(39));
|
||||
assert_eq!(it.advance_back_by(5), 0); // 5..35
|
||||
assert_eq!(it.advance_back_by(5), Ok(())); // 5..35
|
||||
assert_eq!(it.clone().last(), Some(34));
|
||||
assert_eq!(it.advance_by(10), 0); // 15..35
|
||||
assert_eq!(it.advance_by(10), Ok(())); // 15..35
|
||||
assert_eq!(it.clone().last(), Some(34));
|
||||
assert_eq!(it.advance_back_by(8), 0); // 15..27
|
||||
assert_eq!(it.advance_back_by(8), Ok(())); // 15..27
|
||||
assert_eq!(it.clone().last(), Some(26));
|
||||
assert_eq!(it.advance_by(4), 0); // 19..27
|
||||
assert_eq!(it.advance_by(4), Ok(())); // 19..27
|
||||
assert_eq!(it.clone().last(), Some(26));
|
||||
assert_eq!(it.advance_back_by(5), 0); // 19..22
|
||||
assert_eq!(it.advance_back_by(5), Ok(())); // 19..22
|
||||
assert_eq!(it.clone().last(), Some(21));
|
||||
assert_eq!(it.advance_by(3), 0); // 22..22
|
||||
assert_eq!(it.advance_by(3), Ok(())); // 22..22
|
||||
assert_eq!(it.clone().last(), None);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use core::iter::*;
|
||||
use core::num::NonZeroUsize;
|
||||
|
||||
use super::Unfuse;
|
||||
|
||||
|
@ -73,16 +74,16 @@ fn test_iterator_skip_nth() {
|
|||
|
||||
#[test]
|
||||
fn test_skip_advance_by() {
|
||||
assert_eq!((0..0).skip(10).advance_by(0), 0);
|
||||
assert_eq!((0..0).skip(10).advance_by(1), 1);
|
||||
assert_eq!((0..0).skip(10).advance_by(0), Ok(()));
|
||||
assert_eq!((0..0).skip(10).advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!(
|
||||
(0u128..(usize::MAX as u128) + 1).skip(usize::MAX - 10).advance_by(usize::MAX - 5),
|
||||
usize::MAX - 16
|
||||
Err(NonZeroUsize::new(usize::MAX - 16).unwrap())
|
||||
);
|
||||
assert_eq!((0u128..u128::MAX).skip(usize::MAX - 10).advance_by(20), 0);
|
||||
assert_eq!((0u128..u128::MAX).skip(usize::MAX - 10).advance_by(20), Ok(()));
|
||||
|
||||
assert_eq!((0..2).skip(1).advance_back_by(10), 9);
|
||||
assert_eq!((0..0).skip(1).advance_back_by(0), 0);
|
||||
assert_eq!((0..2).skip(1).advance_back_by(10), Err(NonZeroUsize::new(9).unwrap()));
|
||||
assert_eq!((0..0).skip(1).advance_back_by(0), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use core::iter::*;
|
||||
use core::num::NonZeroUsize;
|
||||
|
||||
#[test]
|
||||
fn test_iterator_take() {
|
||||
|
@ -76,23 +77,23 @@ fn test_iterator_take_nth_back() {
|
|||
#[test]
|
||||
fn test_take_advance_by() {
|
||||
let mut take = (0..10).take(3);
|
||||
assert_eq!(take.advance_by(2), 0);
|
||||
assert_eq!(take.advance_by(2), Ok(()));
|
||||
assert_eq!(take.next(), Some(2));
|
||||
assert_eq!(take.advance_by(1), 1);
|
||||
assert_eq!(take.advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
|
||||
assert_eq!((0..0).take(10).advance_by(0), 0);
|
||||
assert_eq!((0..0).take(10).advance_by(1), 1);
|
||||
assert_eq!((0..10).take(4).advance_by(5), 1);
|
||||
assert_eq!((0..0).take(10).advance_by(0), Ok(()));
|
||||
assert_eq!((0..0).take(10).advance_by(1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!((0..10).take(4).advance_by(5), Err(NonZeroUsize::new(1).unwrap()));
|
||||
|
||||
let mut take = (0..10).take(3);
|
||||
assert_eq!(take.advance_back_by(2), 0);
|
||||
assert_eq!(take.advance_back_by(2), Ok(()));
|
||||
assert_eq!(take.next(), Some(0));
|
||||
assert_eq!(take.advance_back_by(1), 1);
|
||||
assert_eq!(take.advance_back_by(1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
|
||||
assert_eq!((0..2).take(1).advance_back_by(10), 9);
|
||||
assert_eq!((0..0).take(1).advance_back_by(1), 1);
|
||||
assert_eq!((0..0).take(1).advance_back_by(0), 0);
|
||||
assert_eq!((0..usize::MAX).take(100).advance_back_by(usize::MAX), usize::MAX - 100);
|
||||
assert_eq!((0..2).take(1).advance_back_by(10), Err(NonZeroUsize::new(9).unwrap()));
|
||||
assert_eq!((0..0).take(1).advance_back_by(1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!((0..0).take(1).advance_back_by(0), Ok(()));
|
||||
assert_eq!((0..usize::MAX).take(100).advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 100).unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use core::num::NonZeroUsize;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -287,25 +288,25 @@ fn test_range_step() {
|
|||
#[test]
|
||||
fn test_range_advance_by() {
|
||||
let mut r = 0..usize::MAX;
|
||||
assert_eq!(0, r.advance_by(0));
|
||||
assert_eq!(0, r.advance_back_by(0));
|
||||
assert_eq!(Ok(()), r.advance_by(0));
|
||||
assert_eq!(Ok(()), r.advance_back_by(0));
|
||||
|
||||
assert_eq!(r.len(), usize::MAX);
|
||||
|
||||
assert_eq!(0, r.advance_by(1));
|
||||
assert_eq!(0, r.advance_back_by(1));
|
||||
assert_eq!(Ok(()), r.advance_by(1));
|
||||
assert_eq!(Ok(()), r.advance_back_by(1));
|
||||
|
||||
assert_eq!((r.start, r.end), (1, usize::MAX - 1));
|
||||
|
||||
assert_eq!(2, r.advance_by(usize::MAX));
|
||||
assert_eq!(Err(NonZeroUsize::new(2).unwrap()), r.advance_by(usize::MAX));
|
||||
|
||||
assert_eq!(0, r.advance_by(0));
|
||||
assert_eq!(0, r.advance_back_by(0));
|
||||
assert_eq!(Ok(()), r.advance_by(0));
|
||||
assert_eq!(Ok(()), r.advance_back_by(0));
|
||||
|
||||
let mut r = 0u128..u128::MAX;
|
||||
|
||||
assert_eq!(0, r.advance_by(usize::MAX));
|
||||
assert_eq!(0, r.advance_back_by(usize::MAX));
|
||||
assert_eq!(Ok(()), r.advance_by(usize::MAX));
|
||||
assert_eq!(Ok(()), r.advance_back_by(usize::MAX));
|
||||
|
||||
assert_eq!((r.start, r.end), (0u128 + usize::MAX as u128, u128::MAX - usize::MAX as u128));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use core::num::NonZeroUsize;
|
||||
|
||||
/// A wrapper struct that implements `Eq` and `Ord` based on the wrapped
|
||||
/// integer modulo 3. Used to test that `Iterator::max` and `Iterator::min`
|
||||
/// return the correct element if some of them are equal.
|
||||
|
@ -148,13 +150,13 @@ fn test_iterator_advance_by() {
|
|||
|
||||
for i in 0..v.len() {
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_by(i), 0);
|
||||
assert_eq!(iter.advance_by(i), Ok(()));
|
||||
assert_eq!(iter.next().unwrap(), &v[i]);
|
||||
assert_eq!(iter.advance_by(100), 100 - (v.len() - 1 - i));
|
||||
assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap()));
|
||||
}
|
||||
|
||||
assert_eq!(v.iter().advance_by(v.len()), 0);
|
||||
assert_eq!(v.iter().advance_by(100), 100 - v.len());
|
||||
assert_eq!(v.iter().advance_by(v.len()), Ok(()));
|
||||
assert_eq!(v.iter().advance_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -163,13 +165,13 @@ fn test_iterator_advance_back_by() {
|
|||
|
||||
for i in 0..v.len() {
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_back_by(i), 0);
|
||||
assert_eq!(iter.advance_back_by(i), Ok(()));
|
||||
assert_eq!(iter.next_back().unwrap(), &v[v.len() - 1 - i]);
|
||||
assert_eq!(iter.advance_back_by(100), 100 - (v.len() - 1 - i));
|
||||
assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap()));
|
||||
}
|
||||
|
||||
assert_eq!(v.iter().advance_back_by(v.len()), 0);
|
||||
assert_eq!(v.iter().advance_back_by(100), 100 - v.len());
|
||||
assert_eq!(v.iter().advance_back_by(v.len()), Ok(()));
|
||||
assert_eq!(v.iter().advance_back_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -178,13 +180,13 @@ fn test_iterator_rev_advance_back_by() {
|
|||
|
||||
for i in 0..v.len() {
|
||||
let mut iter = v.iter().rev();
|
||||
assert_eq!(iter.advance_back_by(i), 0);
|
||||
assert_eq!(iter.advance_back_by(i), Ok(()));
|
||||
assert_eq!(iter.next_back().unwrap(), &v[i]);
|
||||
assert_eq!(iter.advance_back_by(100), 100 - (v.len() - 1 - i));
|
||||
assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap()));
|
||||
}
|
||||
|
||||
assert_eq!(v.iter().rev().advance_back_by(v.len()), 0);
|
||||
assert_eq!(v.iter().rev().advance_back_by(100), 100 - v.len());
|
||||
assert_eq!(v.iter().rev().advance_back_by(v.len()), Ok(()));
|
||||
assert_eq!(v.iter().rev().advance_back_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -422,13 +424,13 @@ fn test_iterator_rev_advance_by() {
|
|||
|
||||
for i in 0..v.len() {
|
||||
let mut iter = v.iter().rev();
|
||||
assert_eq!(iter.advance_by(i), 0);
|
||||
assert_eq!(iter.advance_by(i), Ok(()));
|
||||
assert_eq!(iter.next().unwrap(), &v[v.len() - 1 - i]);
|
||||
assert_eq!(iter.advance_by(100), 100 - (v.len() - 1 - i));
|
||||
assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap()));
|
||||
}
|
||||
|
||||
assert_eq!(v.iter().rev().advance_by(v.len()), 0);
|
||||
assert_eq!(v.iter().rev().advance_by(100), 100 - v.len());
|
||||
assert_eq!(v.iter().rev().advance_by(v.len()), Ok(()));
|
||||
assert_eq!(v.iter().rev().advance_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use core::cell::Cell;
|
||||
use core::cmp::Ordering;
|
||||
use core::mem::MaybeUninit;
|
||||
use core::num::NonZeroUsize;
|
||||
use core::result::Result::{Err, Ok};
|
||||
use core::slice;
|
||||
|
||||
|
@ -142,20 +143,20 @@ fn test_iterator_advance_by() {
|
|||
|
||||
for i in 0..=v.len() {
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_by(i), 0);
|
||||
assert_eq!(iter.advance_by(i), Ok(()));
|
||||
assert_eq!(iter.as_slice(), &v[i..]);
|
||||
}
|
||||
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_by(v.len() + 1), 1);
|
||||
assert_eq!(iter.advance_by(v.len() + 1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!(iter.as_slice(), &[]);
|
||||
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_by(3), 0);
|
||||
assert_eq!(iter.advance_by(3), Ok(()));
|
||||
assert_eq!(iter.as_slice(), &v[3..]);
|
||||
assert_eq!(iter.advance_by(2), 0);
|
||||
assert_eq!(iter.advance_by(2), Ok(()));
|
||||
assert_eq!(iter.as_slice(), &[]);
|
||||
assert_eq!(iter.advance_by(0), 0);
|
||||
assert_eq!(iter.advance_by(0), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -164,20 +165,20 @@ fn test_iterator_advance_back_by() {
|
|||
|
||||
for i in 0..=v.len() {
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_back_by(i), 0);
|
||||
assert_eq!(iter.advance_back_by(i), Ok(()));
|
||||
assert_eq!(iter.as_slice(), &v[..v.len() - i]);
|
||||
}
|
||||
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_back_by(v.len() + 1), 1);
|
||||
assert_eq!(iter.advance_back_by(v.len() + 1), Err(NonZeroUsize::new(1).unwrap()));
|
||||
assert_eq!(iter.as_slice(), &[]);
|
||||
|
||||
let mut iter = v.iter();
|
||||
assert_eq!(iter.advance_back_by(3), 0);
|
||||
assert_eq!(iter.advance_back_by(3), Ok(()));
|
||||
assert_eq!(iter.as_slice(), &v[..v.len() - 3]);
|
||||
assert_eq!(iter.advance_back_by(2), 0);
|
||||
assert_eq!(iter.advance_back_by(2), Ok(()));
|
||||
assert_eq!(iter.as_slice(), &[]);
|
||||
assert_eq!(iter.advance_back_by(0), 0);
|
||||
assert_eq!(iter.advance_back_by(0), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue