I'm currently playing around with implementing a stack based vec with limited (const) size and wanted to implement something like Drain
for it.
So currently my problem looks like this (simplified):
pub struct Drain<'a, T> {
small_vec: &'a mut [MaybeUninit<T>],
}
impl<'a, T> Iterator for Drain<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.small_vec.len() == 0 {
None
} else {
let ret = self.small_vec.last_mut().unwrap().as_mut_ptr();
let ret = unsafe { ret.read() };
let new_len = self.small_vec.len() - 1;
let new_vec: &mut [MaybeUninit<T>] = &mut self.small_vec[..new_len];
//transmute is used to extend the lifetime. Is this safe??
self.small_vec = unsafe { core::mem::transmute(new_vec) };
Some(ret)
}
}
}
What I'm wondering is: Is there a better way to shorten the slice and work on the last element?
I found methods like split_last_mut
, but wasn't able to convince rustc of what I was doing. The problem always was when trying to assign self.small_vec
, a short example:
pub struct Drain<'a, T> {
small_vec: &'a mut [MaybeUninit<T>],
}
impl<'a, T> Iterator for Drain<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.small_vec.len() == 0 {
None
} else {
let (ret, front) = self.small_vec.split_last_mut().unwrap();
self.small_vec = front;
let ret = ret.as_mut_ptr();
Some(unsafe { ret.read() })
}
}
}
Maybe it would be useful to have a function similar to split_last_mut
but that modified self
in place and additionally returned the last element?