From 0ab03c56128a58e6d5bfe2bbeb9e10c5ec3b4248 Mon Sep 17 00:00:00 2001 From: Kieran Griffiths Date: Sun, 10 Oct 2021 07:53:03 +0800 Subject: [PATCH 1/5] Added implementations for IntoIter and IterMut - The main goal was to add IntoIter, this allows moving the values and their count out of the counter - It may be nicer to modify the counts manually with an iterator rather than via index. --- src/lib.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 925b68e..edb8476 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,7 +158,7 @@ use num_traits::{One, Zero}; use std::borrow::Borrow; -use std::collections::{hash_map::Iter, HashMap}; +use std::collections::{hash_map::{Iter, IntoIter, IterMut}, HashMap}; use std::hash::Hash; use std::iter; use std::ops::{Add, AddAssign, BitAnd, BitOr, Deref, DerefMut, Index, IndexMut, Sub, SubAssign}; @@ -553,6 +553,32 @@ where } } +impl IntoIterator for Counter +where + T: Hash + Eq, + N: PartialOrd + AddAssign + SubAssign + Zero + One, +{ + type Item = (T, N); + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.map.into_iter() + } +} + +impl<'a, T, N> IntoIterator for &'a mut Counter +where + T: Hash + Eq, + N: PartialOrd + AddAssign + SubAssign + Zero + One, +{ + type Item = (&'a T, &'a mut N); + type IntoIter = IterMut<'a, T, N>; + + fn into_iter(self) -> Self::IntoIter { + self.map.iter_mut() + } +} + impl Index<&'_ Q> for Counter where T: Hash + Eq + Borrow, From cec47caf0e983946dd0924760ae229cf23b1b277 Mon Sep 17 00:00:00 2001 From: Kieran Griffiths <20491633@student.uwa.edu.au> Date: Sun, 10 Oct 2021 16:43:00 +0800 Subject: [PATCH 2/5] Removed constraints on counter type parameter for `into_iter` and `iter_mut` --- src/lib.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index edb8476..b720459 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,7 +158,10 @@ use num_traits::{One, Zero}; use std::borrow::Borrow; -use std::collections::{hash_map::{Iter, IntoIter, IterMut}, HashMap}; +use std::collections::{ + hash_map::{IntoIter, Iter, IterMut}, + HashMap, +}; use std::hash::Hash; use std::iter; use std::ops::{Add, AddAssign, BitAnd, BitOr, Deref, DerefMut, Index, IndexMut, Sub, SubAssign}; @@ -556,7 +559,6 @@ where impl IntoIterator for Counter where T: Hash + Eq, - N: PartialOrd + AddAssign + SubAssign + Zero + One, { type Item = (T, N); type IntoIter = IntoIter; @@ -569,7 +571,6 @@ where impl<'a, T, N> IntoIterator for &'a mut Counter where T: Hash + Eq, - N: PartialOrd + AddAssign + SubAssign + Zero + One, { type Item = (&'a T, &'a mut N); type IntoIter = IterMut<'a, T, N>; @@ -864,8 +865,8 @@ where #[cfg(test)] mod tests { - use maplit::hashmap; use super::*; + use maplit::hashmap; use std::collections::HashMap; #[test] From 0c292b41bc2451257e32077e9004292274fa4cb3 Mon Sep 17 00:00:00 2001 From: Kieran Griffiths <20491633@student.uwa.edu.au> Date: Sun, 10 Oct 2021 16:44:23 +0800 Subject: [PATCH 3/5] Removed constraints on counter type parameter for `iter` --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b720459..0830508 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -546,7 +546,6 @@ where impl<'a, T, N> IntoIterator for &'a Counter where T: Hash + Eq, - N: PartialOrd + AddAssign + SubAssign + Zero + One, { type Item = (&'a T, &'a N); type IntoIter = Iter<'a, T, N>; From 9279b50078624016abb93ba4ed20fe846bb5dc27 Mon Sep 17 00:00:00 2001 From: Kieran Griffiths <20491633@student.uwa.edu.au> Date: Sun, 10 Oct 2021 17:05:53 +0800 Subject: [PATCH 4/5] Added docs with doctest to IntoIterator implementations --- src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 0830508..9d0685a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -562,6 +562,26 @@ where type Item = (T, N); type IntoIter = IntoIter; + /// Consumes the Counter to produce an iterator that owns the values it returns + /// + /// # Examples + /// ```rust + /// # use counter::Counter; + /// + /// let counter: Counter<_> = "aaab".chars().collect(); + /// + /// let vec: Vec<_> = counter.into_iter().collect(); + /// + /// for (item, count) in &vec { + /// if item == &'a' { + /// assert_eq!(count, &3); + /// } + /// if item == &'b' { + /// assert_eq!(count, &1); + /// } + /// } + /// ``` + fn into_iter(self) -> Self::IntoIter { self.map.into_iter() } @@ -574,6 +594,24 @@ where type Item = (&'a T, &'a mut N); type IntoIter = IterMut<'a, T, N>; + /// Creates an iterator that provides mutable references to the counts, but keeps the key immutable + /// + /// # Examples + /// ```rust + /// # use counter::Counter; + /// + /// let mut counter: Counter<_> = "aaab".chars().collect(); + /// + /// for (item, count) in &mut counter { + /// if *item == 'a' { + /// // 'a' is so great it counts as 2 + /// *count *= 2; + /// } + /// } + /// + /// assert_eq!(counter[&'a'], 6); + /// assert_eq!(counter[&'b'], 1); + /// ``` fn into_iter(self) -> Self::IntoIter { self.map.iter_mut() } From 1f81e90a34884f7e299be5a4f0bf42b11c41d1c2 Mon Sep 17 00:00:00 2001 From: Kieran Griffiths <20491633@student.uwa.edu.au> Date: Sun, 10 Oct 2021 17:15:58 +0800 Subject: [PATCH 5/5] Changed from import HashMap's iterators to fully qualifying them at use. --- src/lib.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9d0685a..7851304 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,10 +158,7 @@ use num_traits::{One, Zero}; use std::borrow::Borrow; -use std::collections::{ - hash_map::{IntoIter, Iter, IterMut}, - HashMap, -}; +use std::collections::HashMap; use std::hash::Hash; use std::iter; use std::ops::{Add, AddAssign, BitAnd, BitOr, Deref, DerefMut, Index, IndexMut, Sub, SubAssign}; @@ -548,9 +545,9 @@ where T: Hash + Eq, { type Item = (&'a T, &'a N); - type IntoIter = Iter<'a, T, N>; + type IntoIter = std::collections::hash_map::Iter<'a, T, N>; - fn into_iter(self) -> Iter<'a, T, N> { + fn into_iter(self) -> Self::IntoIter { self.map.iter() } } @@ -560,18 +557,18 @@ where T: Hash + Eq, { type Item = (T, N); - type IntoIter = IntoIter; + type IntoIter = std::collections::hash_map::IntoIter; /// Consumes the Counter to produce an iterator that owns the values it returns - /// + /// /// # Examples /// ```rust /// # use counter::Counter; - /// + /// /// let counter: Counter<_> = "aaab".chars().collect(); - /// + /// /// let vec: Vec<_> = counter.into_iter().collect(); - /// + /// /// for (item, count) in &vec { /// if item == &'a' { /// assert_eq!(count, &3); @@ -592,23 +589,23 @@ where T: Hash + Eq, { type Item = (&'a T, &'a mut N); - type IntoIter = IterMut<'a, T, N>; + type IntoIter = std::collections::hash_map::IterMut<'a, T, N>; /// Creates an iterator that provides mutable references to the counts, but keeps the key immutable - /// + /// /// # Examples /// ```rust /// # use counter::Counter; - /// + /// /// let mut counter: Counter<_> = "aaab".chars().collect(); - /// + /// /// for (item, count) in &mut counter { /// if *item == 'a' { /// // 'a' is so great it counts as 2 /// *count *= 2; /// } /// } - /// + /// /// assert_eq!(counter[&'a'], 6); /// assert_eq!(counter[&'b'], 1); /// ```