Skip to content

Instantly share code, notes, and snippets.

@ben0x539
Last active December 12, 2015 06:19
Show Gist options
  • Save ben0x539/4727955 to your computer and use it in GitHub Desktop.
Save ben0x539/4727955 to your computer and use it in GitHub Desktop.
use core::iter::BaseIter;
use io::ReaderUtil;
fn main() {
let va = range_iter(1, 10);
let vb = ReaderIter { reader: io::stdin() };
for both(&va, &vb).each |&(a, b)| {
io::println(fmt!("%d, %s", a, b));
}
}
struct Both<A, B> {
a: A,
b: B
}
pure fn to_vec<TE, T: BaseIter<TE>>(t: &T) -> ~[TE] {
do vec::build_sized_opt(t.size_hint()) |push| {
for t.each |&x| {
push(x);
}
}
}
impl<AE: Copy, BE: Copy, A: BaseIter<AE>, B:BaseIter<BE>> Both<&A, &B>: BaseIter<(AE, BE)> {
pure fn each(&self, blk: fn(v: &(AE, BE)) -> bool) {
let buf_a = to_vec(self.a);
let buf_b = to_vec(self.b);
for uint::range(0, uint::min(buf_a.len(), buf_b.len())) |i| {
blk(&(buf_a[i], buf_b[i]));
}
}
pure fn size_hint(&self) -> Option<uint>{
match (self.a.size_hint(), self.b.size_hint()) {
(None, None) => None,
(a_size, b_size) => Some(uint::max(a_size.get_or_zero(),
b_size.get_or_zero()))
}
}
}
fn both<AE, BE, A: BaseIter<AE>, B: BaseIter<BE>>(a: &lt/A, b: &lt/B) -> Both<&lt/A, &lt/B> {
Both { a: a, b: b }
}
struct ReaderIter {
reader: @io::Reader
}
impl ReaderIter: BaseIter<~str> {
pure fn each(&self, blk: fn(&~str) -> bool) {
unsafe { // each_line is impure
for self.reader.each_line |line| {
let boxed_line = str::from_slice(line);
if !blk(&boxed_line) {
break;
}
}
}
}
pure fn size_hint(&self) -> Option<uint> { None }
}
struct RangeIter {
min: int,
max: int
}
impl RangeIter: BaseIter<int> {
pure fn each(&self, blk: fn(&int) -> bool) {
for int::range(self.min, self.max) |i| {
if !blk(&i) {
break;
}
}
}
pure fn size_hint(&self) -> Option<uint> {
Some((self.max - self.min) as uint)
}
}
fn range_iter(min: int, max: int) -> RangeIter {
assert min <= max;
RangeIter { min: min, max: max }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment