Skip to content

Commit

Permalink
add MoveItems to RingBuf, fixes #19085
Browse files Browse the repository at this point in the history
  • Loading branch information
Gankra committed Nov 23, 2014
1 parent 4389ee3 commit 865c2db
Showing 1 changed file with 102 additions and 8 deletions.
110 changes: 102 additions & 8 deletions src/libcollections/ring_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ static MINIMUM_CAPACITY: uint = 2u;

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


/// `RingBuf` is a circular buffer that implements `Deque`.
pub struct RingBuf<T> {
Expand Down Expand Up @@ -394,6 +392,14 @@ impl<T> RingBuf<T> {
}
}

/// Consumes the list into an iterator yielding elements by value.
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn into_iter(self) -> MoveItems<T> {
MoveItems {
inner: self,
}
}

/// Returns the number of elements in the `RingBuf`.
///
/// # Example
Expand Down Expand Up @@ -737,11 +743,9 @@ impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
}
let tail = self.tail;
self.tail = wrap_index(self.tail + 1, self.cap);
if mem::size_of::<T>() != 0 {
unsafe { Some(&mut *self.ptr.offset(tail as int)) }
} else {
// use a non-zero pointer
Some(unsafe { mem::transmute(1u) })

unsafe {
Some(&mut *self.ptr.offset(tail as int))
}
}

Expand All @@ -759,12 +763,43 @@ impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
return None;
}
self.head = wrap_index(self.head - 1, self.cap);
unsafe { Some(&mut *self.ptr.offset(self.head as int)) }

unsafe {
Some(&mut *self.ptr.offset(self.head as int))
}
}
}

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

// A by-value RingBuf iterator
pub struct MoveItems<T> {
inner: RingBuf<T>,
}

impl<T> Iterator<T> for MoveItems<T> {
#[inline]
fn next(&mut self) -> Option<T> {
self.inner.pop_front()
}

#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let len = self.inner.len();
(len, Some(len))
}
}

impl<T> DoubleEndedIterator<T> for MoveItems<T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
self.inner.pop_back()
}
}


impl<T> ExactSize<T> for MoveItems<T> {}

impl<A: PartialEq> PartialEq for RingBuf<A> {
fn eq(&self, other: &RingBuf<A>) -> bool {
self.len() == other.len() &&
Expand Down Expand Up @@ -1314,6 +1349,65 @@ mod tests {
}
}

#[test]
fn test_into_iter() {

// Empty iter
{
let d: RingBuf<int> = RingBuf::new();
let mut iter = d.into_iter();

assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next(), None);
assert_eq!(iter.size_hint(), (0, Some(0)));
}

// simple iter
{
let mut d = RingBuf::new();
for i in range(0i, 5) {
d.push_back(i);
}

let b = vec![0,1,2,3,4];
assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
}

// wrapped iter
{
let mut d = RingBuf::new();
for i in range(0i, 5) {
d.push_back(i);
}
for i in range(6, 9) {
d.push_front(i);
}

let b = vec![8,7,6,0,1,2,3,4];
assert_eq!(d.into_iter().collect::<Vec<int>>(), b);
}

// partially used
{
let mut d = RingBuf::new();
for i in range(0i, 5) {
d.push_back(i);
}
for i in range(6, 9) {
d.push_front(i);
}

let mut it = d.into_iter();
assert_eq!(it.size_hint(), (8, Some(8)));
assert_eq!(it.next(), Some(8));
assert_eq!(it.size_hint(), (7, Some(7)));
assert_eq!(it.next_back(), Some(4));
assert_eq!(it.size_hint(), (6, Some(6)));
assert_eq!(it.next(), Some(7));
assert_eq!(it.size_hint(), (5, Some(5)));
}
}

#[test]
fn test_from_iter() {
use std::iter;
Expand Down

8 comments on commit 865c2db

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from huonw
at Gankra@865c2db

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging Gankro/rust/ringbuf-into-iter = 865c2db into auto

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gankro/rust/ringbuf-into-iter = 865c2db merged ok, testing candidate = 4a51574

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 26, 2014

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from huonw
at Gankra@865c2db

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging Gankro/rust/ringbuf-into-iter = 865c2db into auto

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gankro/rust/ringbuf-into-iter = 865c2db merged ok, testing candidate = 7fcd1f17

@bors
Copy link
Contributor

@bors bors commented on 865c2db Nov 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.