1use super::{
2 observer::{DelegateObserver, Observer},
3 utils::{add_mod, modulus},
4};
5use crate::utils::{move_uninit_slice, slice_as_uninit_mut, slice_assume_init_mut, slice_assume_init_ref};
6use core::{
7 iter::Chain,
8 mem::{self, MaybeUninit},
9 ptr, slice,
10};
11#[cfg(feature = "std")]
12use std::io::{self, Write};
13
14pub trait Consumer: Observer {
16 unsafe fn set_read_index(&self, value: usize);
24
25 unsafe fn advance_read_index(&self, count: usize) {
33 unsafe { self.set_read_index(add_mod(self.read_index(), count, modulus(self))) };
34 }
35
36 fn occupied_slices(&self) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]) {
50 unsafe { self.unsafe_slices(self.read_index(), self.write_index()) }
51 }
52
53 unsafe fn occupied_slices_mut(&mut self) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
61 unsafe { self.unsafe_slices_mut(self.read_index(), self.write_index()) }
62 }
63
64 #[inline]
66 fn as_slices(&self) -> (&[Self::Item], &[Self::Item]) {
67 unsafe {
68 let (left, right) = self.occupied_slices();
69 (slice_assume_init_ref(left), slice_assume_init_ref(right))
70 }
71 }
72
73 #[inline]
75 fn as_mut_slices(&mut self) -> (&mut [Self::Item], &mut [Self::Item]) {
76 unsafe {
77 let (left, right) = self.occupied_slices_mut();
78 (slice_assume_init_mut(left), slice_assume_init_mut(right))
79 }
80 }
81
82 #[inline]
84 fn first(&self) -> Option<&Self::Item> {
85 self.as_slices().0.first()
86 }
87 #[inline]
89 fn first_mut(&mut self) -> Option<&mut Self::Item> {
90 self.as_mut_slices().0.first_mut()
91 }
92 fn last(&self) -> Option<&Self::Item> {
96 let (first, second) = self.as_slices();
97 if second.is_empty() { first.last() } else { second.last() }
98 }
99 fn last_mut(&mut self) -> Option<&mut Self::Item> {
103 let (first, second) = self.as_mut_slices();
104 if second.is_empty() { first.last_mut() } else { second.last_mut() }
105 }
106
107 fn try_pop(&mut self) -> Option<Self::Item> {
111 if !self.is_empty() {
112 let elem = unsafe { self.occupied_slices().0.get_unchecked(0).assume_init_read() };
113 unsafe { self.advance_read_index(1) };
114 Some(elem)
115 } else {
116 None
117 }
118 }
119
120 fn try_peek(&self) -> Option<&Self::Item> {
124 if !self.is_empty() {
125 Some(unsafe { self.occupied_slices().0.get_unchecked(0).assume_init_ref() })
126 } else {
127 None
128 }
129 }
130
131 fn peek_slice_uninit(&self, elems: &mut [MaybeUninit<Self::Item>]) -> usize {
135 let (left, right) = self.occupied_slices();
136 if elems.len() < left.len() {
137 move_uninit_slice(elems, unsafe { left.get_unchecked(..elems.len()) });
138 elems.len()
139 } else {
140 let (left_elems, elems) = elems.split_at_mut(left.len());
141 move_uninit_slice(left_elems, left);
142 left.len()
143 + if elems.len() < right.len() {
144 move_uninit_slice(elems, unsafe { right.get_unchecked(..elems.len()) });
145 elems.len()
146 } else {
147 move_uninit_slice(unsafe { elems.get_unchecked_mut(..right.len()) }, right);
148 right.len()
149 }
150 }
151 }
152
153 fn peek_slice(&self, elems: &mut [Self::Item]) -> usize
157 where
158 Self::Item: Copy,
159 {
160 self.peek_slice_uninit(unsafe { slice_as_uninit_mut(elems) })
161 }
162
163 fn pop_slice_uninit(&mut self, elems: &mut [MaybeUninit<Self::Item>]) -> usize {
167 let count = self.peek_slice_uninit(elems);
168 unsafe { self.advance_read_index(count) };
169 count
170 }
171
172 fn pop_slice(&mut self, elems: &mut [Self::Item]) -> usize
176 where
177 Self::Item: Copy,
178 {
179 self.pop_slice_uninit(unsafe { slice_as_uninit_mut(elems) })
180 }
181
182 fn pop_iter(&mut self) -> PopIter<'_, Self> {
184 PopIter::new(self)
185 }
186
187 fn iter(&self) -> Iter<'_, Self> {
191 let (left, right) = self.as_slices();
192 left.iter().chain(right.iter())
193 }
194
195 fn iter_mut(&mut self) -> IterMut<'_, Self> {
199 let (left, right) = self.as_mut_slices();
200 left.iter_mut().chain(right.iter_mut())
201 }
202
203 fn skip(&mut self, count: usize) -> usize {
226 if !mem::needs_drop::<Self::Item>() {
227 let count = usize::min(count, self.occupied_len());
230 unsafe { self.advance_read_index(count) };
231 return count;
232 }
233
234 struct Guard<'a, C: Consumer + ?Sized> {
235 consumer: &'a mut C,
236 count: usize,
237 }
238 impl<C: Consumer + ?Sized> Drop for Guard<'_, C> {
239 fn drop(&mut self) {
240 unsafe { self.consumer.advance_read_index(self.count) };
243 }
244 }
245
246 let mut guard = Guard { consumer: self, count: 0 };
247 let (left, right) = unsafe { guard.consumer.occupied_slices_mut() };
248 for elem in left.iter_mut().chain(right.iter_mut()).take(count) {
249 guard.count += 1;
252 unsafe { ptr::drop_in_place(elem.as_mut_ptr()) };
253 }
254 guard.count
255 }
256
257 fn clear(&mut self) -> usize {
261 self.skip(usize::MAX)
262 }
263
264 #[cfg(feature = "std")]
265 fn write_into<S: Write>(&mut self, writer: &mut S, count: Option<usize>) -> Option<io::Result<usize>>
275 where
276 Self: Consumer<Item = u8>,
277 {
278 let (left, _) = self.occupied_slices();
279 let count = usize::min(count.unwrap_or(left.len()), left.len());
280 if count == 0 {
281 return None;
282 }
283 let left_init = unsafe { slice_assume_init_ref(&left[..count]) };
284
285 let write_count = match writer.write(left_init) {
286 Ok(n) => n,
287 Err(e) => return Some(Err(e)),
288 };
289 assert!(write_count <= count);
290 unsafe { self.advance_read_index(write_count) };
291 Some(Ok(write_count))
292 }
293}
294
295pub struct IntoIter<C: Consumer + ?Sized> {
297 inner: C,
298}
299
300impl<C: Consumer> IntoIter<C> {
301 pub fn new(inner: C) -> Self {
302 Self { inner }
303 }
304 pub fn into_inner(self) -> C {
305 self.inner
306 }
307}
308
309impl<C: Consumer> Iterator for IntoIter<C> {
310 type Item = C::Item;
311
312 #[inline]
313 fn next(&mut self) -> Option<Self::Item> {
314 self.inner.try_pop()
315 }
316 #[inline]
317 fn size_hint(&self) -> (usize, Option<usize>) {
318 (self.inner.occupied_len(), None)
319 }
320}
321
322pub struct PopIter<'a, C: Consumer + ?Sized> {
327 inner: &'a C,
328 iter: Chain<slice::Iter<'a, MaybeUninit<C::Item>>, slice::Iter<'a, MaybeUninit<C::Item>>>,
329 read: usize,
330 modulus: usize,
331 remaining: usize,
332}
333
334impl<'a, C: Consumer + ?Sized> PopIter<'a, C> {
335 pub fn new(inner: &'a mut C) -> Self {
337 let (left, right) = inner.occupied_slices();
338 Self {
339 inner,
340 iter: left.iter().chain(right),
341 read: inner.read_index(),
342 modulus: modulus(inner).get(),
343 remaining: left.len() + right.len(),
344 }
345 }
346
347 #[deprecated(note = "each yielded item is removed immediately; remove this call")]
349 pub fn commit(&mut self) {}
350}
351
352impl<C: Consumer + ?Sized> Iterator for PopIter<'_, C> {
353 type Item = C::Item;
354
355 #[inline]
356 fn next(&mut self) -> Option<Self::Item> {
357 let item = unsafe { self.iter.next()?.assume_init_read() };
358 self.read += 1;
359 if self.read == self.modulus {
360 self.read = 0;
361 }
362 self.remaining -= 1;
363 unsafe { self.inner.set_read_index(self.read) };
366 Some(item)
367 }
368 #[inline]
369 fn size_hint(&self) -> (usize, Option<usize>) {
370 (self.remaining, Some(self.remaining))
371 }
372}
373
374impl<C: Consumer + ?Sized> ExactSizeIterator for PopIter<'_, C> {}
375
376#[allow(type_alias_bounds)]
380pub type Iter<'a, C: Consumer> = Chain<slice::Iter<'a, C::Item>, slice::Iter<'a, C::Item>>;
381
382#[allow(type_alias_bounds)]
386pub type IterMut<'a, C: Consumer> = Chain<slice::IterMut<'a, C::Item>, slice::IterMut<'a, C::Item>>;
387
388pub trait DelegateConsumer: DelegateObserver
390where
391 Self::Base: Consumer,
392{
393}
394impl<D: DelegateConsumer> Consumer for D
395where
396 D::Base: Consumer,
397{
398 #[inline]
399 unsafe fn set_read_index(&self, value: usize) {
400 unsafe { self.base().set_read_index(value) }
401 }
402 #[inline]
403 unsafe fn advance_read_index(&self, count: usize) {
404 unsafe { self.base().advance_read_index(count) }
405 }
406
407 #[inline]
408 fn occupied_slices(&self) -> (&[core::mem::MaybeUninit<Self::Item>], &[core::mem::MaybeUninit<Self::Item>]) {
409 self.base().occupied_slices()
410 }
411
412 #[inline]
413 unsafe fn occupied_slices_mut(&mut self) -> (&mut [core::mem::MaybeUninit<Self::Item>], &mut [core::mem::MaybeUninit<Self::Item>]) {
414 unsafe { self.base_mut().occupied_slices_mut() }
415 }
416
417 #[inline]
418 fn as_slices(&self) -> (&[Self::Item], &[Self::Item]) {
419 self.base().as_slices()
420 }
421
422 #[inline]
423 fn as_mut_slices(&mut self) -> (&mut [Self::Item], &mut [Self::Item]) {
424 self.base_mut().as_mut_slices()
425 }
426
427 #[inline]
428 fn try_pop(&mut self) -> Option<Self::Item> {
429 self.base_mut().try_pop()
430 }
431
432 #[inline]
433 fn pop_slice(&mut self, elems: &mut [Self::Item]) -> usize
434 where
435 Self::Item: Copy,
436 {
437 self.base_mut().pop_slice(elems)
438 }
439
440 #[inline]
441 fn iter(&self) -> Iter<'_, Self> {
442 self.base().iter()
443 }
444
445 #[inline]
446 fn iter_mut(&mut self) -> IterMut<'_, Self> {
447 self.base_mut().iter_mut()
448 }
449
450 #[inline]
451 fn skip(&mut self, count: usize) -> usize {
452 self.base_mut().skip(count)
453 }
454
455 #[inline]
456 fn clear(&mut self) -> usize {
457 self.base_mut().clear()
458 }
459}
460
461macro_rules! impl_consumer_traits {
462 ($type:ident $(< $( $param:tt $( : $first_bound:tt $(+ $next_bound:tt )* )? ),+ >)?) => {
463 impl $(< $( $param $( : $first_bound $(+ $next_bound )* )? ),+ >)? core::iter::IntoIterator for $type $(< $( $param ),+ >)? where Self: Sized {
464 type Item = <Self as $crate::traits::Observer>::Item;
465 type IntoIter = $crate::traits::consumer::IntoIter<Self>;
466 fn into_iter(self) -> Self::IntoIter {
467 $crate::traits::consumer::IntoIter::new(self)
468 }
469 }
470
471 #[cfg(feature = "std")]
472 impl $(< $( $param $( : $first_bound $(+ $next_bound )* )? ),+ >)? std::io::Read for $type $(< $( $param ),+ >)?
473 where
474 Self: $crate::traits::Consumer<Item = u8>,
475 {
476 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
477 let n = self.pop_slice(buf);
478 if n == 0 {
479 Err(std::io::ErrorKind::WouldBlock.into())
480 } else {
481 Ok(n)
482 }
483 }
484 }
485 };
486}
487pub(crate) use impl_consumer_traits;