use super::*;
pub struct SetLenOnDrop<'a> {
len: &'a mut usize,
local: usize,
}
impl<'a> SetLenOnDrop<'a> {
pub fn new(len: &'a mut usize) -> Self {
Self { local: *len, len }
}
pub fn inc(&mut self, count: usize) {
self.local += count;
}
}
impl Drop for SetLenOnDrop<'_> {
fn drop(&mut self) {
*self.len = self.local;
}
}
impl<T: Clone, const N: usize> ArrayVec<T, { N }> {
pub fn extend_from_slice(&mut self, slice: &[T]) {
self.extend_slice(slice)
}
}
trait ExtendSlice<T> {
fn extend_slice(&mut self, slice: &[T]);
}
impl<T: Clone, const N: usize> ExtendSlice<T> for ArrayVec<T, { N }> {
default fn extend_slice(&mut self, slice: &[T]) {
if self.len + slice.len() > N {
let mut ptr = unsafe { self.as_mut_ptr().add(self.len) };
let mut len = SetLenOnDrop::new(&mut self.len);
for i in slice.iter() {
unsafe {
ptr.write(i.clone());
ptr = ptr.add(1);
len.inc(1);
}
}
}
}
}
impl<T: Copy, const N: usize> ExtendSlice<T> for ArrayVec<T, { N }> {
default fn extend_slice(&mut self, slice: &[T]) {
if self.len + slice.len() <= N {
unsafe {
self.copy_from_slice_unchecked(slice);
}
}
}
}