#![allow(dead_code)]
use crate::*;
pub trait Sealed {}
impl<T> Sealed for [T; 0] {}
pub struct ArrayBuilder<T, N: ArrayLength> {
array: GenericArray<MaybeUninit<T>, N>,
position: usize,
}
impl<T, N: ArrayLength> ArrayBuilder<T, N> {
#[inline(always)]
pub const fn new() -> ArrayBuilder<T, N> {
ArrayBuilder {
array: GenericArray::uninit(),
position: 0,
}
}
#[inline(always)]
pub unsafe fn extend(&mut self, source: impl Iterator<Item = T>) {
let (destination, position) = (self.array.iter_mut(), &mut self.position);
destination.zip(source).for_each(|(dst, src)| {
dst.write(src);
*position += 1;
});
}
#[inline(always)]
pub const fn is_full(&self) -> bool {
self.position == N::USIZE
}
#[inline(always)]
pub unsafe fn iter_position(&mut self) -> (slice::IterMut<MaybeUninit<T>>, &mut usize) {
(self.array.iter_mut(), &mut self.position)
}
#[inline(always)]
pub const unsafe fn assume_init(self) -> GenericArray<T, N> {
debug_assert!(self.is_full());
let array = ptr::read(&self.array);
mem::forget(self);
GenericArray::assume_init(array)
}
}
impl<T, N: ArrayLength> Drop for ArrayBuilder<T, N> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(
self.array.get_unchecked_mut(..self.position) as *mut [MaybeUninit<T>]
as *mut [T],
);
}
}
}
pub struct IntrusiveArrayBuilder<'a, T, N: ArrayLength> {
array: &'a mut GenericArray<MaybeUninit<T>, N>,
position: usize,
}
impl<'a, T, N: ArrayLength> IntrusiveArrayBuilder<'a, T, N> {
#[inline(always)]
pub const fn new(
array: &'a mut GenericArray<MaybeUninit<T>, N>,
) -> IntrusiveArrayBuilder<'a, T, N> {
IntrusiveArrayBuilder { array, position: 0 }
}
#[inline(always)]
pub unsafe fn extend(&mut self, source: impl Iterator<Item = T>) {
let (destination, position) = (self.array.iter_mut(), &mut self.position);
destination.zip(source).for_each(|(dst, src)| {
dst.write(src);
*position += 1;
});
}
#[inline(always)]
pub const fn is_full(&self) -> bool {
self.position == N::USIZE
}
#[inline(always)]
pub unsafe fn iter_position(&mut self) -> (slice::IterMut<MaybeUninit<T>>, &mut usize) {
(self.array.iter_mut(), &mut self.position)
}
#[inline(always)]
pub const unsafe fn finish(self) {
debug_assert!(self.is_full());
mem::forget(self)
}
#[inline(always)]
pub unsafe fn array_assume_init(array: GenericArray<MaybeUninit<T>, N>) -> GenericArray<T, N> {
ptr::read(&array as *const _ as *const MaybeUninit<GenericArray<T, N>>).assume_init()
}
}
impl<T, N: ArrayLength> Drop for IntrusiveArrayBuilder<'_, T, N> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(
self.array.get_unchecked_mut(..self.position) as *mut [MaybeUninit<T>]
as *mut [T],
);
}
}
}
pub struct ArrayConsumer<T, N: ArrayLength> {
array: ManuallyDrop<GenericArray<T, N>>,
position: usize,
}
impl<T, N: ArrayLength> ArrayConsumer<T, N> {
#[inline(always)]
pub const fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
ArrayConsumer {
array: ManuallyDrop::new(array),
position: 0,
}
}
#[inline(always)]
pub unsafe fn iter_position(&mut self) -> (slice::Iter<T>, &mut usize) {
(self.array.iter(), &mut self.position)
}
}
impl<T, N: ArrayLength> Drop for ArrayConsumer<T, N> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(self.array.get_unchecked_mut(self.position..));
}
}
}