swap_buffer_queue/buffer/
array.rs

1use core::{cell::Cell, mem::MaybeUninit, ops::Range};
2
3use crate::{
4    buffer::{Buffer, CellBuffer, Drain},
5    utils::init_array,
6};
7
8/// A simple array buffer.
9pub struct ArrayBuffer<T, const N: usize>([Cell<MaybeUninit<T>>; N]);
10
11impl<T, const N: usize> Default for ArrayBuffer<T, N> {
12    fn default() -> Self {
13        Self(init_array(|| Cell::new(MaybeUninit::uninit())))
14    }
15}
16
17// SAFETY: `ArrayBuffer::clear` does clear the inserted range from the buffer
18unsafe impl<T, const N: usize> Buffer for ArrayBuffer<T, N> {
19    type Slice<'a> = &'a mut [T]
20    where
21        T: 'a;
22
23    #[inline]
24    fn capacity(&self) -> usize {
25        self.0.len()
26    }
27
28    #[inline]
29    unsafe fn slice(&mut self, range: Range<usize>) -> Self::Slice<'_> {
30        // SAFETY: [Cell<MaybeUninit<T>>] has the same layout as [T]
31        // and function contract guarantees that the range is initialized
32        unsafe { &mut *(&mut self.0[range] as *mut _ as *mut [T]) }
33    }
34
35    #[inline]
36    unsafe fn clear(&mut self, range: Range<usize>) {
37        for index in range {
38            // SAFETY: function contract guarantees that the range is initialized
39            unsafe { self.remove(index) };
40        }
41    }
42}
43
44// SAFETY: `insert` does initialize the index in the buffer
45unsafe impl<T, const N: usize> CellBuffer<T> for ArrayBuffer<T, N> {
46    unsafe fn insert(&self, index: usize, value: T) {
47        self.0[index].set(MaybeUninit::new(value));
48    }
49}
50
51// SAFETY: `ArrayBuffer::remove` does remove the index from the buffer
52unsafe impl<T, const N: usize> Drain for ArrayBuffer<T, N> {
53    type Value = T;
54    #[inline]
55    unsafe fn remove(&mut self, index: usize) -> Self::Value {
56        // SAFETY: function contract guarantees that the index has been inserted and is then initialized
57        unsafe { self.0[index].replace(MaybeUninit::uninit()).assume_init() }
58    }
59}