Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add iterable::Reverse. #41

Merged
merged 1 commit into from Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/iterable/mod.rs
Expand Up @@ -4,11 +4,15 @@
//! Essentially, it provides a set of handy utilities as a wrapper around
//! iterators.

mod rev;
pub use rev::Reverse;

/// The trait [`Iterable`] represents a streamable object that can produce
/// an arbitrary number of streams of length [`Iterable::len`](Iterable::len).
///
/// An Iterable is pretty much like an [`IntoIterator`] that can be copied over
/// and over, and has an hint of the length. Copies are meant to be shared across threads safely.
/// and over, and has an hint of the length. Copies are meant to be shared
/// across threads safely.
///
/// # Examples
///
Expand Down Expand Up @@ -41,8 +45,8 @@
/// [`Borrow`](std::borrow::Borrow) in order to avoid copying the contents of
/// the iterator..
///
/// The `Iter` associated type has a lifetime that is independent from that of the
/// [`Iterable`] object. This means that implicitly a copy of the relevant
/// The `Iter` associated type has a lifetime that is independent from that of
/// the [`Iterable`] object. This means that implicitly a copy of the relevant
/// contents of the object will happen whenever
/// [`Iterable::iter`](crate::iterable::Iterable::iter) is called. This might
/// change in the future as associated type constructors
Expand Down
44 changes: 44 additions & 0 deletions src/iterable/rev.rs
@@ -0,0 +1,44 @@
use super::Iterable;
use crate::iter::Rev;

/// Stream that goes over an `[ExactSizeIterator]` in reverse order.
///
/// This stream allows to switch fast from little endian ordering used in
/// time-efficient algorithms, e.g. in slices `&[T]` into big endia ordering
/// (used in space-efficient algorithms.
///
/// # Examples
/// ```
/// use ark_std::iterable::{Iterable, Reverse};
///
/// let le_v = &[1, 2, 3];
/// let be_v = Reverse(le_v);
/// let mut be_v_iter = be_v.iter();
/// assert_eq!(be_v_iter.next(), Some(&3));
/// assert_eq!(be_v_iter.next(), Some(&2));
/// assert_eq!(be_v_iter.next(), Some(&1));
/// ```
#[derive(Clone, Copy)]
pub struct Reverse<I>(pub I)
where
I: Iterable,
I::Iter: DoubleEndedIterator;

impl<I> Iterable for Reverse<I>
where
I: Iterable,
I::Iter: DoubleEndedIterator,
{
type Item = I::Item;
type Iter = Rev<I::Iter>;

#[inline]
fn iter(&self) -> Self::Iter {
self.0.iter().rev()
}

#[inline]
fn len(&self) -> usize {
self.0.len()
}
}