Skip to content

Commit

Permalink
Added external iterators for SmallIntMap and SmallIntSet
Browse files Browse the repository at this point in the history
Adding iterators for extra::smallintmap

Working on mutability error

Ran into ICE

More mutability problems

Working through mutability issue

working on getting tests passing

SmallIntMa tests passing

Added SmallIntSet iterators, and the tests are passing

Stripped trailing spaces

Removed extra use directive
  • Loading branch information
=Mark Sinclair authored and MarkJr94 committed Jul 6, 2013
1 parent 6595c42 commit 6f479a6
Showing 1 changed file with 287 additions and 0 deletions.
287 changes: 287 additions & 0 deletions src/libextra/smallintmap.rs
Expand Up @@ -18,8 +18,10 @@

use std::cmp;
use std::container::{Container, Mutable, Map, Set};
use std::iterator::{Iterator,IteratorUtil,ZipIterator,Counter};
use std::uint;
use std::util::replace;
use std::vec::{VecIterator,VecMutIterator,VecRevIterator,VecMutRevIterator};

#[allow(missing_doc)]
pub struct SmallIntMap<T> {
Expand Down Expand Up @@ -168,6 +170,40 @@ impl<V> SmallIntMap<V> {
pub fn get<'a>(&'a self, key: &uint) -> &'a V {
self.find(key).expect("key not present")
}

/// An iterator visiting all key-value pairs in ascending order by the keys.
/// Iterator element type is (uint, &'r V)
pub fn iter<'r>(&'r self) -> SmallIntMapIterator<'r, V> {
SmallIntMapIterator {
iter: Counter::new(0,1).zip(self.v.iter())
}
}

/// An iterator visiting all key-value pairs in ascending order by the keys,
/// with mutable references to the values
/// Iterator element type is (uint, &'r mut V)
pub fn mut_iter<'r>(&'r mut self) -> SmallIntMapMutIterator<'r, V> {
SmallIntMapMutIterator {
iter: Counter::new(0,1).zip(self.v.mut_iter())
}
}

/// An iterator visiting all key-value pairs in descending order by the keys.
/// Iterator element type is (uint, &'r V)
pub fn rev_iter<'r>(&'r self) -> SmallIntMapRevIterator<'r, V> {
SmallIntMapRevIterator {
iter: Counter::new(self.len() as int - 1, -1).zip(self.v.rev_iter())
}
}

/// An iterator visiting all key-value pairs in descending order by the keys,
/// with mutable references to the values
/// Iterator element type is (uint, &'r mut V)
pub fn mut_rev_iter<'r>(&'r mut self) -> SmallIntMapMutRevIterator <'r, V> {
SmallIntMapMutRevIterator {
iter: Counter::new(self.len() as int - 1, -1).zip(self.v.mut_rev_iter())
}
}
}

impl<V:Copy> SmallIntMap<V> {
Expand All @@ -186,6 +222,95 @@ impl<V:Copy> SmallIntMap<V> {
}
}


macro_rules! iterator {
/* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
(struct $name:ident -> $ptr:ty, $elem:ty) => {
pub struct $name<'self, T> {
priv ptr: $ptr,
priv end: $ptr,
priv lifetime: $elem // FIXME: #5922
}
};*/
(impl $name:ident -> $elem:ty) => {
impl<'self, T> Iterator<(uint, $elem)> for $name<'self, T> {
#[inline]
pub fn next(&mut self) -> Option<(uint, $elem)> {
for self.iter.advance |(idx, elem)| {
match elem {
&None => {}
&Some(ref e) => { return Some((idx as uint, e)) }
}
}

None
}
}
}
}

macro_rules! mut_iterator {
/* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
(struct $name:ident -> $ptr:ty, $elem:ty) => {
pub struct $name<'self, T> {
priv ptr: $ptr,
priv end: $ptr,
priv lifetime: $elem // FIXME: #5922
}
};*/
(impl $name:ident -> $elem:ty) => {
impl<'self, T> Iterator<(uint, $elem)> for $name<'self, T> {
#[inline]
pub fn next(&mut self) -> Option<(uint, $elem)> {
for self.iter.advance |(idx, elem)| {
match elem {
&None => {}
&Some(ref mut e) => { return Some((idx as uint, e)) }
}
}

None
}
}
}
}

pub struct SmallIntMapIterator<'self, T> {
priv iter: ZipIterator<int,
Counter<int>,
&'self Option<T>,
VecIterator<'self, Option<T> > >
}

iterator!{impl SmallIntMapIterator -> &'self T}

pub struct SmallIntMapMutIterator<'self, T> {
priv iter: ZipIterator<int,
Counter<int>,
&'self mut Option<T>,
VecMutIterator<'self, Option<T> > >
}

mut_iterator!{impl SmallIntMapMutIterator -> &'self mut T}

pub struct SmallIntMapRevIterator<'self, T> {
priv iter: ZipIterator<int,
Counter<int>,
&'self Option<T>,
VecRevIterator<'self, Option<T> > >
}

iterator!{impl SmallIntMapRevIterator -> &'self T}

pub struct SmallIntMapMutRevIterator<'self, T> {
priv iter: ZipIterator<int,
Counter<int>,
&'self mut Option<T>,
VecMutRevIterator<'self, Option<T> > >
}

mut_iterator!{impl SmallIntMapMutRevIterator -> &'self mut T}

/// A set implemented on top of the SmallIntMap type. This set is always a set
/// of integers, and the space requirements are on the order of the highest
/// valued integer in the set.
Expand Down Expand Up @@ -281,8 +406,57 @@ impl SmallIntSet {

/// Visit all values in order
pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }

/// An iterator visiting all set members in ascending order.
/// Iterator element type is uint
pub fn iter<'r>(&'r self) -> SmallIntSetIterator<'r> {
SmallIntSetIterator {
iter: self.map.iter()
}
}

