#![cfg_attr(not(test), no_std)]
#![deny(warnings)]
#![warn(
clippy::all,
clippy::missing_docs_in_private_items,
clippy::nursery,
clippy::pedantic,
clippy::restriction,
clippy::cargo,
elided_lifetimes_in_paths,
missing_docs,
rustdoc::all
)]
#![warn(
absolute_paths_not_starting_with_crate,
box_pointers,
elided_lifetimes_in_paths,
explicit_outlives_requirements,
keyword_idents,
let_underscore_drop,
macro_use_extern_crate,
meta_variable_misuse,
missing_abi,
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
non_ascii_idents,
noop_method_call,
pointer_structural_match,
rust_2021_incompatible_closure_captures,
rust_2021_incompatible_or_patterns,
rust_2021_prefixes_incompatible_syntax,
rust_2021_prelude_collisions,
single_use_lifetimes,
trivial_casts,
trivial_numeric_casts,
unreachable_pub,
unsafe_code,
unsafe_op_in_unsafe_fn,
unstable_features,
unused_crate_dependencies,
unused_extern_crates,
unused_import_braces,
unused_lifetimes,
unused_macro_rules,
unused_qualifications,
unused_results,
unused_tuple_struct_fields,
variant_size_differences
)]
#![allow(
box_pointers,
clippy::blanket_clippy_restriction_lints,
clippy::implicit_return,
clippy::inline_always,
clippy::match_ref_pats,
clippy::mod_module_files,
clippy::pub_use,
clippy::question_mark_used,
clippy::separated_literal_suffix,
clippy::single_char_lifetime_names
)]
extern crate alloc;
pub mod cache;
pub mod indexed;
#[cfg(test)]
mod test;
#[allow(missing_debug_implementations, clippy::partial_pub_fields)]
pub struct Reiterator<I: Iterator> {
cache: cache::Cache<I>,
pub index: usize,
}
impl<I: Iterator> Reiterator<I> {
#[inline(always)]
pub fn new<II: IntoIterator<IntoIter = I>>(into_iter: II) -> Self {
use cache::Cached;
Self {
cache: into_iter.cached(),
index: 0,
}
}
#[inline(always)]
pub fn restart(&mut self) {
self.index = 0;
}
#[inline]
#[must_use]
pub fn at(&mut self, index: usize) -> Option<&I::Item> {
self.cache.get(index).map(|item| {
let pointer: *const _ = item;
#[allow(unsafe_code)]
unsafe {
&*pointer
}
})
}
#[inline(always)]
#[must_use]
pub fn get(&mut self) -> Option<indexed::Indexed<'_, I::Item>> {
Some(indexed::Indexed {
index: self.index,
value: self.at(self.index)?,
})
}
#[inline(always)]
pub fn lazy_next(&mut self) -> Option<usize> {
self.index.checked_add(1).map(|incr| {
self.index = incr;
incr
})
}
#[inline(always)]
pub fn next(&mut self) -> Option<indexed::Indexed<'_, I::Item>> {
let index = self.index;
let _ = self.lazy_next()?;
self.at(index)
.map(|value| indexed::Indexed { index, value })
}
#[inline(always)]
#[must_use]
pub fn map<UnReferenceInator: FnMut(indexed::Indexed<'_, I::Item>) -> Output, Output>(
self,
un_reference_inator: UnReferenceInator,
) -> Map<I, UnReferenceInator, Output> {
Map {
iter: self,
un_reference_inator,
}
}
#[inline(always)]
#[must_use]
pub fn map_indices<UnReferenceInator: FnMut(usize) -> Output, Output>(
self,
un_reference_inator: UnReferenceInator,
) -> MapIndices<I, UnReferenceInator, Output> {
MapIndices {
iter: self,
un_reference_inator,
}
}
#[inline(always)]
#[must_use]
pub fn map_values<UnReferenceInator: FnMut(&I::Item) -> Output, Output>(
self,
un_reference_inator: UnReferenceInator,
) -> MapValues<I, UnReferenceInator, Output> {
MapValues {
iter: self,
un_reference_inator,
}
}
#[inline(always)]
#[must_use]
pub fn cloned(
self,
) -> Map<I, impl FnMut(indexed::Indexed<'_, I::Item>) -> (usize, I::Item), (usize, I::Item)>
where
I::Item: Clone,
{
Map {
iter: self,
un_reference_inator: |indexed| (indexed.index, indexed.value.clone()),
}
}
}
#[allow(missing_debug_implementations)]
pub struct Map<
I: Iterator,
UnReferenceInator: FnMut(indexed::Indexed<'_, I::Item>) -> Output,
Output,
> {
iter: Reiterator<I>,
un_reference_inator: UnReferenceInator,
}
impl<I: Iterator, UnReferenceInator: FnMut(indexed::Indexed<'_, I::Item>) -> Output, Output>
Iterator for Map<I, UnReferenceInator, Output>
{
type Item = Output;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(&mut self.un_reference_inator)
}
}
impl<I: Iterator, UnReferenceInator: FnMut(indexed::Indexed<'_, I::Item>) -> Output, Output>
ExactSizeIterator for Map<I, UnReferenceInator, Output>
{
}
#[allow(missing_debug_implementations)]
pub struct MapIndices<I: Iterator, UnReferenceInator: FnMut(usize) -> Output, Output> {
iter: Reiterator<I>,
un_reference_inator: UnReferenceInator,
}
impl<I: Iterator, UnReferenceInator: FnMut(usize) -> Output, Output> Iterator
for MapIndices<I, UnReferenceInator, Output>
{
type Item = Output;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|indexed| (self.un_reference_inator)(indexed.index))
}
}
impl<I: Iterator, UnReferenceInator: FnMut(usize) -> Output, Output> ExactSizeIterator
for MapIndices<I, UnReferenceInator, Output>
{
}
#[allow(missing_debug_implementations)]
pub struct MapValues<I: Iterator, UnReferenceInator: FnMut(&I::Item) -> Output, Output> {
iter: Reiterator<I>,
un_reference_inator: UnReferenceInator,
}
impl<I: Iterator, UnReferenceInator: FnMut(&I::Item) -> Output, Output> Iterator
for MapValues<I, UnReferenceInator, Output>
{
type Item = Output;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|indexed| (self.un_reference_inator)(indexed.value))
}
}
impl<I: Iterator, UnReferenceInator: FnMut(&I::Item) -> Output, Output> ExactSizeIterator
for MapValues<I, UnReferenceInator, Output>
{
}
#[inline(always)]
#[must_use]
pub fn reiterate<I: IntoIterator>(iter: I) -> Reiterator<I::IntoIter> {
use cache::Cached;
Reiterator {
cache: iter.cached(),
index: 0,
}
}
pub trait Reiterate: IntoIterator {
#[must_use]
fn reiterate(self) -> Reiterator<Self::IntoIter>;
}
impl<I: IntoIterator> Reiterate for I {
#[inline(always)]
#[must_use]
fn reiterate(self) -> Reiterator<Self::IntoIter> {
reiterate(self)
}
}