Skip to content

Commit

Permalink
Unify IntoIter and PopIter
Browse files Browse the repository at this point in the history
  • Loading branch information
agerasev committed Aug 17, 2023
1 parent f2beced commit e221881
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 62 deletions.
83 changes: 21 additions & 62 deletions src/traits/consumer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{observer::Observer, utils::modulus};
use crate::utils::{slice_assume_init_mut, slice_assume_init_ref, write_uninit_slice};
use core::{iter::Chain, mem::MaybeUninit, ptr, slice};
use core::{iter::Chain, marker::PhantomData, mem::MaybeUninit, ptr, slice};
#[cfg(feature = "std")]
use std::io::{self, Write};

Expand Down Expand Up @@ -106,12 +106,11 @@ pub trait Consumer: Observer {
count
}

fn into_iter(self) -> IntoIter<Self> {
IntoIter::new(self)
}

/// Returns an iterator that removes items one by one from the ring buffer.
fn pop_iter(&mut self) -> PopIter<'_, Self> {
fn pop_iter(&mut self) -> PopIter<&mut Self, Self>
where
Self: AsMut<Self> + AsRef<Self>,
{
PopIter::new(self)
}

Expand Down Expand Up @@ -214,74 +213,34 @@ pub trait Consumer: Observer {
}
}

pub struct IntoIter<C: Consumer>(C);
impl<C: Consumer> IntoIter<C> {
pub fn new(inner: C) -> Self {
Self(inner)
}
pub fn into_inner(self) -> C {
self.0
}
}
impl<C: Consumer> Iterator for IntoIter<C> {
type Item = C::Item;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.try_pop()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.0.occupied_len(), None)
}
}

/// An iterator that removes items from the ring buffer.
pub struct PopIter<'a, C: Consumer> {
target: &'a C,
slices: (&'a [MaybeUninit<C::Item>], &'a [MaybeUninit<C::Item>]),
len: usize,
pub struct PopIter<U: AsMut<C> + AsRef<C>, C: Consumer> {
inner: U,
_ghost: PhantomData<C>,
}
impl<'a, C: Consumer> PopIter<'a, C> {
pub fn new(target: &'a mut C) -> Self {
let slices = target.occupied_slices();

impl<U: AsMut<C> + AsRef<C>, C: Consumer> PopIter<U, C> {
pub fn new(inner: U) -> Self {
Self {
len: slices.0.len() + slices.1.len(),
slices,
target,
inner,
_ghost: PhantomData,
}
}
pub fn into_inner(self) -> U {
self.inner
}
}
impl<'a, C: Consumer> Iterator for PopIter<'a, C> {

impl<U: AsMut<C> + AsRef<C>, C: Consumer> Iterator for PopIter<U, C> {
type Item = C::Item;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.slices.0.len() {
0 => None,
n => {
let item = unsafe { self.slices.0.get_unchecked(0).assume_init_read() };
if n == 1 {
(self.slices.0, self.slices.1) = (self.slices.1, &[]);
} else {
self.slices.0 = unsafe { self.slices.0.get_unchecked(1..n) };
}
Some(item)
}
}
self.inner.as_mut().try_pop()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<'a, C: Consumer> ExactSizeIterator for PopIter<'a, C> {
fn len(&self) -> usize {
self.slices.0.len() + self.slices.1.len()
}
}
impl<'a, C: Consumer> Drop for PopIter<'a, C> {
fn drop(&mut self) {
unsafe { self.target.advance_read_index(self.len - self.len()) };
(self.inner.as_ref().occupied_len(), None)
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/wrap/caching.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{direct::Obs, frozen::Frozen};
use crate::{
consumer::PopIter,
rb::traits::{RbRef, ToRbRef},
traits::{Consumer, Observer, Producer},
};
Expand Down Expand Up @@ -43,6 +44,17 @@ impl<R: RbRef, const P: bool, const C: bool> ToRbRef for Caching<R, P, C> {
}
}

impl<R: RbRef, const P: bool, const C: bool> AsRef<Self> for Caching<R, P, C> {
fn as_ref(&self) -> &Self {
self
}
}
impl<R: RbRef, const P: bool, const C: bool> AsMut<Self> for Caching<R, P, C> {
fn as_mut(&mut self) -> &mut Self {
self
}
}

impl<R: RbRef, const P: bool, const C: bool> Observer for Caching<R, P, C> {
type Item = <R::Target as Observer>::Item;

Expand Down Expand Up @@ -130,6 +142,14 @@ where
}
}

impl<R: RbRef> IntoIterator for CachingCons<R> {
type Item = <Self as Observer>::Item;
type IntoIter = PopIter<Self, Self>;
fn into_iter(self) -> Self::IntoIter {
PopIter::new(self)
}
}

#[cfg(feature = "std")]
impl<R: RbRef> io::Read for CachingCons<R>
where
Expand Down
20 changes: 20 additions & 0 deletions src/wrap/direct.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::frozen::Frozen;
use crate::{
consumer::PopIter,
rb::traits::{RbRef, ToRbRef},
traits::{consumer::Consumer, producer::Producer, Observer},
};
Expand Down Expand Up @@ -51,6 +52,17 @@ impl<R: RbRef, const P: bool, const C: bool> ToRbRef for Direct<R, P, C> {
}
}

impl<R: RbRef, const P: bool, const C: bool> AsRef<Self> for Direct<R, P, C> {
fn as_ref(&self) -> &Self {
self
}
}
impl<R: RbRef, const P: bool, const C: bool> AsMut<Self> for Direct<R, P, C> {
fn as_mut(&mut self) -> &mut Self {
self
}
}

impl<R: RbRef, const P: bool, const C: bool> Observer for Direct<R, P, C> {
type Item = <R::Target as Observer>::Item;

Expand Down Expand Up @@ -107,6 +119,14 @@ where
}
}

impl<R: RbRef> IntoIterator for Cons<R> {
type Item = <Self as Observer>::Item;
type IntoIter = PopIter<Self, Self>;
fn into_iter(self) -> Self::IntoIter {
PopIter::new(self)
}
}

#[cfg(feature = "std")]
impl<R: RbRef> io::Read for Cons<R>
where
Expand Down
20 changes: 20 additions & 0 deletions src/wrap/frozen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::direct::Obs;
use crate::{
consumer::PopIter,
rb::traits::{RbRef, ToRbRef},
traits::{Consumer, Observer, Producer},
};
Expand Down Expand Up @@ -63,6 +64,17 @@ impl<R: RbRef, const P: bool, const C: bool> ToRbRef for Frozen<R, P, C> {
}
}

impl<R: RbRef, const P: bool, const C: bool> AsRef<Self> for Frozen<R, P, C> {
fn as_ref(&self) -> &Self {
self
}
}
impl<R: RbRef, const P: bool, const C: bool> AsMut<Self> for Frozen<R, P, C> {
fn as_mut(&mut self) -> &mut Self {
self
}
}

impl<R: RbRef, const P: bool, const C: bool> Frozen<R, P, C> {
/// Commit changes to the ring buffer.
pub fn commit(&self) {
Expand Down Expand Up @@ -169,6 +181,14 @@ where
}
}

impl<R: RbRef> IntoIterator for FrozenCons<R> {
type Item = <Self as Observer>::Item;
type IntoIter = PopIter<Self, Self>;
fn into_iter(self) -> Self::IntoIter {
PopIter::new(self)
}
}

#[cfg(feature = "std")]
impl<R: RbRef> io::Read for FrozenCons<R>
where
Expand Down

0 comments on commit e221881

Please sign in to comment.