#![no_std]
#![allow(stable_features)]
#![cfg_attr(feature = "nightly_features", allow(incomplete_features))]
#![cfg_attr(feature = "nightly_features", feature(generic_const_exprs))]
#![warn(clippy::doc_markdown)]
#![warn(clippy::ignored_unit_patterns)]
#![warn(clippy::missing_inline_in_public_items)]
#![warn(clippy::use_self)]
use core::iter;
mod from;
mod helpers;
mod into;
#[cfg(feature = "nightly_features")]
use helpers::{ceiling_div, min, sub_or_zero};
pub use from::FromIteratorFixed;
pub use into::IntoIteratorFixed;
pub struct IteratorFixed<I: Iterator, const N: usize> {
inner: I,
}
#[inline]
pub fn from_fn<'a, F, T: 'a, const N: usize>(
mut f: F,
) -> IteratorFixed<impl Iterator<Item = T> + 'a, N>
where
F: FnMut(usize) -> T + 'a,
{
[(); N]
.into_iter_fixed()
.enumerate()
.map(move |(i, ())| f(i))
}
impl<I, const N: usize> IteratorFixed<I, N>
where
I: Iterator,
{
#[inline]
pub unsafe fn from_iter<II: IntoIterator<IntoIter = I>>(i: II) -> Self {
Self {
inner: i.into_iter(),
}
}
#[inline]
pub fn map<U, F: FnMut(<I as Iterator>::Item) -> U>(
self,
p: F,
) -> IteratorFixed<impl Iterator<Item = U>, N> {
IteratorFixed {
inner: self.inner.map(p),
}
}
#[inline]
pub fn inspect<F: FnMut(&<I as Iterator>::Item)>(
self,
p: F,
) -> IteratorFixed<impl Iterator<Item = I::Item>, N> {
IteratorFixed {
inner: self.inner.inspect(p),
}
}
#[cfg(feature = "nightly_features")]
#[inline]
pub fn skip<const SKIP: usize>(
self,
) -> IteratorFixed<impl Iterator<Item = I::Item>, { sub_or_zero(N, SKIP) }> {
IteratorFixed {
inner: self.inner.skip(SKIP),
}
}
#[cfg(feature = "nightly_features")]
#[inline]
pub fn step_by<const STEP: usize>(
self,
) -> IteratorFixed<impl Iterator<Item = I::Item>, { ceiling_div(N, STEP) }> {
IteratorFixed {
inner: self.inner.step_by(STEP),
}
}
#[cfg(feature = "nightly_features")]
#[inline]
pub fn chain<IIF, const M: usize>(
self,
other: IIF,
) -> IteratorFixed<impl Iterator<Item = I::Item>, { N + M }>
where
IIF: IntoIteratorFixed<M, Item = I::Item>,
{
IteratorFixed {
inner: self.inner.chain(other.into_iter_fixed().inner),
}
}
#[inline]
pub fn enumerate(self) -> IteratorFixed<impl Iterator<Item = (usize, I::Item)>, N> {
IteratorFixed {
inner: self.inner.enumerate(),
}
}
#[cfg(feature = "nightly_features")]
#[inline]
pub fn take<const TAKE: usize>(
self,
) -> IteratorFixed<impl Iterator<Item = I::Item>, { min(TAKE, N) }> {
IteratorFixed {
inner: self.inner.take(TAKE),
}
}
#[inline]
pub fn zip<IIF>(
self,
other: IIF,
) -> IteratorFixed<impl Iterator<Item = (I::Item, IIF::Item)>, N>
where
IIF: IntoIteratorFixed<N>,
{
IteratorFixed {
inner: self.inner.zip(other.into_iter_fixed().inner),
}
}
#[inline]
pub fn rev(self) -> IteratorFixed<impl Iterator<Item = I::Item>, N>
where
I: iter::DoubleEndedIterator,
{
IteratorFixed {
inner: self.inner.rev(),
}
}
#[cfg(feature = "nightly_features")]
#[inline]
pub fn flatten<IIF, const M: usize>(
self,
) -> IteratorFixed<impl Iterator<Item = IIF::Item>, { M * N }>
where
I: Iterator<Item = IIF>,
IIF: IntoIteratorFixed<M>,
{
IteratorFixed {
inner: self.inner.flat_map(IntoIteratorFixed::into_iter_fixed),
}
}
#[cfg(feature = "nightly_features")]
#[inline]
pub fn flat_map<F, IIF, const M: usize>(
self,
mut f: F,
) -> IteratorFixed<impl Iterator<Item = IIF::Item>, { M * N }>
where
F: FnMut(I::Item) -> IIF,
IIF: IntoIteratorFixed<M>,
{
IteratorFixed {
inner: self.inner.flat_map(move |x| f(x).into_iter_fixed()),
}
}
#[inline]
pub fn collect<U: FromIteratorFixed<I::Item, N>>(self) -> U {
U::from_iter_fixed(self)
}
}
impl<'a, I, T: 'a, const N: usize> IteratorFixed<I, N>
where
I: Iterator<Item = &'a T>,
{
#[inline]
pub fn copied(self) -> IteratorFixed<impl Iterator<Item = T>, N>
where
T: Copy,
{
IteratorFixed {
inner: self.inner.copied(),
}
}
#[inline]
pub fn cloned(self) -> IteratorFixed<impl Iterator<Item = T>, N>
where
T: Clone,
{
IteratorFixed {
inner: self.inner.cloned(),
}
}
}
impl<T, I: Iterator<Item = T>, const N: usize> IntoIterator for IteratorFixed<I, N> {
type Item = T;
type IntoIter = I;
#[inline]
fn into_iter(self) -> I {
self.inner
}
}