diff --git a/src/iterable/mod.rs b/src/iterable/mod.rs index 939dddf..202c3da 100644 --- a/src/iterable/mod.rs +++ b/src/iterable/mod.rs @@ -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 /// @@ -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 diff --git a/src/iterable/rev.rs b/src/iterable/rev.rs new file mode 100644 index 0000000..d6e6926 --- /dev/null +++ b/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(pub I) +where + I: Iterable, + I::Iter: DoubleEndedIterator; + +impl Iterable for Reverse +where + I: Iterable, + I::Iter: DoubleEndedIterator, +{ + type Item = I::Item; + type Iter = Rev; + + #[inline] + fn iter(&self) -> Self::Iter { + self.0.iter().rev() + } + + #[inline] + fn len(&self) -> usize { + self.0.len() + } +}