use super::{
consumer::{Consumer, DelegateConsumer},
producer::{DelegateProducer, Producer},
Observer,
};
pub trait RingBuffer: Observer + Consumer + Producer {
unsafe fn hold_read(&self, flag: bool) -> bool;
unsafe fn hold_write(&self, flag: bool) -> bool;
fn push_overwrite(&mut self, elem: Self::Item) -> Option<Self::Item> {
let ret = if self.is_full() { self.try_pop() } else { None };
let _ = self.try_push(elem);
ret
}
fn push_iter_overwrite<I: Iterator<Item = Self::Item>>(&mut self, iter: I) {
for elem in iter {
self.push_overwrite(elem);
}
}
fn push_slice_overwrite(&mut self, elems: &[Self::Item])
where
Self::Item: Copy,
{
if elems.len() > self.vacant_len() {
self.skip(usize::min(elems.len() - self.vacant_len(), self.occupied_len()));
}
self.push_slice(if elems.len() > self.vacant_len() {
&elems[(elems.len() - self.vacant_len())..]
} else {
elems
});
}
}
pub trait DelegateRingBuffer: DelegateProducer + DelegateConsumer
where
Self::Base: RingBuffer,
{
}
impl<D: DelegateRingBuffer> RingBuffer for D
where
D::Base: RingBuffer,
{
unsafe fn hold_read(&self, flag: bool) -> bool {
self.base().hold_read(flag)
}
unsafe fn hold_write(&self, flag: bool) -> bool {
self.base().hold_write(flag)
}
#[inline]
fn push_overwrite(&mut self, elem: Self::Item) -> Option<Self::Item> {
self.base_mut().push_overwrite(elem)
}
#[inline]
fn push_iter_overwrite<I: Iterator<Item = Self::Item>>(&mut self, iter: I) {
self.base_mut().push_iter_overwrite(iter)
}
#[inline]
fn push_slice_overwrite(&mut self, elems: &[Self::Item])
where
Self::Item: Copy,
{
self.base_mut().push_slice_overwrite(elems)
}
}