Skip to content

Commit

Permalink
IntoIter for Map, & Map and &mut Map.
Browse files Browse the repository at this point in the history
  • Loading branch information
Zefick committed May 3, 2023
1 parent ae18b8a commit 53e6d93
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 9 deletions.
71 changes: 65 additions & 6 deletions src/iterators.rs
Expand Up @@ -19,6 +19,8 @@
// SOFTWARE.

use crate::{IntoIter, Iter, IterMut, Map};
use std::mem;
use std::mem::MaybeUninit;

impl<K: PartialEq, V, const N: usize> Map<K, V, N> {
/// Make an iterator over all pairs.
Expand Down Expand Up @@ -76,24 +78,54 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
}
}

impl<'a, K: Clone, V: Clone, const N: usize> Iterator for IntoIter<'a, K, V, N> {
impl<K: PartialEq, V, const N: usize> Iterator for IntoIter<K, V, N> {
type Item = (K, V);

#[inline]
#[must_use]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|p| (p.0.clone(), p.1.clone()))
while self.pos < self.map.next {
let p = &mut self.map.pairs[self.pos];
self.pos += 1;
unsafe {
if p.assume_init_ref().is_some() {
return mem::replace(p, MaybeUninit::new(None)).assume_init();
}
}
}
None
}
}

impl<'a, K: PartialEq, V, const N: usize> IntoIterator for &'a Map<K, V, N> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V, N>;

#[inline]
#[must_use]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}

impl<'a, K: PartialEq, V, const N: usize> IntoIterator for &'a mut Map<K, V, N> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;

#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}

impl<'a, K: Clone + PartialEq, V: Clone, const N: usize> IntoIterator for &'a Map<K, V, N> {
impl<K: PartialEq, V, const N: usize> IntoIterator for Map<K, V, N> {
type Item = (K, V);
type IntoIter = IntoIter<'a, K, V, N>;
type IntoIter = IntoIter<K, V, N>;

#[inline]
#[must_use]
fn into_iter(self) -> Self::IntoIter {
IntoIter { iter: self.iter() }
IntoIter { pos: 0, map: self }
}
}

Expand Down Expand Up @@ -158,7 +190,7 @@ fn into_iterate_with_blanks() {
m.insert("three", 5);
m.remove(&"two");
let mut sum = 0;
for (_k, v) in m.into_iter() {
for (_k, v) in m {
sum += v;
}
assert_eq!(6, sum);
Expand Down Expand Up @@ -188,3 +220,30 @@ fn iter_mut_with_blanks() {
assert_eq!(m.iter_mut().count(), 2);
assert_eq!(m.iter_mut().last().unwrap().1, &5);
}

#[test]
fn into_iter_mut() {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("one", 2);
m.insert("two", 3);
m.insert("three", 5);
for (_k, v) in &mut m {
*v *= 2;
}
let sum = m.iter().map(|p| p.1).sum::<i32>();
assert_eq!(20, sum);
}

#[test]
fn into_iter_drop() {
use std::rc::Rc;
let mut m: Map<i32, Rc<()>, 8> = Map::new();
let v = Rc::new(());
let n = 8;
for i in 0..n {
m.insert(i, Rc::clone(&v));
}
assert_eq!(Rc::strong_count(&v), (n + 1) as usize);
let _p = m.into_iter().nth(3);
assert_eq!(Rc::strong_count(&v), 2); // v & p
}
6 changes: 3 additions & 3 deletions src/lib.rs
Expand Up @@ -47,7 +47,6 @@
#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
#![allow(clippy::multiple_inherent_impl)]
#![allow(clippy::multiple_crate_versions)]

mod clone;
mod ctors;
mod debug;
Expand Down Expand Up @@ -110,6 +109,7 @@ pub struct IterMut<'a, K, V> {
}

/// Into-iterator over the [`Map`].
pub struct IntoIter<'a, K, V, const N: usize> {
iter: Iter<'a, K, V, N>,
pub struct IntoIter<K: PartialEq, V, const N: usize> {
pos: usize,
map: Map<K, V, N>,
}

0 comments on commit 53e6d93

Please sign in to comment.