use super::{
Based,
utils::{add_mod, modulus, sub_mod},
};
use core::num::NonZeroUsize;
pub trait Observer {
type Item: Sized;
fn capacity(&self) -> NonZeroUsize;
fn read_index(&self) -> usize;
fn write_index(&self) -> usize;
fn read_is_held(&self) -> bool;
fn write_is_held(&self) -> bool;
fn occupied_len(&self) -> usize {
let modulus = modulus(self);
sub_mod(self.write_index(), self.read_index(), modulus)
}
fn vacant_len(&self) -> usize {
let modulus = modulus(self);
sub_mod(
add_mod(self.read_index(), self.capacity().get(), modulus),
self.write_index(),
modulus,
)
}
#[inline]
fn is_empty(&self) -> bool {
self.read_index() == self.write_index()
}
#[inline]
fn is_full(&self) -> bool {
self.vacant_len() == 0
}
}
pub trait DelegateObserver: Based
where
Self::Base: Observer,
{
}
impl<D: DelegateObserver> Observer for D
where
D::Base: Observer,
{
type Item = <D::Base as Observer>::Item;
#[inline]
fn capacity(&self) -> NonZeroUsize {
self.base().capacity()
}
#[inline]
fn read_index(&self) -> usize {
self.base().read_index()
}
#[inline]
fn write_index(&self) -> usize {
self.base().write_index()
}
#[inline]
fn read_is_held(&self) -> bool {
self.base().read_is_held()
}
#[inline]
fn write_is_held(&self) -> bool {
self.base().write_is_held()
}
#[inline]
fn occupied_len(&self) -> usize {
self.base().occupied_len()
}
#[inline]
fn vacant_len(&self) -> usize {
self.base().vacant_len()
}
#[inline]
fn is_empty(&self) -> bool {
self.base().is_empty()
}
#[inline]
fn is_full(&self) -> bool {
self.base().is_full()
}
}