1 | use super::{RbBase, RbRead, RbWrite}; |
2 | use crate::{ |
3 | consumer::PopIterator, |
4 | utils::{slice_assume_init_mut, slice_assume_init_ref}, |
5 | Consumer, Producer, |
6 | }; |
7 | use core::{ |
8 | iter::Chain, |
9 | ops::{Deref, DerefMut}, |
10 | slice, |
11 | }; |
12 | |
13 | #[cfg (feature = "alloc" )] |
14 | use alloc::{rc::Rc, sync::Arc}; |
15 | |
16 | /// An abstract ring buffer. |
17 | /// |
18 | /// See [`RbBase`] for details of internal implementation of the ring buffer. |
19 | /// |
20 | /// This trait contains methods that takes `&mut self` allowing you to use ring buffer without splitting it into [`Producer`] and [`Consumer`]. |
21 | /// |
22 | /// There are `push*_overwrite` methods that cannot be used from [`Producer`]. |
23 | /// |
24 | /// The ring buffer can be guarded with mutex or other synchronization primitive and be used from different threads without splitting (but now only in blocking mode, obviously). |
25 | pub trait Rb<T>: RbRead<T> + RbWrite<T> { |
26 | /// Returns capacity of the ring buffer. |
27 | /// |
28 | /// The capacity of the buffer is constant. |
29 | #[inline ] |
30 | fn capacity(&self) -> usize { |
31 | <Self as RbBase<T>>::capacity_nonzero(self).get() |
32 | } |
33 | |
34 | /// The number of items stored in the ring buffer. |
35 | fn len(&self) -> usize { |
36 | self.occupied_len() |
37 | } |
38 | |
39 | /// The number of remaining free places in the buffer. |
40 | #[inline ] |
41 | fn free_len(&self) -> usize { |
42 | self.vacant_len() |
43 | } |
44 | |
45 | /// Returns a pair of slices which contain, in order, the contents of the ring buffer. |
46 | #[inline ] |
47 | fn as_slices(&self) -> (&[T], &[T]) { |
48 | unsafe { |
49 | let (left, right) = self.occupied_slices(); |
50 | (slice_assume_init_ref(left), slice_assume_init_ref(right)) |
51 | } |
52 | } |
53 | |
54 | /// Returns a pair of mutable slices which contain, in order, the contents of the ring buffer. |
55 | #[inline ] |
56 | fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) { |
57 | unsafe { |
58 | let (left, right) = self.occupied_slices(); |
59 | (slice_assume_init_mut(left), slice_assume_init_mut(right)) |
60 | } |
61 | } |
62 | |
63 | /// Removes latest item from the ring buffer and returns it. |
64 | /// |
65 | /// Returns `None` if the ring buffer is empty. |
66 | #[inline ] |
67 | fn pop(&mut self) -> Option<T> { |
68 | unsafe { Consumer::new(self as &Self) }.pop() |
69 | } |
70 | |
71 | /// Returns an iterator that removes items one by one from the ring buffer. |
72 | fn pop_iter(&mut self) -> PopIterator<'_, T, RbWrap<Self>> { |
73 | PopIterator::new(unsafe { &*(self as *const Self as *const RbWrap<Self>) }) |
74 | } |
75 | |
76 | /// Returns a front-to-back iterator containing references to items in the ring buffer. |
77 | /// |
78 | /// This iterator does not remove items out of the ring buffer. |
79 | fn iter(&self) -> Chain<slice::Iter<T>, slice::Iter<T>> { |
80 | let (left, right) = self.as_slices(); |
81 | left.iter().chain(right.iter()) |
82 | } |
83 | |
84 | /// Returns a front-to-back iterator that returns mutable references to items in the ring buffer. |
85 | /// |
86 | /// This iterator does not remove items out of the ring buffer. |
87 | fn iter_mut(&mut self) -> Chain<slice::IterMut<T>, slice::IterMut<T>> { |
88 | let (left, right) = self.as_mut_slices(); |
89 | left.iter_mut().chain(right.iter_mut()) |
90 | } |
91 | |
92 | /// Removes exactly `n` items from the buffer and safely drops them. |
93 | /// |
94 | /// *Panics if `n` is greater than number of items in the ring buffer.* |
95 | fn skip(&mut self, count: usize) -> usize { |
96 | assert!(count <= self.len()); |
97 | unsafe { self.skip_internal(Some(count)) }; |
98 | count |
99 | } |
100 | |
101 | /// Removes all items from the buffer and safely drops them. |
102 | /// |
103 | /// Returns the number of deleted items. |
104 | #[inline ] |
105 | fn clear(&mut self) -> usize { |
106 | unsafe { self.skip_internal(None) } |
107 | } |
108 | |
109 | /// Appends an item to the ring buffer. |
110 | /// |
111 | /// On failure returns an `Err` containing the item that hasn't been appended. |
112 | #[inline ] |
113 | fn push(&mut self, elem: T) -> Result<(), T> { |
114 | unsafe { Producer::new(self as &Self) }.push(elem) |
115 | } |
116 | |
117 | /// Pushes an item to the ring buffer overwriting the latest item if the buffer is full. |
118 | /// |
119 | /// Returns overwritten item if overwriting took place. |
120 | fn push_overwrite(&mut self, elem: T) -> Option<T> { |
121 | let ret = if self.is_full() { self.pop() } else { None }; |
122 | let _ = self.push(elem); |
123 | ret |
124 | } |
125 | |
126 | /// Appends items from an iterator to the ring buffer. |
127 | /// Elements that haven't been added to the ring buffer remain in the iterator. |
128 | #[inline ] |
129 | fn push_iter<I: Iterator<Item = T>>(&mut self, iter: &mut I) { |
130 | unsafe { Producer::new(self as &Self) }.push_iter(iter); |
131 | } |
132 | |
133 | /// Appends items from an iterator to the ring buffer. |
134 | /// |
135 | /// *This method consumes iterator until its end.* |
136 | /// Exactly last `min(iter.len(), capacity)` items from the iterator will be stored in the ring buffer. |
137 | fn push_iter_overwrite<I: Iterator<Item = T>>(&mut self, iter: I) { |
138 | for elem in iter { |
139 | self.push_overwrite(elem); |
140 | } |
141 | } |
142 | |
143 | /// Removes first items from the ring buffer and writes them into a slice. |
144 | /// Elements must be [`Copy`]. |
145 | /// |
146 | /// *Panics if slice length is greater than number of items in the ring buffer.* |
147 | fn pop_slice(&mut self, elems: &mut [T]) |
148 | where |
149 | T: Copy, |
150 | { |
151 | assert!(elems.len() <= self.len()); |
152 | let _ = unsafe { Consumer::new(self as &Self) }.pop_slice(elems); |
153 | } |
154 | |
155 | /// Appends items from slice to the ring buffer. |
156 | /// Elements must be [`Copy`]. |
157 | /// |
158 | /// *Panics if slice length is greater than number of free places in the ring buffer.* |
159 | fn push_slice(&mut self, elems: &[T]) |
160 | where |
161 | T: Copy, |
162 | { |
163 | assert!(elems.len() <= self.free_len()); |
164 | let _ = unsafe { Producer::new(self as &Self) }.push_slice(elems); |
165 | } |
166 | |
167 | /// Appends items from slice to the ring buffer overwriting existing items in the ring buffer. |
168 | /// |
169 | /// If the slice length is greater than ring buffer capacity then only last `capacity` items from slice will be stored in the buffer. |
170 | fn push_slice_overwrite(&mut self, elems: &[T]) |
171 | where |
172 | T: Copy, |
173 | { |
174 | if elems.len() > self.free_len() { |
175 | self.skip(usize::min(elems.len() - self.free_len(), self.len())); |
176 | } |
177 | self.push_slice(if elems.len() > self.free_len() { |
178 | &elems[(elems.len() - self.free_len())..] |
179 | } else { |
180 | elems |
181 | }); |
182 | } |
183 | } |
184 | |
185 | /// An abstract reference to the ring buffer. |
186 | pub trait RbRef: Deref<Target = Self::Rb> { |
187 | type Rb: ?Sized; |
188 | } |
189 | impl<B: ?Sized> RbRef for RbWrap<B> { |
190 | type Rb = B; |
191 | } |
192 | impl<'a, B: ?Sized> RbRef for &'a B { |
193 | type Rb = B; |
194 | } |
195 | #[cfg (feature = "alloc" )] |
196 | impl<B: ?Sized> RbRef for Rc<B> { |
197 | type Rb = B; |
198 | } |
199 | #[cfg (feature = "alloc" )] |
200 | impl<B: ?Sized> RbRef for Arc<B> { |
201 | type Rb = B; |
202 | } |
203 | |
204 | /// Just a wrapper for a ring buffer. |
205 | /// |
206 | /// Used to make an owning implementation of [`RbRef`]. |
207 | #[repr (transparent)] |
208 | pub struct RbWrap<B: ?Sized>(pub B); |
209 | impl<B: ?Sized> Deref for RbWrap<B> { |
210 | type Target = B; |
211 | fn deref(&self) -> &B { |
212 | &self.0 |
213 | } |
214 | } |
215 | impl<B: ?Sized> DerefMut for RbWrap<B> { |
216 | fn deref_mut(&mut self) -> &mut B { |
217 | &mut self.0 |
218 | } |
219 | } |
220 | |