// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // xfail-fast #[legacy_modes]; // A trait for objects that can be used to do an if-then-else // (No actual need for this to be static, but it is a simple test.) trait bool_like { static fn select(b: Self, +x1: A, +x2: A) -> A; } fn andand(x1: T, x2: T) -> T { bool_like::select(x1, x2, x1) } impl bool_like for bool { static fn select(&&b: bool, +x1: A, +x2: A) -> A { if b { x1 } else { x2 } } } impl bool_like for int { static fn select(&&b: int, +x1: A, +x2: A) -> A { if b != 0 { x1 } else { x2 } } } // A trait for sequences that can be constructed imperatively. trait buildable { static pure fn build_sized(size: uint, builder: fn(push: pure fn(+v: A))) -> Self; } impl buildable for @[A] { #[inline(always)] static pure fn build_sized(size: uint, builder: fn(push: pure fn(+v: A))) -> @[A] { at_vec::build_sized(size, builder) } } impl buildable for ~[A] { #[inline(always)] static pure fn build_sized(size: uint, builder: fn(push: pure fn(+v: A))) -> ~[A] { vec::build_sized(size, builder) } } #[inline(always)] pure fn build>(builder: fn(push: pure fn(+v: A))) -> B { buildable::build_sized(4, builder) } /// Apply a function to each element of an iterable and return the results fn map, U, BU: buildable> (v: IT, f: fn(T) -> U) -> BU { do build |push| { for v.each() |elem| { push(f(*elem)); } } } fn seq_range>(lo: uint, hi: uint) -> BT { do buildable::build_sized(hi-lo) |push| { for uint::range(lo, hi) |i| { push(i as int); } } } pub fn main() { let v: @[int] = seq_range(0, 10); assert v == @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let v: @[int] = map(&[1,2,3], |x| 1+x); assert v == @[2, 3, 4]; let v: ~[int] = map(&[1,2,3], |x| 1+x); assert v == ~[2, 3, 4]; assert bool_like::select(true, 9, 14) == 9; assert !andand(true, false); assert andand(7, 12) == 12; assert andand(0, 12) == 0; }