Skip to content

Commit

Permalink
add values()
Browse files Browse the repository at this point in the history
  • Loading branch information
rinde committed Dec 15, 2023
1 parent 9502b14 commit 56d1095
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 12 deletions.
14 changes: 7 additions & 7 deletions doc/vec_map.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Below is an overview of the all methods and traits that are implemented for `Vec
| `iter_mut()` ||
| `keys()` ||
| `into_keys()` | |
| `values()` | planned |
| `values()` | |
| `values_mut()` | |
| `into_values()` | |
| `clear()` ||
Expand Down Expand Up @@ -118,12 +118,12 @@ Below is an overview of the all methods and traits that are implemented for `Vec
| --------------------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ------------ |
| `as_slice()` | not planned | not planned | not planned | not planned | not planned | not planned | not planned | not planned | not planned |
| `as_mut_slice()` | not planned | not planned | not planned | not planned | not planned | not planned | not planned | not planned | not planned |
| `Iterator` |||| || | planned | | |
| `DoubleEndedIterator` |||| || | planned | | |
| `ExactSizeIterator` |||| || | planned | | |
| `FusedIterator` |||| || | planned | | |
| `Clone` || || || | | | |
| `Debug` |||| || | | | |
| `Iterator` |||| || | | | |
| `DoubleEndedIterator` |||| || | | | |
| `ExactSizeIterator` |||| || | | | |
| `FusedIterator` |||| || | | | |
| `Clone` || || || | | | |
| `Debug` |||| || | | | |

## Serde support

Expand Down
92 changes: 92 additions & 0 deletions src/vec_map/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,65 @@ where
}
}

/// An iterator over the values following the key natural order.
#[derive(Clone)]
pub struct Values<'a, V> {
pub(super) inner: core::slice::Iter<'a, Option<V>>,
pub(super) len: usize,
}

impl<'a, V> Iterator for Values<'a, V> {
type Item = &'a V;

fn next(&mut self) -> Option<Self::Item> {
if self.len == 0 {
return None;
}
self.inner.find_map(|value| value.as_ref()).map(|v| {
self.len -= 1;
v
})
}
}

impl<'a, V> DoubleEndedIterator for Values<'a, V> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.len == 0 {
return None;
}
self.inner
.by_ref()
.rev()
.find_map(|value| value.as_ref())
.map(|v| {
self.len -= 1;
v
})
}
}

impl<'a, V> ExactSizeIterator for Values<'a, V> {
fn len(&self) -> usize {
self.len
}
}

impl<'a, V> FusedIterator for Values<'a, V> {}

impl<'a, V> fmt::Debug for Values<'a, V>
where
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// TODO why can't we use self.clone()
let iter: Values<'a, V> = Values {
inner: self.inner.clone(),
len: self.len,
};
f.debug_list().entries(iter).finish()
}
}

#[cfg(test)]
mod test {
use crate::vecmap;
Expand Down Expand Up @@ -408,4 +467,37 @@ mod test {
assert_eq!(None, iter.next());
assert_eq!(0, iter.len());
}

#[test]
fn test_values() {
let map = vecmap! { 9u16 => "nine", 17 => "seventeen", 2 => "two"};

// forward
let mut iter = map.values();
assert_eq!(3, iter.len());
assert_eq!(Some(&"two"), iter.next());
assert_eq!(2, iter.len());
assert_eq!(Some(&"nine"), iter.next());
assert_eq!(1, iter.len());
assert_eq!(Some(&"seventeen"), iter.next());
assert_eq!(0, iter.len());
assert_eq!(None, iter.next());

// back, forward, back
let mut iter = map.values();
assert_eq!(3, iter.len());
assert_eq!(Some(&"seventeen"), iter.next_back());
assert_eq!(2, iter.len());
assert_eq!(Some(&"two"), iter.next());
assert_eq!(1, iter.len());
assert_eq!(Some(&"nine"), iter.next_back());
assert_eq!(0, iter.len());
assert_eq!(None, iter.next_back());

let map: VecMap<usize, usize> = VecMap::with_capacity(40);
let mut iter = map.values();
assert_eq!(0, iter.len());
assert_eq!(None, iter.next());
assert_eq!(0, iter.len());
}
}
13 changes: 8 additions & 5 deletions src/vec_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ use std::marker::PhantomData;
use std::ops::Index;
use std::ops::IndexMut;

pub use crate::vec_map::iter::IntoIter;
pub use crate::vec_map::iter::Iter;
use crate::vec_map::iter::IterMut;
pub use crate::vec_map::iter::Keys;
pub use crate::vec_map::iter::*;

/// A key that can be used in a map without needing a hasher.
///
Expand Down Expand Up @@ -242,7 +239,13 @@ impl<K: IndexKey, V> VecMap<K, V> {
}
}

// TODO values()
/// Returns an iterator over the values of the map following the natural order of the keys.
pub fn values(&self) -> Values<'_, V> {
Values {
inner: self.data.iter(),
len: self.len,
}
}
}

impl<K: IndexKey, V> Default for VecMap<K, V> {
Expand Down

0 comments on commit 56d1095

Please sign in to comment.