1use super::{utils::modulus, Based};
2use core::{mem::MaybeUninit, num::NonZeroUsize};
34/// Ring buffer observer.
5///
6/// Can observe ring buffer state but cannot safely access its data.
7pub trait Observer {
8type Item: Sized;
910/// Capacity of the ring buffer.
11 ///
12 /// It is constant during the whole ring buffer lifetime.
13fn capacity(&self) -> NonZeroUsize;
1415/// Index of the last item in the ring buffer.
16 ///
17 /// Index value is in range `0..(2 * capacity)`.
18fn read_index(&self) -> usize;
19/// Index of the next empty slot in the ring buffer.
20 ///
21 /// Index value is in range `0..(2 * capacity)`.
22fn write_index(&self) -> usize;
2324/// Get slice between `start` and `end` indices.
25 ///
26 /// # Safety
27 ///
28 /// Slice must not overlap with any mutable slice existing at the same time.
29 ///
30 /// Non-`Sync` items must not be accessed from multiple threads at the same time.
31unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]);
3233/// Get mutable slice between `start` and `end` indices.
34 ///
35 /// # Safety
36 ///
37 /// There must not exist overlapping slices at the same time.
38unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]);
3940/// Whether read end is held by consumer.
41fn read_is_held(&self) -> bool;
42/// Whether write end is held by producer.
43fn write_is_held(&self) -> bool;
4445/// The number of items stored in the buffer.
46 ///
47 /// *Actual number may be greater or less than returned value due to concurring activity of producer or consumer respectively.*
48fn occupied_len(&self) -> usize {
49let modulus = modulus(self);
50 (modulus.get() + self.write_index() - self.read_index()) % modulus
51 }
5253/// The number of remaining free places in the buffer.
54 ///
55 /// *Actual number may be greater or less than returned value due to concurring activity of consumer or producer respectively.*
56fn vacant_len(&self) -> usize {
57let modulus = modulus(self);
58 (self.capacity().get() + self.read_index() - self.write_index()) % modulus
59 }
6061/// Checks if the ring buffer is empty.
62 ///
63 /// *The result may become irrelevant at any time because of concurring producer activity.*
64#[inline]
65fn is_empty(&self) -> bool {
66self.read_index() == self.write_index()
67 }
6869/// Checks if the ring buffer is full.
70 ///
71 /// *The result may become irrelevant at any time because of concurring consumer activity.*
72#[inline]
73fn is_full(&self) -> bool {
74self.vacant_len() == 0
75}
76}
7778/// Trait used for delegating observer methods.
79pub trait DelegateObserver: Based
80where
81Self::Base: Observer,
82{
83}
8485impl<D: DelegateObserver> Observer for D
86where
87D::Base: Observer,
88{
89type Item = <D::Base as Observer>::Item;
9091#[inline]
92fn capacity(&self) -> NonZeroUsize {
93self.base().capacity()
94 }
9596#[inline]
97fn read_index(&self) -> usize {
98self.base().read_index()
99 }
100#[inline]
101fn write_index(&self) -> usize {
102self.base().write_index()
103 }
104105#[inline]
106unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]) {
107self.base().unsafe_slices(start, end)
108 }
109#[inline]
110unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
111self.base().unsafe_slices_mut(start, end)
112 }
113114#[inline]
115fn read_is_held(&self) -> bool {
116self.base().read_is_held()
117 }
118#[inline]
119fn write_is_held(&self) -> bool {
120self.base().write_is_held()
121 }
122123#[inline]
124fn occupied_len(&self) -> usize {
125self.base().occupied_len()
126 }
127128#[inline]
129fn vacant_len(&self) -> usize {
130self.base().vacant_len()
131 }
132133#[inline]
134fn is_empty(&self) -> bool {
135self.base().is_empty()
136 }
137138#[inline]
139fn is_full(&self) -> bool {
140self.base().is_full()
141 }
142}