use impl_tools::autoimpl;
use mem_dbg::{MemDbg, MemSize};
pub trait IntoIteratorFrom: IntoIterator {
type IntoIterFrom: Iterator<Item = <Self as IntoIterator>::Item>;
fn into_iter_from(self, from: usize) -> Self::IntoIterFrom;
}
impl<'a, T> IntoIteratorFrom for &'a [T] {
type IntoIterFrom = std::iter::Skip<std::slice::Iter<'a, T>>;
fn into_iter_from(self, from: usize) -> Self::IntoIterFrom {
self.iter().skip(from)
}
}
impl<T> IntoIteratorFrom for Vec<T> {
type IntoIterFrom = std::iter::Skip<std::vec::IntoIter<T>>;
fn into_iter_from(self, from: usize) -> Self::IntoIterFrom {
self.into_iter().skip(from)
}
}
impl<'a, T> IntoIteratorFrom for &'a Vec<T> {
type IntoIterFrom = std::iter::Skip<std::slice::Iter<'a, T>>;
fn into_iter_from(self, from: usize) -> Self::IntoIterFrom {
self.iter().skip(from)
}
}
impl<T> IntoIteratorFrom for Box<[T]> {
type IntoIterFrom = std::iter::Skip<std::vec::IntoIter<T>>;
fn into_iter_from(self, from: usize) -> Self::IntoIterFrom {
IntoIterator::into_iter(self).skip(from)
}
}
impl<'a, T> IntoIteratorFrom for &'a Box<[T]> {
type IntoIterFrom = std::iter::Skip<std::slice::Iter<'a, T>>;
fn into_iter_from(self, from: usize) -> Self::IntoIterFrom {
self.into_iter().skip(from)
}
}
impl<'a, T: Copy> UncheckedIterator for std::iter::Skip<std::slice::Iter<'a, T>> {
type Item = T;
#[inline(always)]
unsafe fn next_unchecked(&mut self) -> T {
*unsafe { self.next().unwrap_unchecked() }
}
}
#[autoimpl(for<T: trait + ?Sized> &mut T, Box<T>)]
pub trait UncheckedIterator {
type Item;
unsafe fn next_unchecked(&mut self) -> Self::Item;
}
pub trait IntoUncheckedIterator: Sized {
type Item;
type IntoUncheckedIter: UncheckedIterator<Item = Self::Item>;
fn into_unchecked_iter(self) -> Self::IntoUncheckedIter {
self.into_unchecked_iter_from(0)
}
fn into_unchecked_iter_from(self, from: usize) -> Self::IntoUncheckedIter;
}
pub trait IntoUncheckedBackIterator: Sized {
type Item;
type IntoUncheckedIterBack: UncheckedIterator<Item = Self::Item>;
fn into_unchecked_iter_back(self) -> Self::IntoUncheckedIterBack;
fn into_unchecked_iter_back_from(self, from: usize) -> Self::IntoUncheckedIterBack;
}
pub trait IntoBackIterator: Sized {
type Item;
type IntoIterBack: Iterator<Item = Self::Item>;
fn into_iter_back(self) -> Self::IntoIterBack;
}
pub trait IntoBackIteratorFrom: IntoBackIterator {
type IntoIterBackFrom: Iterator<Item = <Self as IntoBackIterator>::Item>;
fn into_iter_back_from(self, from: usize) -> Self::IntoIterBackFrom;
}
pub trait BidiIterator: Iterator + Sized {
type SwappedIter: BidiIterator<Item = Self::Item, SwappedIter = Self>;
fn swap(self) -> Self::SwappedIter;
fn prev(&mut self) -> Option<Self::Item>;
fn prev_size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
#[cfg(feature = "iter_advance_by")]
fn prev_advance_by(&mut self, n: usize) -> Result<(), std::num::NonZero<usize>> {
for i in 0..n {
if self.prev().is_none() {
return Err(unsafe { std::num::NonZero::new_unchecked(n - i) });
}
}
Ok(())
}
fn prev_nth(&mut self, n: usize) -> Option<Self::Item> {
for _ in 0..n {
self.prev()?;
}
self.prev()
}
fn prev_fold<B, F>(mut self, init: B, mut f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
let mut accum = init;
while let Some(x) = self.prev() {
accum = f(accum, x);
}
accum
}
fn prev_for_each<F>(self, mut f: F)
where
F: FnMut(Self::Item),
{
self.prev_fold((), |(), x| f(x));
}
fn prev_count(self) -> usize {
self.prev_fold(0, |count, _| count + 1)
}
fn prev_last(mut self) -> Option<Self::Item> {
let mut last = None;
while let Some(x) = self.prev() {
last = Some(x);
}
last
}
}
pub trait ExactSizeBidiIterator: BidiIterator {
fn prev_len(&self) -> usize;
}
pub trait FusedBidiIterator: BidiIterator {}
#[derive(Clone, Debug, MemSize, MemDbg)]
#[repr(transparent)]
pub struct SwappedIter<I>(pub I);
impl<I: BidiIterator<SwappedIter = SwappedIter<I>>> Iterator for SwappedIter<I> {
type Item = I::Item;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.prev()
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.prev_size_hint()
}
#[inline(always)]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.0.prev_nth(n)
}
#[cfg(feature = "iter_advance_by")]
#[inline(always)]
fn advance_by(&mut self, n: usize) -> Result<(), std::num::NonZero<usize>> {
self.0.prev_advance_by(n)
}
#[inline(always)]
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.0.prev_fold(init, f)
}
#[inline(always)]
fn for_each<F>(self, f: F)
where
F: FnMut(Self::Item),
{
self.0.prev_for_each(f);
}
#[inline(always)]
fn count(self) -> usize {
self.0.prev_count()
}
#[inline(always)]
fn last(self) -> Option<Self::Item> {
self.0.prev_last()
}
}
impl<I: BidiIterator<SwappedIter = SwappedIter<I>>> BidiIterator for SwappedIter<I> {
type SwappedIter = I;
#[inline(always)]
fn swap(self) -> I {
self.0
}
#[inline(always)]
fn prev(&mut self) -> Option<Self::Item> {
self.0.next()
}
#[inline(always)]
fn prev_size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
#[cfg(feature = "iter_advance_by")]
#[inline(always)]
fn prev_advance_by(&mut self, n: usize) -> Result<(), std::num::NonZero<usize>> {
self.0.advance_by(n)
}
#[inline(always)]
fn prev_nth(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth(n)
}
#[inline(always)]
fn prev_fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.0.fold(init, f)
}
#[inline(always)]
fn prev_for_each<F>(self, f: F)
where
F: FnMut(Self::Item),
{
self.0.for_each(f);
}
#[inline(always)]
fn prev_count(self) -> usize {
self.0.count()
}
#[inline(always)]
fn prev_last(self) -> Option<Self::Item> {
self.0.last()
}
}
impl<I: ExactSizeBidiIterator<SwappedIter = SwappedIter<I>>> ExactSizeIterator for SwappedIter<I> {
#[inline(always)]
fn len(&self) -> usize {
self.0.prev_len()
}
}
impl<I: BidiIterator<SwappedIter = SwappedIter<I>> + ExactSizeIterator> ExactSizeBidiIterator
for SwappedIter<I>
{
#[inline(always)]
fn prev_len(&self) -> usize {
self.0.len()
}
}
impl<I: FusedBidiIterator<SwappedIter = SwappedIter<I>>> std::iter::FusedIterator
for SwappedIter<I>
{
}
impl<I: BidiIterator<SwappedIter = SwappedIter<I>> + std::iter::FusedIterator> FusedBidiIterator
for SwappedIter<I>
{
}
pub trait IntoBidiIterator: Sized {
type Item;
type IntoIterBidi: BidiIterator<Item = Self::Item>;
fn into_iter_bidi(self) -> Self::IntoIterBidi;
}
pub trait IntoBidiIteratorFrom: IntoBidiIterator {
type IntoIterBidiFrom: BidiIterator<Item = <Self as IntoBidiIterator>::Item>;
fn into_iter_bidi_from(self, from: usize) -> Self::IntoIterBidiFrom;
}