Skip to content

Commit f661e2c

Browse files
committed
feat(soavec): add SoAVec::iter and SoAVec::iter_mut
1 parent b9aecc4 commit f661e2c

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed

soavec/src/iter.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
use std::{marker::PhantomData, ptr::NonNull};
6+
7+
use crate::{
8+
SoAVec,
9+
soable::{SoATuple, SoAble},
10+
};
11+
12+
impl<'a, T: SoAble> IntoIterator for &'a SoAVec<T> {
13+
type Item = T::Ref<'a>;
14+
type IntoIter = SoAIter<'a, T>;
15+
16+
fn into_iter(self) -> Self::IntoIter {
17+
self.iter()
18+
}
19+
}
20+
21+
impl<'a, T: SoAble> IntoIterator for &'a mut SoAVec<T> {
22+
type Item = T::Mut<'a>;
23+
type IntoIter = SoAIterMut<'a, T>;
24+
25+
fn into_iter(self) -> Self::IntoIter {
26+
self.iter_mut()
27+
}
28+
}
29+
30+
/// An iterator over the elements of a `SoAVec`.
31+
///
32+
/// This struct is created by the [`iter`] method on [`SoAVec`].
33+
///
34+
/// [`iter`]: SoAVec::iter
35+
pub struct SoAIter<'a, T: SoAble> {
36+
ptr: NonNull<u8>,
37+
capacity: u32,
38+
index: u32,
39+
end: u32,
40+
_marker: PhantomData<&'a T>,
41+
}
42+
43+
impl<'a, T: SoAble> SoAIter<'a, T> {
44+
pub(crate) fn new(ptr: NonNull<u8>, capacity: u32, end: u32) -> SoAIter<'a, T> {
45+
SoAIter {
46+
ptr,
47+
capacity,
48+
index: 0,
49+
end,
50+
_marker: PhantomData,
51+
}
52+
}
53+
}
54+
55+
impl<'a, T: SoAble> Iterator for SoAIter<'a, T> {
56+
type Item = T::Ref<'a>;
57+
58+
fn next(&mut self) -> Option<Self::Item> {
59+
if self.index >= self.end {
60+
return None;
61+
}
62+
let ptrs = unsafe { T::TupleRepr::get_pointers(self.ptr, self.index, self.capacity) };
63+
self.index += 1;
64+
Some(T::as_ref(PhantomData, ptrs))
65+
}
66+
67+
#[inline]
68+
fn size_hint(&self) -> (usize, Option<usize>) {
69+
let len = self.len();
70+
(len, Some(len))
71+
}
72+
}
73+
74+
impl<'a, T: SoAble> ExactSizeIterator for SoAIter<'a, T> {
75+
#[inline]
76+
fn len(&self) -> usize {
77+
(self.end - self.index) as usize
78+
}
79+
}
80+
81+
/// A mutable iterator over the elements of a `SoAVec`.
82+
///
83+
/// This struct is created by the [`iter_mut`] method on [`SoAVec`].
84+
///
85+
/// [`iter_mut`]: SoAVec::iter_mut
86+
pub struct SoAIterMut<'a, T: SoAble> {
87+
ptr: NonNull<u8>,
88+
capacity: u32,
89+
index: u32,
90+
end: u32,
91+
_marker: PhantomData<&'a mut T>,
92+
}
93+
94+
impl<'a, T: SoAble> SoAIterMut<'a, T> {
95+
pub(crate) fn new(ptr: NonNull<u8>, capacity: u32, end: u32) -> SoAIterMut<'a, T> {
96+
SoAIterMut {
97+
ptr,
98+
capacity,
99+
index: 0,
100+
end,
101+
_marker: PhantomData,
102+
}
103+
}
104+
}
105+
106+
impl<'a, T: SoAble> Iterator for SoAIterMut<'a, T> {
107+
type Item = T::Mut<'a>;
108+
109+
fn next(&mut self) -> Option<Self::Item> {
110+
if self.index >= self.end {
111+
return None;
112+
}
113+
let ptrs = unsafe { T::TupleRepr::get_pointers(self.ptr, self.index, self.capacity) };
114+
self.index += 1;
115+
Some(T::as_mut(PhantomData, ptrs))
116+
}
117+
118+
#[inline]
119+
fn size_hint(&self) -> (usize, Option<usize>) {
120+
let len = self.len();
121+
(len, Some(len))
122+
}
123+
}
124+
125+
impl<'a, T: SoAble> ExactSizeIterator for SoAIterMut<'a, T> {
126+
#[inline]
127+
fn len(&self) -> usize {
128+
(self.end - self.index) as usize
129+
}
130+
}