/// An iterator visiting all set members in descending order.
/// Iterator element type is uint
pub fn rev_iter<'r>(&'r mut self) -> SmallIntSetRevIterator<'r> {
SmallIntSetRevIterator {
iter: self.map.rev_iter()
}
}

}

pub struct SmallIntSetIterator<'self> {
priv iter: SmallIntMapIterator<'self, ()>
}

pub struct SmallIntSetRevIterator<'self> {
priv iter: SmallIntMapRevIterator<'self,()>
}

impl<'self> Iterator<uint> for SmallIntSetIterator<'self> {
#[inline]
pub fn next(&mut self) -> Option<uint> {
let next_opt = self.iter.next();
match next_opt {
None => { None }
Some((idx, _)) => { Some(idx) }
}
}
}

impl<'self> Iterator<uint> for SmallIntSetRevIterator<'self> {
#[inline]
pub fn next(&mut self) -> Option<uint> {
let next_opt = self.iter.next();
match next_opt {
None => { None }
Some((idx, _)) => { Some(idx) }
}
}
}



#[cfg(test)]
mod tests {

Expand Down Expand Up @@ -375,6 +549,82 @@ mod tests {
assert_eq!(m.pop(&1), Some(2));
assert_eq!(m.pop(&1), None);
}

#[test]
fn test_iterator() {
let mut a = SmallIntMap::new();

assert!(a.insert(0,1));
assert!(a.insert(1,2));
assert!(a.insert(2,5));
assert!(a.insert(3,10));
assert!(a.insert(4,11));

let mut it = a.iter();
assert_eq!(it.next().unwrap(), (0, &1));
assert_eq!(it.next().unwrap(), (1, &2));
assert_eq!(it.next().unwrap(), (2, &5));
assert_eq!(it.next().unwrap(), (3, &10));
assert_eq!(it.next().unwrap(), (4, &11));
assert!(it.next().is_none());
}

#[test]
fn test_mut_iterator() {
let mut a = SmallIntMap::new();

assert!(a.insert(0,1));
assert!(a.insert(1,1));
assert!(a.insert(2,1));
assert!(a.insert(3,1));
assert!(a.insert(4,1));

for a.mut_iter().advance |(_,v)| {
*v += 1;
}

assert!(a.iter().all(|(_,v)| *v == 2));
}

#[test]
fn test_rev_iterator() {
let mut a = SmallIntMap::new();

assert!(a.insert(0,1));
assert!(a.insert(1,2));
assert!(a.insert(2,5));
assert!(a.insert(3,10));
assert!(a.insert(4,11));

let mut b = SmallIntMap::new();

assert!(b.insert(0,11));
assert!(b.insert(1,10));
assert!(b.insert(2,5));
assert!(b.insert(3,2));
assert!(b.insert(4,1));

let (a_it, b_it) = (a.iter(), b.rev_iter());

assert!(a_it.zip(b_it).all(|( (_ ,v1), (_, v2) )| *v1 == *v2));
}

#[test]
fn test_mut_rev_iterator() {
let mut a = SmallIntMap::new();

assert!(a.insert(0,5));
assert!(a.insert(1,4));
assert!(a.insert(2,3));
assert!(a.insert(3,2));
assert!(a.insert(4,1));

for a.mut_rev_iter().advance |(i,v)| {
*v += i as int;
}

assert!(a.iter().all(|(_,v)| *v == 5 ));
}
}

#[cfg(test)]
Expand Down Expand Up @@ -535,4 +785,41 @@ mod test_set {
}
assert_eq!(i, expected.len());
}

#[test]
fn test_iterator() {
let mut a = SmallIntSet::new();

assert!(a.insert(0));
assert!(a.insert(1));
assert!(a.insert(2));
assert!(a.insert(3));
assert!(a.insert(4));

let mut it = a.iter();
assert_eq!(it.next().unwrap(), 0);
assert_eq!(it.next().unwrap(), 1);
assert_eq!(it.next().unwrap(), 2);
assert_eq!(it.next().unwrap(), 3);
assert_eq!(it.next().unwrap(), 4);
assert!(it.next().is_none());
}

#[test]
fn test_rev_iterator() {
let mut a = SmallIntSet::new();

assert!(a.insert(0));
assert!(a.insert(1));
assert!(a.insert(2));
assert!(a.insert(3));
assert!(a.insert(4));

let a_it = a.rev_iter();

assert!(do a_it.enumerate().all |( i, v2 )| {
i + v2 == 4
});
}

}

5 comments on commit 6f479a6

@bors
Copy link
Contributor

@bors bors commented on 6f479a6 Jul 9, 2013

Choose a reason for hiding this comment

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

@bors
Copy link
Contributor

@bors bors commented on 6f479a6 Jul 9, 2013

Choose a reason for hiding this comment

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

merging MarkJr94/rust/smallintmap_enum = 6f479a6 into auto

@bors
Copy link
Contributor

@bors bors commented on 6f479a6 Jul 9, 2013

Choose a reason for hiding this comment

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

MarkJr94/rust/smallintmap_enum = 6f479a6 merged ok, testing candidate = ee10246

@bors
Copy link
Contributor

@bors bors commented on 6f479a6 Jul 9, 2013

Choose a reason for hiding this comment

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

fast-forwarding master to auto = ee10246

Please sign in to comment.