Implement DoubleEndedIterator on IntoIter and Drain

This commit is contained in:
Markus
2016-07-31 21:30:38 +02:00
parent 8e059c83b9
commit d97f391cf3
+71 -1
View File
@@ -73,6 +73,20 @@ impl<'a, T: 'a> Iterator for Drain<'a,T> {
}
}
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
match self.iter.next_back() {
None => None,
Some(reference) => {
unsafe {
Some(ptr::read(reference))
}
}
}
}
}
impl<'a, T: 'a> Drop for Drain<'a,T> {
fn drop(&mut self) {
// Destroy the remaining elements.
@@ -496,6 +510,7 @@ impl<A: Array> Drop for IntoIter<A> {
impl<A: Array> Iterator for IntoIter<A> {
type Item = A::Item;
#[inline]
#[inline]
fn next(&mut self) -> Option<A::Item> {
if self.current == self.end {
@@ -511,6 +526,21 @@ impl<A: Array> Iterator for IntoIter<A> {
}
}
impl<A: Array> DoubleEndedIterator for IntoIter<A> {
#[inline]
fn next_back(&mut self) -> Option<A::Item> {
if self.current == self.end {
None
}
else {
unsafe {
self.end -= 1;
Some(ptr::read(self.data.ptr_mut().offset(self.end as isize)))
}
}
}
}
impl<A: Array> IntoIterator for SmallVec<A> {
type IntoIter = IntoIter<A>;
type Item = A::Item;
@@ -676,6 +706,19 @@ pub mod tests {
assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
}
#[test]
fn drain_rev() {
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
v.push(3);
assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[3]);
// spilling the vec
v.push(3);
v.push(4);
v.push(5);
assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[5, 4, 3]);
}
#[test]
fn into_iter() {
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
@@ -687,7 +730,21 @@ pub mod tests {
v.push(3);
v.push(4);
v.push(5);
assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]);
}
#[test]
fn into_iter_rev() {
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
v.push(3);
assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]);
// spilling the vec
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
v.push(3);
v.push(4);
v.push(5);
assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]);
}
#[test]
@@ -728,6 +785,19 @@ pub mod tests {
assert!(v.into_iter().next().is_some());
assert_eq!(cell.get(), 3);
}
{
let cell = Cell::new(0);
let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
v.push(DropCounter(&cell));
v.push(DropCounter(&cell));
v.push(DropCounter(&cell));
{
let mut it = v.into_iter();
assert!(it.next().is_some());
assert!(it.next_back().is_some());
}
assert_eq!(cell.get(), 3);
}
}
#[test]