From d034215575c79c8c084b7eaf50aee67da89349db Mon Sep 17 00:00:00 2001 From: Jacob Rothstein Date: Sun, 20 Jul 2025 13:35:35 -0700 Subject: [PATCH] feat: add FrozenVec::copy_iter and CopyIter --- src/vec.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/vec.rs b/src/vec.rs index cb701b2..2e15d6f 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -74,6 +74,13 @@ impl FrozenVec { (&*vec).get(index).copied() } } + + /// Returns an iterator of copies of the elements + /// + /// It is safe to push to the vector during iteration + pub fn copy_iter(&self) -> CopyIter<'_, T> { + CopyIter { vec: self, idx: 0 } + } } impl FrozenVec { @@ -292,6 +299,27 @@ where } } +/// Iterator over `FrozenVec`, obtained via [`.copy_iter()`](FrozenVec::copy_iter) +/// +/// It is safe to push to the vector during iteration +pub struct CopyIter<'a, T> { + vec: &'a FrozenVec, + idx: usize, +} + +impl<'a, T: Copy> Iterator for CopyIter<'a, T> { + type Item = T; + + fn next(&mut self) -> Option { + if let Some(ret) = self.vec.get_copy(self.idx) { + self.idx += 1; + Some(ret) + } else { + None + } + } +} + #[test] fn test_iteration() { let vec = vec!["a", "b", "c", "d"]; @@ -305,6 +333,19 @@ fn test_iteration() { assert_eq!(vec.len(), frozen.iter().count()) } +#[test] +fn test_copy_iteration() { + let vec = vec![1, 2, 3, 4, 5]; + let frozen: FrozenVec<_> = vec.clone().into(); + + assert_eq!(vec, frozen.copy_iter().collect::>()); + for (e1, e2) in vec.iter().zip(frozen.copy_iter()) { + assert_eq!(*e1, e2); + } + + assert_eq!(vec.len(), frozen.copy_iter().count()) +} + #[test] fn test_accessors() { let vec: FrozenVec = FrozenVec::new();