use core::fmt::Debug;
use core::mem::ManuallyDrop;
use crate::ArrayVec;
impl<const C: usize, T> IntoIterator for ArrayVec<C, T> {
type IntoIter = ArrayVecIter<C, T>;
type Item = T;
#[inline]
fn into_iter(self) -> Self::IntoIter {
ArrayVecIter::new(self)
}
}
#[must_use]
pub struct ArrayVecIter<const C: usize, T> {
vec: ManuallyDrop<ArrayVec<C, T>>,
index: usize,
}
impl<const C: usize, T> Drop for ArrayVecIter<C, T> {
#[inline]
fn drop(&mut self) {
let len = self.vec.len();
unsafe {
self.vec.array[self.index..len].assume_init_drop();
}
}
}
impl<const C: usize, T> ArrayVecIter<C, T> {
#[inline]
pub const fn new(vec: ArrayVec<C, T>) -> Self {
Self {
vec: ManuallyDrop::new(vec),
index: 0,
}
}
}
impl<const C: usize, T> Iterator for ArrayVecIter<C, T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.vec.len() {
let item = unsafe { self.vec.array[self.index].assume_init_read() };
self.index = self.index.wrapping_add(1);
Some(item)
} else {
None
}
}
}
impl<const C: usize, T: Debug> Debug for ArrayVecIter<C, T> {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("ArrayVecIter").field(&*self.vec).finish()
}
}
impl<const C: usize, T: Clone> Clone for ArrayVecIter<C, T> {
#[inline]
fn clone(&self) -> Self {
Self {
vec: self.vec.clone(),
index: self.index,
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn debug() {
let expected = "ArrayVecIter([2, 2])";
let iter = ArrayVec::from_array([2; 2]).into_iter();
let str = format!("{iter:?}");
assert_eq!(expected, str);
}
#[test]
fn iter_consuming() {
let vec = ArrayVec::from_array([1u8, 2, 3]);
let collected: Vec<_> = vec.into_iter().collect();
assert_eq!(collected, [1, 2, 3]);
}
#[test]
fn iter_drop_partial() {
let vec = ArrayVec::from_array([String::from("a"), String::from("b"), String::from("c")]);
let mut iter = vec.into_iter();
assert_eq!(iter.next(), Some(String::from("a")));
drop(iter); }
#[test]
fn iter_empty() {
let vec: ArrayVec<4, u8> = ArrayVec::new();
assert_eq!(vec.into_iter().next(), None);
}
#[test]
fn iter_clone_independent() {
let vec = ArrayVec::from_array([1u8, 2, 3]);
let mut iter = vec.into_iter();
iter.next();
let mut iter2 = iter.clone();
assert_eq!(iter.next(), Some(2));
assert_eq!(iter2.next(), Some(2));
}
}