diff --git a/server/src/engine/mem/tests.rs b/server/src/engine/mem/tests.rs index da30fb68..c627ef72 100644 --- a/server/src/engine/mem/tests.rs +++ b/server/src/engine/mem/tests.rs @@ -251,4 +251,24 @@ mod uarray { let b = a.clone(); assert_eq!(a, b); } + #[test] + fn into_iter_rev() { + let a: UArray = (0u8..8).into_iter().map(|v| v.to_string()).collect(); + let r: Vec = a.into_iter().rev().collect(); + (0..8) + .rev() + .into_iter() + .zip(r.into_iter()) + .for_each(|(x, y)| assert_eq!(x.to_string(), y)); + } + #[test] + fn into_iter_rev_partial() { + let a: UArray = (0u8..8).into_iter().map(|v| v.to_string()).collect(); + let r: Vec = a.into_iter().rev().take(4).collect(); + (4..8) + .rev() + .into_iter() + .zip(r.into_iter()) + .for_each(|(x, y)| assert_eq!(x.to_string(), y)); + } } diff --git a/server/src/engine/mem/uarray.rs b/server/src/engine/mem/uarray.rs index 263f454d..85ced38b 100644 --- a/server/src/engine/mem/uarray.rs +++ b/server/src/engine/mem/uarray.rs @@ -181,6 +181,7 @@ pub struct IntoIter { } impl IntoIter { + #[inline(always)] fn _next(&mut self) -> Option { if self.i == self.l { return None; @@ -194,6 +195,17 @@ impl IntoIter { Some(ret) } } + #[inline(always)] + fn _next_back(&mut self) -> Option { + if self.i == self.l { + return None; + } + unsafe { + self.l -= 1; + // UNSAFE(@ohsayan): we always ensure EOA condition + Some(ptr::read(self.d.a.as_ptr().add(self.l).cast())) + } + } } impl Drop for IntoIter { @@ -218,6 +230,11 @@ impl Iterator for IntoIter { } impl ExactSizeIterator for IntoIter {} impl FusedIterator for IntoIter {} +impl DoubleEndedIterator for IntoIter { + fn next_back(&mut self) -> Option { + self._next_back() + } +} impl IntoIterator for UArray { type Item = T;