From 60b06490f274f3185049dccc9d89dbf5beda30be Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Mon, 3 Mar 2025 18:33:29 +0100 Subject: [PATCH 1/3] IArray and IMap iterators now yields references --- src/array.rs | 46 +++++++++++++++++++------------------- src/map.rs | 63 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/array.rs b/src/array.rs index d02d179..94579c2 100644 --- a/src/array.rs +++ b/src/array.rs @@ -112,14 +112,14 @@ impl From<[T; N]> for IArray { /// An iterator over the elements of an `IArray`. #[derive(Debug)] -pub struct Iter { - array: IArray, +pub struct IArrayIter<'a, T: ImplicitClone + 'static> { + array: &'a IArray, left: usize, right: usize, } -impl Iter { - fn new(array: IArray) -> Self { +impl<'a, T: ImplicitClone + 'static> IArrayIter<'a, T> { + fn new(array: &'a IArray) -> Self { Self { left: 0, right: array.len(), @@ -128,26 +128,26 @@ impl Iter { } } -impl Iterator for Iter { - type Item = T; +impl<'a, T: ImplicitClone + 'static> Iterator for IArrayIter<'a, T> { + type Item = &'a T; fn next(&mut self) -> Option { if self.left >= self.right { return None; } - let item = self.array.get(self.left); + let item = &self.array[self.left]; self.left += 1; - item + Some(item) } } -impl DoubleEndedIterator for Iter { +impl<'a, T: ImplicitClone + 'static> DoubleEndedIterator for IArrayIter<'a, T> { fn next_back(&mut self) -> Option { if self.left >= self.right { return None; } self.right -= 1; - self.array.get(self.right) + Some(&self.array[self.right]) } } @@ -164,18 +164,18 @@ impl IArray { /// let x = IArray::::Static(&[1, 2, 3, 4, 5, 6]); /// let mut iter = x.iter(); /// - /// assert_eq!(Some(1), iter.next()); - /// assert_eq!(Some(6), iter.next_back()); - /// assert_eq!(Some(5), iter.next_back()); - /// assert_eq!(Some(2), iter.next()); - /// assert_eq!(Some(3), iter.next()); - /// assert_eq!(Some(4), iter.next()); + /// assert_eq!(Some(&1), iter.next()); + /// assert_eq!(Some(&6), iter.next_back()); + /// assert_eq!(Some(&5), iter.next_back()); + /// assert_eq!(Some(&2), iter.next()); + /// assert_eq!(Some(&3), iter.next()); + /// assert_eq!(Some(&4), iter.next()); /// assert_eq!(None, iter.next()); /// assert_eq!(None, iter.next_back()); /// ``` #[inline] - pub fn iter(&self) -> Iter { - Iter::new(self.clone()) + pub fn iter(&self) -> IArrayIter { + IArrayIter::new(self) } /// Returns the number of elements in the vector, also referred to @@ -236,21 +236,21 @@ impl IArray { } } - /// Returns a clone of an element at a position or `None` if out of bounds. + /// Returns a reference of an element at a position or `None` if out of bounds. /// /// # Examples /// /// ``` /// # use implicit_clone::unsync::*; /// let v = IArray::::Static(&[10, 40, 30]); - /// assert_eq!(Some(40), v.get(1)); + /// assert_eq!(Some(&40), v.get(1)); /// assert_eq!(None, v.get(3)); /// ``` #[inline] - pub fn get(&self, index: usize) -> Option { + pub fn get(&self, index: usize) -> Option<&T> { match self { - Self::Static(a) => a.get(index).cloned(), - Self::Rc(a) => a.get(index).cloned(), + Self::Static(a) => a.get(index), + Self::Rc(a) => a.get(index), } } diff --git a/src/map.rs b/src/map.rs index b59b9ee..a49b261 100644 --- a/src/map.rs +++ b/src/map.rs @@ -298,12 +298,23 @@ pub enum IMapIter<'a, K, V> { impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator for IMapIter<'a, K, V> { - type Item = (K, V); + type Item = (&'a K, &'a V); fn next(&mut self) -> Option { match self { - Self::Slice(it) => it.next().map(|(k, v)| (k.clone(), v.clone())), - Self::Map(it) => it.next().map(|(k, v)| (k.clone(), v.clone())), + Self::Slice(it) => it.next().map(|(k, v)| (k, v)), + Self::Map(it) => it.next(), + } + } +} + +impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> + DoubleEndedIterator for IMapIter<'a, K, V> +{ + fn next_back(&mut self) -> Option { + match self { + Self::Slice(it) => it.next_back().map(|(k, v)| (k, v)), + Self::Map(it) => it.next_back(), } } } @@ -317,12 +328,23 @@ pub enum IMapKeys<'a, K, V> { impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator for IMapKeys<'a, K, V> { - type Item = K; + type Item = &'a K; fn next(&mut self) -> Option { match self { - Self::Slice(it) => it.next().map(|(k, _)| k.clone()), - Self::Map(it) => it.next().cloned(), + Self::Slice(it) => it.next().map(|(k, _)| k), + Self::Map(it) => it.next(), + } + } +} + +impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> + DoubleEndedIterator for IMapKeys<'a, K, V> +{ + fn next_back(&mut self) -> Option { + match self { + Self::Slice(it) => it.next_back().map(|(k, _)| k), + Self::Map(it) => it.next_back(), } } } @@ -336,12 +358,23 @@ pub enum IMapValues<'a, K, V> { impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator for IMapValues<'a, K, V> { - type Item = V; + type Item = &'a V; fn next(&mut self) -> Option { match self { - Self::Slice(it) => it.next().map(|(_, v)| v.clone()), - Self::Map(it) => it.next().cloned(), + Self::Slice(it) => it.next().map(|(_, v)| v), + Self::Map(it) => it.next(), + } + } +} + +impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> + DoubleEndedIterator for IMapValues<'a, K, V> +{ + fn next_back(&mut self) -> Option { + match self { + Self::Slice(it) => it.next_back().map(|(_, v)| v), + Self::Map(it) => it.next_back(), } } } @@ -413,12 +446,12 @@ mod test_map { assert_eq!( flattened_vec, [ - (IString::from("foo1"), 1), - (IString::from("bar1"), 2), - (IString::from("baz1"), 3), - (IString::from("foo2"), 4), - (IString::from("bar2"), 5), - (IString::from("baz2"), 6), + (&IString::from("foo1"), &1), + (&IString::from("bar1"), &2), + (&IString::from("baz1"), &3), + (&IString::from("foo2"), &4), + (&IString::from("bar2"), &5), + (&IString::from("baz2"), &6), ] ); } From d50416c84940d412e0c0b21d47756b83ac0b25d1 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Wed, 5 Mar 2025 13:43:01 +0100 Subject: [PATCH 2/3] Implement into_iter for IArray --- src/array.rs | 67 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/src/array.rs b/src/array.rs index 94579c2..8126f16 100644 --- a/src/array.rs +++ b/src/array.rs @@ -118,16 +118,6 @@ pub struct IArrayIter<'a, T: ImplicitClone + 'static> { right: usize, } -impl<'a, T: ImplicitClone + 'static> IArrayIter<'a, T> { - fn new(array: &'a IArray) -> Self { - Self { - left: 0, - right: array.len(), - array, - } - } -} - impl<'a, T: ImplicitClone + 'static> Iterator for IArrayIter<'a, T> { type Item = &'a T; @@ -151,6 +141,50 @@ impl<'a, T: ImplicitClone + 'static> DoubleEndedIterator for IArrayIter<'a, T> { } } +/// An iterator over the cloned elements of an `IArray`. +#[derive(Debug)] +pub struct IArrayIntoIter { + array: IArray, + left: usize, + right: usize, +} + +impl IntoIterator for IArray { + type Item = T; + type IntoIter = IArrayIntoIter; + + fn into_iter(self) -> ::IntoIter { + IArrayIntoIter { + left: 0, + right: self.len(), + array: self, + } + } +} + +impl Iterator for IArrayIntoIter { + type Item = T; + + fn next(&mut self) -> Option { + if self.left >= self.right { + return None; + } + let item = &self.array[self.left]; + self.left += 1; + Some(item.clone()) + } +} + +impl DoubleEndedIterator for IArrayIntoIter { + fn next_back(&mut self) -> Option { + if self.left >= self.right { + return None; + } + self.right -= 1; + Some(self.array[self.right].clone()) + } +} + impl IArray { /// An empty array without allocation. pub const EMPTY: Self = Self::Static(&[]); @@ -175,7 +209,11 @@ impl IArray { /// ``` #[inline] pub fn iter(&self) -> IArrayIter { - IArrayIter::new(self) + IArrayIter { + left: 0, + right: self.len(), + array: self, + } } /// Returns the number of elements in the vector, also referred to @@ -508,4 +546,11 @@ mod test_array { impl ImplicitClone for _Node {} } + + #[test] + fn into_iter() { + let array = IArray::Static(&[1, 2, 3]); + assert_eq!(array.iter().next().unwrap(), &1); + assert_eq!(array.into_iter().next().unwrap(), 1); + } } From 637c46e142ceb683bbcb9620bd439d0a13758f40 Mon Sep 17 00:00:00 2001 From: Kirill Semyonkin Date: Wed, 5 Mar 2025 16:15:44 +0300 Subject: [PATCH 3/3] Try removing IArrayIter --- src/array.rs | 58 ---------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/src/array.rs b/src/array.rs index 8126f16..9813936 100644 --- a/src/array.rs +++ b/src/array.rs @@ -110,37 +110,6 @@ impl From<[T; N]> for IArray { } } -/// An iterator over the elements of an `IArray`. -#[derive(Debug)] -pub struct IArrayIter<'a, T: ImplicitClone + 'static> { - array: &'a IArray, - left: usize, - right: usize, -} - -impl<'a, T: ImplicitClone + 'static> Iterator for IArrayIter<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option { - if self.left >= self.right { - return None; - } - let item = &self.array[self.left]; - self.left += 1; - Some(item) - } -} - -impl<'a, T: ImplicitClone + 'static> DoubleEndedIterator for IArrayIter<'a, T> { - fn next_back(&mut self) -> Option { - if self.left >= self.right { - return None; - } - self.right -= 1; - Some(&self.array[self.right]) - } -} - /// An iterator over the cloned elements of an `IArray`. #[derive(Debug)] pub struct IArrayIntoIter { @@ -189,33 +158,6 @@ impl IArray { /// An empty array without allocation. pub const EMPTY: Self = Self::Static(&[]); - /// Returns a double-ended iterator over the array. - /// - /// # Examples - /// - /// ``` - /// # use implicit_clone::unsync::*; - /// let x = IArray::::Static(&[1, 2, 3, 4, 5, 6]); - /// let mut iter = x.iter(); - /// - /// assert_eq!(Some(&1), iter.next()); - /// assert_eq!(Some(&6), iter.next_back()); - /// assert_eq!(Some(&5), iter.next_back()); - /// assert_eq!(Some(&2), iter.next()); - /// assert_eq!(Some(&3), iter.next()); - /// assert_eq!(Some(&4), iter.next()); - /// assert_eq!(None, iter.next()); - /// assert_eq!(None, iter.next_back()); - /// ``` - #[inline] - pub fn iter(&self) -> IArrayIter { - IArrayIter { - left: 0, - right: self.len(), - array: self, - } - } - /// Returns the number of elements in the vector, also referred to /// as its 'length'. ///