soavec/src/lib.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
//! [`as_slice`]: SoAVec::as_slice
5959
//! [`as_mut_slice`]: SoAVec::as_mut_slice
6060
61+
mod iter;
6162
mod macros;
6263
mod raw_vec;
6364
mod raw_vec_inner;
@@ -66,6 +67,7 @@ mod soable;
6667
use core::marker::PhantomData;
6768
use std::ptr::NonNull;
6869

70+
use iter::{SoAIter, SoAIterMut};
6971
use raw_vec::RawSoAVec;
7072
use raw_vec_inner::AllocError;
7173
pub use soable::{SoATuple, SoAble};
@@ -1100,6 +1102,52 @@ impl<T: SoAble> SoAVec<T> {
11001102
Ok(value)
11011103
}
11021104
}
1105+
1106+
/// Returns an iterator over the soavec.
1107+
///
1108+
/// The iterator yields all items from start to end.
1109+
///
1110+
/// # Examples
1111+
///
1112+
/// ```
1113+
/// use soavec::soavec;
1114+
///
1115+
/// let vec = soavec![(1, 2), (3, 4), (5, 6)].unwrap();
1116+
/// let mut iterator = vec.iter();
1117+
///
1118+
/// assert_eq!(iterator.next(), Some((&1, &2)));
1119+
/// assert_eq!(iterator.next(), Some((&3, &4)));
1120+
/// assert_eq!(iterator.next(), Some((&5, &6)));
1121+
/// assert_eq!(iterator.next(), None);
1122+
/// ```
1123+
#[inline]
1124+
pub fn iter(&self) -> SoAIter<'_, T> {
1125+
SoAIter::new(self.buf.as_ptr(), self.capacity(), self.len())
1126+
}
1127+
1128+
/// Returns an iterator that allows modifying each value.
1129+
///
1130+
/// The iterator yields all items from start to end.
1131+
///
1132+
/// # Examples
1133+
///
1134+
/// ```
1135+
/// use soavec::soavec;
1136+
///
1137+
/// let mut vec = soavec![(1, 2), (3, 4), (5, 6)].unwrap();
1138+
/// for (a, b) in vec.iter_mut() {
1139+
/// *a += 10;
1140+
/// }
1141+
/// assert_eq!(vec.get(0), Some((&11, &2)));
1142+
/// assert_eq!(vec.get(1), Some((&13, &4)));
1143+
/// assert_eq!(vec.get(2), Some((&15, &6)));
1144+
/// ```
1145+
#[inline]
1146+
pub fn iter_mut(&mut self) -> SoAIterMut<'_, T> {
1147+
let len = self.len();
1148+
let capacity = self.capacity();
1149+
SoAIterMut::new(self.buf.as_mut_ptr(), capacity, len)
1150+
}
11031151
}
11041152

11051153
impl<T: SoAble> Drop for SoAVec<T> {
@@ -2084,4 +2132,37 @@ mod tests {
20842132
assert_eq!(**third.a, 168);
20852133
assert_eq!(third.b, &[6]);
20862134
}
2135+
2136+
#[test]
2137+
fn test_iter() {
2138+
let mut vec = SoAVec::<(u32, u32)>::new();
2139+
2140+
vec.push((1, 10)).unwrap();
2141+
vec.push((2, 20)).unwrap();
2142+
vec.push((3, 30)).unwrap();
2143+
2144+
let mut iter = vec.iter();
2145+
assert_eq!(iter.next(), Some((&1, &10)));
2146+
assert_eq!(iter.next(), Some((&2, &20)));
2147+
assert_eq!(iter.next(), Some((&3, &30)));
2148+
assert_eq!(iter.next(), None);
2149+
}
2150+
2151+
#[test]
2152+
fn test_iter_mut() {
2153+
let mut vec = SoAVec::<(u32, u32)>::new();
2154+
2155+
vec.push((1, 10)).unwrap();
2156+
vec.push((2, 20)).unwrap();
2157+
vec.push((3, 30)).unwrap();
2158+
2159+
for (a, b) in vec.iter_mut() {
2160+
*a += 100;
2161+
*b += 5;
2162+
}
2163+
2164+
assert_eq!(vec.get(0), Some((&101, &15)));
2165+
assert_eq!(vec.get(1), Some((&102, &25)));
2166+
assert_eq!(vec.get(2), Some((&103, &35)));
2167+
}
20872168
}

0 commit comments

Comments
 (0)