use prelude::*;
use VariantPhantom;
use std_::cmp::Ordering;
use std_::iter::FromIterator;
use std_::mem;
#[derive(Copy, Clone)]
pub struct Loop<F>(pub F);
impl<F, T> Iterator for Loop<F>
where
F: FnMut() -> T,
{
type Item = T;
fn next(&mut self) -> Option<T> {
Some((self.0)())
}
}
#[derive(Copy, Clone)]
pub struct LazyOnce<F> {
func: Option<F>,
}
impl<F> LazyOnce<F> {
pub fn new(f: F) -> Self {
LazyOnce { func: Some(f) }
}
}
impl<F, T> Iterator for LazyOnce<F>
where
F: FnOnce() -> T,
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.func.take().map(|f| f())
}
fn size_hint(&self) -> (usize, Option<usize>) {
(1, Some(1))
}
}
impl<F, T> DoubleEndedIterator for LazyOnce<F>
where
F: FnOnce() -> T,
{
fn next_back(&mut self) -> Option<T> {
self.func.take().map(|f| f())
}
}
impl<F, T> ExactSizeIterator for LazyOnce<F> where F: FnOnce() -> T {}
#[derive(Debug, Clone)]
struct Unreplaced<T> {
nth: usize,
current: usize,
with: T,
}
#[derive(Debug, Clone)]
enum ReplaceNthState<T> {
Unreplaced(Unreplaced<T>),
Replaced,
}
#[derive(Debug, Clone)]
pub struct ReplaceNth<I>
where
I: Iterator,
{
iter: I,
state: ReplaceNthState<I::Item>,
}
impl<I> ReplaceNth<I>
where
I: Iterator,
{
pub fn new(iter: I, nth: usize, with: I::Item) -> Self {
Self {
iter,
state: ReplaceNthState::Unreplaced(Unreplaced {
nth,
current: 0,
with,
}),
}
}
}
impl<I> Iterator for ReplaceNth<I>
where
I: Iterator,
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
use self::ReplaceNthState as RNS;
let mut ret = try_opt!(self.iter.next());
let replace = match self.state {
RNS::Unreplaced(ref mut unreplaced) => {
(unreplaced.nth == unreplaced.current).observe(|v| {
if !v {
unreplaced.current += 1
}
})
}
RNS::Replaced => false,
};
if replace {
if let RNS::Unreplaced(unreplaced) = mem::replace(&mut self.state, RNS::Replaced) {
ret = unreplaced.with;
}
}
Some(ret)
}
fn nth(&mut self, nth: usize) -> Option<I::Item> {
use self::ReplaceNthState as RNS;
let mut ret = try_opt!(self.iter.nth(nth));
let mut replace = Ordering::Greater;
if let RNS::Unreplaced(ref mut unreplaced) = self.state {
unreplaced.current += nth;
replace = unreplaced.current.cmp(&unreplaced.nth);
if replace == Ordering::Less {
unreplaced.current += 1;
}
}
match replace {
Ordering::Less => {}
Ordering::Equal => {
if let RNS::Unreplaced(unreplaced) = mem::replace(&mut self.state, RNS::Replaced) {
ret = unreplaced.with;
}
}
Ordering::Greater => self.state = RNS::Replaced,
}
Some(ret)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn count(self) -> usize {
self.iter.count()
}
}
#[cfg(test)]
mod test_replace_nth {
use alloc_::vec::Vec;
use super::*;
#[test]
fn nth_method() {
let list = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for i in 0..list.len() {
let mut iter = ReplaceNth::new(list.iter().cloned(), i, 100);
println!("iteration:{}", i);
println!("values:{:?}", iter.clone().collect::<Vec<_>>());
if i != 0 {
let j = i - 1;
assert_eq!(iter.nth(j).unwrap(), list[j])
}
assert_eq!(iter.next().unwrap(), 100);
if i + 1 < list.len() {
assert_eq!(iter.next().unwrap(), list[i + 1]);
}
if i + 2 < list.len() {
assert_eq!(iter.next().unwrap(), list[i + 2]);
}
}
}
}
pub trait IteratorExt: Iterator {
#[inline(always)]
fn collect_<T>(self, _: VariantPhantom<T>) -> T
where
Self: Sized,
T: FromIterator<Self::Item>,
{
self.collect()
}
#[inline(always)]
fn extending<C>(self, extend: &mut C)
where
Self: Sized,
C: Extend<Self::Item>,
{
extend.extend(self);
}
#[inline(always)]
fn collect_into<C>(self, mut extend: C) -> C
where
Self: Sized,
C: Extend<Self::Item>,
{
extend.extend(self);
extend
}
#[inline(always)]
fn replace_nth(self, nth: usize, with: Self::Item) -> ReplaceNth<Self>
where
Self: Sized,
{
ReplaceNth::new(self, nth, with)
}
}
impl<I> IteratorExt for I where I: Iterator {}
#[cfg_attr(not(enable_copy_closures), doc = r#" ```ignore"#)]
#[cfg_attr(enable_copy_closures, doc = " ```")]
#[derive(Copy, Clone)]
pub struct IterConstructor<F> {
pub f: F,
}
impl<F> IterConstructor<F> {
pub fn new(f: F) -> Self {
Self { f }
}
}
impl<F, I> IntoIterator for IterConstructor<F>
where
F: FnOnce() -> I,
I: Iterator,
{
type Item = I::Item;
type IntoIter = I;
fn into_iter(self) -> Self::IntoIter {
(self.f)()
}
}
#[cfg_attr(not(enable_copy_closures), doc = r#" ```ignore"#)]
#[cfg_attr(enable_copy_closures, doc = " ```")]
#[macro_export]
macro_rules! iter_cloner {
(let $ident:ident = $expr:expr) => {
let $ident = $expr;
let $ident = $crate::iterators::IterCloner::new(&$ident);
};
}
#[cfg_attr(not(enable_copy_closures), doc = r#" ```ignore"#)]
#[cfg_attr(enable_copy_closures, doc = " ```")]
pub struct IterCloner<'a, I: 'a> {
pub iter: &'a I,
}
impl<'a, I> Copy for IterCloner<'a, I> {}
impl<'a, I> Clone for IterCloner<'a, I> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, I: 'a> IterCloner<'a, I>
where
I: Iterator + Clone,
{
pub fn new(iter: &'a I) -> Self {
Self { iter }
}
}
impl<'a, I: 'a> IntoIterator for IterCloner<'a, I>
where
I: Iterator + Clone,
{
type Item = I::Item;
type IntoIter = I;
fn into_iter(self) -> Self::IntoIter {
self.iter.clone()
}
}