use core::{
fmt,
iter::FusedIterator,
marker::PhantomData,
mem::ManuallyDrop,
ops::{Deref, DerefMut, Range},
ptr,
};
use crate::queue::Queue;
mod array;
#[cfg(feature = "alloc")]
mod vec;
pub use array::ArrayBuffer;
#[cfg(feature = "alloc")]
pub use vec::VecBuffer;
pub unsafe trait Buffer: Default {
type Slice<'a>
where
Self: 'a;
fn capacity(&self) -> usize;
unsafe fn slice(&mut self, range: Range<usize>) -> Self::Slice<'_>;
unsafe fn clear(&mut self, range: Range<usize>);
}
pub unsafe trait InsertIntoBuffer<B: Buffer> {
fn size(&self) -> usize;
unsafe fn insert_into(self, buffer: &B, index: usize);
}
pub(crate) unsafe trait CellBuffer<T>: Buffer {
unsafe fn insert(&self, index: usize, value: T);
}
pub struct ValueIter<I>(pub I);
pub trait IntoValueIter: Sized {
type Iter;
fn into_value_iter(self) -> ValueIter<Self::Iter>;
}
impl<I> IntoValueIter for I
where
I: IntoIterator,
I::IntoIter: ExactSizeIterator,
{
type Iter = I::IntoIter;
fn into_value_iter(self) -> ValueIter<Self::Iter> {
ValueIter(self.into_iter())
}
}
unsafe impl<B, I, T> InsertIntoBuffer<B> for ValueIter<I>
where
B: CellBuffer<T>,
I: Iterator<Item = T> + ExactSizeIterator,
{
#[inline]
fn size(&self) -> usize {
self.0.len()
}
#[inline]
unsafe fn insert_into(mut self, buffer: &B, index: usize) {
for i in index..(index + self.0.len()) {
const ERROR: &str = "iterator exhausted before reaching its exact size";
unsafe { buffer.insert(i, self.0.next().expect(ERROR)) };
}
}
}
unsafe impl<B, T, const N: usize> InsertIntoBuffer<B> for [T; N]
where
B: CellBuffer<T>,
{
#[inline]
fn size(&self) -> usize {
N
}
#[inline]
unsafe fn insert_into(self, buffer: &B, index: usize) {
for (i, elt) in self.into_iter().enumerate() {
unsafe { buffer.insert(index + i, elt) };
}
}
}
pub trait Resize: Buffer {
fn resize(&mut self, capacity: usize);
}
pub unsafe trait Drain: Buffer {
type Value;
unsafe fn remove(&mut self, index: usize) -> Self::Value;
}
pub struct BufferSlice<'a, B, N>
where
B: Buffer,
{
queue: &'a Queue<B, N>,
buffer_index: usize,
range: Range<usize>,
slice: B::Slice<'a>,
}
impl<'a, B, N> BufferSlice<'a, B, N>
where
B: Buffer,
{
#[inline]
pub(crate) fn new(
queue: &'a Queue<B, N>,
buffer_index: usize,
range: Range<usize>,
slice: B::Slice<'a>,
) -> Self {
Self {
queue,
buffer_index,
range,
slice,
}
}
#[inline]
pub fn requeue(self) {
let slice = ManuallyDrop::new(self);
slice.queue.requeue(slice.buffer_index, slice.range.clone());
}
}
impl<'a, B, N> fmt::Debug for BufferSlice<'a, B, N>
where
B: Buffer,
B::Slice<'a>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("BufferSlice").field(&self.slice).finish()
}
}
impl<'a, B, N> Deref for BufferSlice<'a, B, N>
where
B: Buffer,
{
type Target = B::Slice<'a>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.slice
}
}
impl<'a, B, N> DerefMut for BufferSlice<'a, B, N>
where
B: Buffer,
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.slice
}
}
impl<'a, B, N> Drop for BufferSlice<'a, B, N>
where
B: Buffer,
{
#[inline]
fn drop(&mut self) {
self.queue.release(self.buffer_index, self.range.clone());
}
}
impl<'a, B, N> IntoIterator for BufferSlice<'a, B, N>
where
B: Buffer + Drain,
{
type Item = B::Value;
type IntoIter = BufferIter<'a, B, N>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
let slice = ManuallyDrop::new(self);
BufferIter {
queue: slice.queue,
buffer_index: slice.buffer_index,
range: slice.range.clone(),
_phantom: PhantomData,
}
}
}
pub struct OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer,
{
queue: Q,
buffer_index: usize,
range: Range<usize>,
_phantom: PhantomData<Queue<B, N>>,
}
pub type BufferIter<'a, B, N> = OwnedBufferIter<&'a Queue<B, N>, B, N>;
impl<'a, B, N> BufferIter<'a, B, N>
where
B: Buffer,
{
#[inline]
pub fn into_slice(self) -> BufferSlice<'a, B, N> {
let iter = ManuallyDrop::new(self);
BufferSlice {
queue: iter.queue,
buffer_index: iter.buffer_index,
range: iter.range.clone(),
slice: iter.queue.get_slice(iter.buffer_index, iter.range.clone()),
}
}
}
impl<Q, B, N> OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer,
{
#[inline]
pub fn with_owned<O>(self, queue: O) -> OwnedBufferIter<O, B, N>
where
O: AsRef<Queue<B, N>>,
{
let iter = ManuallyDrop::new(self);
assert!(
ptr::eq(iter.queue.as_ref(), queue.as_ref()),
"new owner must reference the queue referenced by the iterator"
);
OwnedBufferIter {
queue,
buffer_index: iter.buffer_index,
range: iter.range.clone(),
_phantom: PhantomData,
}
}
}
impl<Q, B, N> fmt::Debug for OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("BufferIter").field(&self.range).finish()
}
}
impl<Q, B, N> Drop for OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer,
{
#[inline]
fn drop(&mut self) {
self.queue
.as_ref()
.requeue(self.buffer_index, self.range.clone());
}
}
impl<Q, B, N> Iterator for OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer + Drain,
{
type Item = B::Value;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.range.is_empty() {
return None;
}
let value = self
.queue
.as_ref()
.remove(self.buffer_index, self.range.start);
self.range.start += 1;
Some(value)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}
impl<Q, B, N> ExactSizeIterator for OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer + Drain,
{
}
impl<Q, B, N> FusedIterator for OwnedBufferIter<Q, B, N>
where
Q: AsRef<Queue<B, N>>,
B: Buffer + Drain,
{
}