78 lines
1.7 KiB
Rust
78 lines
1.7 KiB
Rust
//@ run-pass
|
|
|
|
#![feature(fn_delegation)]
|
|
#![allow(incomplete_features)]
|
|
|
|
use std::iter::{Iterator, Map};
|
|
|
|
pub mod same_trait {
|
|
use super::*;
|
|
|
|
pub struct MapOuter<I, F> {
|
|
pub inner: Map<I, F>
|
|
}
|
|
|
|
impl<B, I: Iterator, F> Iterator for MapOuter<I, F>
|
|
where
|
|
F: FnMut(I::Item) -> B,
|
|
{
|
|
type Item = <Map<I, F> as Iterator>::Item;
|
|
|
|
reuse Iterator::{next, fold} { self.inner }
|
|
}
|
|
}
|
|
use same_trait::MapOuter;
|
|
|
|
mod another_trait {
|
|
use super::*;
|
|
|
|
trait ZipImpl<A, B> {
|
|
type Item;
|
|
|
|
fn next(&mut self) -> Option<Self::Item>;
|
|
}
|
|
|
|
pub struct Zip<A, B> {
|
|
pub a: A,
|
|
pub b: B,
|
|
}
|
|
|
|
impl<A: Iterator, B: Iterator> ZipImpl<A, B> for Zip<A, B> {
|
|
type Item = (A::Item, B::Item);
|
|
|
|
fn next(&mut self) -> Option<(A::Item, B::Item)> {
|
|
let x = self.a.next()?;
|
|
let y = self.b.next()?;
|
|
Some((x, y))
|
|
}
|
|
}
|
|
|
|
impl<A: Iterator, B: Iterator> Iterator for Zip<A, B> {
|
|
type Item = (A::Item, B::Item);
|
|
|
|
// Parameters are inherited from `Iterator::next`, not from `ZipImpl::next`.
|
|
// Otherwise, there would be a compilation error due to an unconstrained parameter.
|
|
reuse ZipImpl::next;
|
|
}
|
|
}
|
|
use another_trait::Zip;
|
|
|
|
fn main() {
|
|
{
|
|
let x = vec![1, 2, 3];
|
|
let iter = x.iter().map(|val| val * 2);
|
|
let outer_iter = MapOuter { inner: iter };
|
|
let val = outer_iter.fold(0, |acc, x| acc + x);
|
|
assert_eq!(val, 12);
|
|
}
|
|
|
|
{
|
|
let x = vec![1, 2];
|
|
let y = vec![4, 5];
|
|
|
|
let mut zip = Zip { a: x.iter(), b: y.iter() };
|
|
assert_eq!(zip.next(), Some((&1, &4)));
|
|
assert_eq!(zip.next(), Some((&2, &5)));
|
|
}
|
|
}
|