Skip to content

Commit 865c2db

Browse files
committed
add MoveItems to RingBuf, fixes #19085
1 parent 4389ee3 commit 865c2db

File tree

1 file changed

+102
-8
lines changed

1 file changed

+102
-8
lines changed

src/libcollections/ring_buf.rs

+102-8
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ static MINIMUM_CAPACITY: uint = 2u;
3434

3535
// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
3636
// be scrapped anyway. Defer to rewrite?
37-
// FIXME(conventions): implement into_iter
38-
3937

4038
/// `RingBuf` is a circular buffer that implements `Deque`.
4139
pub struct RingBuf<T> {
@@ -394,6 +392,14 @@ impl<T> RingBuf<T> {
394392
}
395393
}
396394

395+
/// Consumes the list into an iterator yielding elements by value.
396+
#[unstable = "matches collection reform specification, waiting for dust to settle"]
397+
pub fn into_iter(self) -> MoveItems<T> {
398+
MoveItems {
399+
inner: self,
400+
}
401+
}
402+
397403
/// Returns the number of elements in the `RingBuf`.
398404
///
399405
/// # Example
@@ -737,11 +743,9 @@ impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
737743
}
738744
let tail = self.tail;
739745
self.tail = wrap_index(self.tail + 1, self.cap);
740-
if mem::size_of::<T>() != 0 {
741-
unsafe { Some(&mut *self.ptr.offset(tail as int)) }
742-
} else {
743-
// use a non-zero pointer
744-
Some(unsafe { mem::transmute(1u) })
746+
747+
unsafe {
748+
Some(&mut *self.ptr.offset(tail as int))
745749
}
746750
}
747751

@@ -759,12 +763,43 @@ impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
759763
return None;
760764
}
761765
self.head = wrap_index(self.head - 1, self.cap);
762-
unsafe { Some(&mut *self.ptr.offset(self.head as int)) }
766+
767+
unsafe {
768+
Some(&mut *self.ptr.offset(self.head as int))
769+
}
763770
}
764771
}
765772

766773
impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
767774

775+
// A by-value RingBuf iterator
776+
pub struct MoveItems<T> {
777+
inner: RingBuf<T>,
778+
}
779+
780+
impl<T> Iterator<T> for MoveItems<T> {
781+
#[inline]
782+
fn next(&mut self) -> Option<T> {
783+
self.inner.pop_front()
784+
}
785+
786+
#[inline]
787+
fn size_hint(&self) -> (uint, Option<uint>) {
788+
let len = self.inner.len();
789+
(len, Some(len))
790+
}
791+
}
792+
793+
impl<T> DoubleEndedIterator<T> for MoveItems<T> {
794+
#[inline]
795+
fn next_back(&mut self) -> Option<T> {
796+
self.inner.pop_back()
797+
}
798+
}
799+
800+
801+
impl<T> ExactSize<T> for MoveItems<T> {}
802+
768803
impl<A: PartialEq> PartialEq for RingBuf<A> {
769804
fn eq(&self, other: &RingBuf<A>) -> bool {
770805
self.len() == other.len() &&
@@ -1314,6 +1349,65 @@ mod tests {
13141349
}
13151350
}
13161351

1352+
#[test]
1353+
fn test_into_iter() {
1354+
1355+
// Empty iter
1356+
{
1357+
let d: RingBuf<int> = RingBuf::new();
1358+
let mut iter = d.into_iter();
1359+
1360+
assert_eq!(iter.size_hint(), (0, Some(0)));
1361+
assert_eq!(iter.next(), None);
1362+
assert_eq!(iter.size_hint(), (0, Some(0)));
1363+
}
1364+
1365+
// simple iter
1366+
{
1367+
let mut d = RingBuf::new();
1368+
for i in range(0i, 5) {
1369+
d.push_back(i);
1370+
}
1371+
1372+
let b = vec![0,1,2,3,4];
1373+
assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1374+
}
1375+
1376+
// wrapped iter
1377+
{
1378+
let mut d = RingBuf::new();
1379+
for i in range(0i, 5) {
1380+
d.push_back(i);
1381+
}
1382+
for i in range(6, 9) {
1383+
d.push_front(i);
1384+
}
1385+
1386+
let b = vec![8,7,6,0,1,2,3,4];
1387+
assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
1388+
}
1389+
1390+
// partially used
1391+
{
1392+
let mut d = RingBuf::new();
1393+
for i in range(0i, 5) {
1394+
d.push_back(i);
1395+
}
1396+
for i in range(6, 9) {
1397+
d.push_front(i);
1398+
}
1399+
1400+
let mut it = d.into_iter();
1401+
assert_eq!(it.size_hint(), (8, Some(8)));
1402+
assert_eq!(it.next(), Some(8));
1403+
assert_eq!(it.size_hint(), (7, Some(7)));
1404+
assert_eq!(it.next_back(), Some(4));
1405+
assert_eq!(it.size_hint(), (6, Some(6)));
1406+
assert_eq!(it.next(), Some(7));
1407+
assert_eq!(it.size_hint(), (5, Some(5)));
1408+
}
1409+
}
1410+
13171411
#[test]
13181412
fn test_from_iter() {
13191413
use std::iter;

0 commit comments

Comments
 (0)