risingwave_common/array/
iterator.rsuse std::iter::TrustedLen;
use super::Array;
pub struct ArrayIterator<'a, A: Array> {
data: &'a A,
pos: usize,
}
impl<'a, A: Array> ArrayIterator<'a, A> {
pub fn new(data: &'a A) -> Self {
Self { data, pos: 0 }
}
}
impl<'a, A: Array> Iterator for ArrayIterator<'a, A> {
type Item = Option<A::RefItem<'a>>;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.data.len() {
None
} else {
let item = unsafe { self.data.value_at_unchecked(self.pos) };
self.pos += 1;
Some(item)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.data.len() - self.pos;
(size, Some(size))
}
}
impl<A: Array> ExactSizeIterator for ArrayIterator<'_, A> {}
unsafe impl<A: Array> TrustedLen for ArrayIterator<'_, A> {}
#[cfg(test)]
mod tests {
use paste::paste;
use super::*;
use crate::array::{ArrayBuilder, ArrayImpl};
use crate::for_all_variants;
macro_rules! test_trusted_len {
($( { $data_type:ident, $variant_name:ident, $suffix_name:ident, $scalar:ty, $scalar_ref:ty, $array:ty, $builder:ty } ),*) => {
$(
paste! {
#[test]
fn [<test_trusted_len_for_ $suffix_name _array>]() {
let mut builder = $builder::new(5);
for _ in 0..5 {
builder.append_null();
}
let array = builder.finish();
let mut iter = array.iter();
assert_eq!(iter.size_hint(), (5, Some(5))); iter.next();
assert_eq!(iter.size_hint(), (4, Some(4))); iter.next();
assert_eq!(iter.size_hint(), (3, Some(3))); iter.nth(0);
assert_eq!(iter.size_hint(), (2, Some(2))); iter.nth(1);
assert_eq!(iter.size_hint(), (0, Some(0)));
let array_impl = ArrayImpl::from(array);
let mut iter = array_impl.iter();
assert_eq!(iter.size_hint(), (5, Some(5))); iter.next();
assert_eq!(iter.size_hint(), (4, Some(4))); iter.next();
assert_eq!(iter.size_hint(), (3, Some(3))); iter.nth(0);
assert_eq!(iter.size_hint(), (2, Some(2))); iter.nth(1);
assert_eq!(iter.size_hint(), (0, Some(0)));
}
}
)*
};
}
for_all_variants! { test_trusted_len }
}