Skip to content

Commit d97f391

Browse files
committed
Implement DoubleEndedIterator on IntoIter and Drain
1 parent 8e059c8 commit d97f391

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

lib.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ impl<'a, T: 'a> Iterator for Drain<'a,T> {
7373
}
7474
}
7575

76+
impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
77+
#[inline]
78+
fn next_back(&mut self) -> Option<T> {
79+
match self.iter.next_back() {
80+
None => None,
81+
Some(reference) => {
82+
unsafe {
83+
Some(ptr::read(reference))
84+
}
85+
}
86+
}
87+
}
88+
}
89+
7690
impl<'a, T: 'a> Drop for Drain<'a,T> {
7791
fn drop(&mut self) {
7892
// Destroy the remaining elements.
@@ -496,6 +510,7 @@ impl<A: Array> Drop for IntoIter<A> {
496510
impl<A: Array> Iterator for IntoIter<A> {
497511
type Item = A::Item;
498512

513+
#[inline]
499514
#[inline]
500515
fn next(&mut self) -> Option<A::Item> {
501516
if self.current == self.end {
@@ -511,6 +526,21 @@ impl<A: Array> Iterator for IntoIter<A> {
511526
}
512527
}
513528

529+
impl<A: Array> DoubleEndedIterator for IntoIter<A> {
530+
#[inline]
531+
fn next_back(&mut self) -> Option<A::Item> {
532+
if self.current == self.end {
533+
None
534+
}
535+
else {
536+
unsafe {
537+
self.end -= 1;
538+
Some(ptr::read(self.data.ptr_mut().offset(self.end as isize)))
539+
}
540+
}
541+
}
542+
}
543+
514544
impl<A: Array> IntoIterator for SmallVec<A> {
515545
type IntoIter = IntoIter<A>;
516546
type Item = A::Item;
@@ -676,6 +706,19 @@ pub mod tests {
676706
assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
677707
}
678708

709+
#[test]
710+
fn drain_rev() {
711+
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
712+
v.push(3);
713+
assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[3]);
714+
715+
// spilling the vec
716+
v.push(3);
717+
v.push(4);
718+
v.push(5);
719+
assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[5, 4, 3]);
720+
}
721+
679722
#[test]
680723
fn into_iter() {
681724
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
@@ -687,7 +730,21 @@ pub mod tests {
687730
v.push(3);
688731
v.push(4);
689732
v.push(5);
690-
assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
733+
assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]);
734+
}
735+
736+
#[test]
737+
fn into_iter_rev() {
738+
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
739+
v.push(3);
740+
assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]);
741+
742+
// spilling the vec
743+
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
744+
v.push(3);
745+
v.push(4);
746+
v.push(5);
747+
assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]);
691748
}
692749

693750
#[test]
@@ -728,6 +785,19 @@ pub mod tests {
728785
assert!(v.into_iter().next().is_some());
729786
assert_eq!(cell.get(), 3);
730787
}
788+
{
789+
let cell = Cell::new(0);
790+
let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
791+
v.push(DropCounter(&cell));
792+
v.push(DropCounter(&cell));
793+
v.push(DropCounter(&cell));
794+
{
795+
let mut it = v.into_iter();
796+
assert!(it.next().is_some());
797+
assert!(it.next_back().is_some());
798+
}
799+
assert_eq!(cell.get(), 3);
800+
}
731801
}
732802

733803
#[test]

0 commit comments

Comments
 (0)