Closed
Description
The title says it, i dont see any reason why the current unsafe
implementation using pointers is necessary when it could be written entirely in safe code without too much hassle
use core::{iter::FusedIterator, mem::take};
struct IterMut<'a, T> {
slice: &'a mut [T],
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let [first, rest @ ..] = take(&mut self.slice) else {
return None;
};
self.slice = rest;
Some(first)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.slice.len(), Some(self.slice.len()))
}
fn count(self) -> usize
where
Self: Sized,
{
self.slice.len()
}
fn last(mut self) -> Option<Self::Item>
where
Self: Sized,
{
self.next_back()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let Some([value, rest @ ..]) = take(&mut self.slice).get_mut(n..) else {
return None;
};
self.slice = rest;
Some(value)
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
let [rest @ .., last] = take(&mut self.slice) else {
return None;
};
self.slice = rest;
Some(last)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let Some(new_end) = self.slice.len().checked_sub(n) else {
self.slice = &mut [];
return None;
};
let Some([rest @ .., last]) = take(&mut self.slice).get_mut(..new_end) else {
return None;
};
self.slice = rest;
Some(last)
}
}
impl<'a, T> FusedIterator for IterMut<'a, T> {}
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}