2012-09-19 15:59:44 -05:00
|
|
|
// xfail-fast
|
2012-09-18 17:52:21 -05:00
|
|
|
#[legacy_modes];
|
2012-08-02 18:01:38 -05:00
|
|
|
|
|
|
|
// 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<A>(b: self, +x1: A, +x2: A) -> A;
|
|
|
|
}
|
|
|
|
|
2012-09-07 16:52:28 -05:00
|
|
|
fn andand<T: bool_like Copy>(x1: T, x2: T) -> T {
|
2012-08-02 18:01:38 -05:00
|
|
|
select(x1, x2, x1)
|
|
|
|
}
|
|
|
|
|
2012-08-07 20:10:06 -05:00
|
|
|
impl bool: bool_like {
|
2012-08-02 18:01:38 -05:00
|
|
|
static fn select<A>(&&b: bool, +x1: A, +x2: A) -> A {
|
2012-09-19 00:45:24 -05:00
|
|
|
if b { move x1 } else { move x2 }
|
2012-08-02 18:01:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-07 20:10:06 -05:00
|
|
|
impl int: bool_like {
|
2012-08-02 18:01:38 -05:00
|
|
|
static fn select<A>(&&b: int, +x1: A, +x2: A) -> A {
|
2012-09-19 00:45:24 -05:00
|
|
|
if b != 0 { move x1 } else { move x2 }
|
2012-08-02 18:01:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A trait for sequences that can be constructed imperatively.
|
|
|
|
trait buildable<A> {
|
|
|
|
static pure fn build_sized(size: uint,
|
2012-09-23 06:39:27 -05:00
|
|
|
builder: fn(push: pure fn(+v: A))) -> self;
|
2012-08-02 18:01:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-07 20:10:06 -05:00
|
|
|
impl<A> @[A]: buildable<A> {
|
2012-08-02 18:01:38 -05:00
|
|
|
#[inline(always)]
|
|
|
|
static pure fn build_sized(size: uint,
|
2012-09-23 06:39:27 -05:00
|
|
|
builder: fn(push: pure fn(+v: A))) -> @[A] {
|
2012-08-02 18:01:38 -05:00
|
|
|
at_vec::build_sized(size, builder)
|
|
|
|
}
|
|
|
|
}
|
2012-08-07 20:10:06 -05:00
|
|
|
impl<A> ~[A]: buildable<A> {
|
2012-08-02 18:01:38 -05:00
|
|
|
#[inline(always)]
|
|
|
|
static pure fn build_sized(size: uint,
|
2012-09-23 06:39:27 -05:00
|
|
|
builder: fn(push: pure fn(+v: A))) -> ~[A] {
|
2012-08-02 18:01:38 -05:00
|
|
|
vec::build_sized(size, builder)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
2012-09-23 06:39:27 -05:00
|
|
|
pure fn build<A, B: buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B {
|
2012-08-02 18:01:38 -05:00
|
|
|
build_sized(4, builder)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Apply a function to each element of an iterable and return the results
|
2012-08-14 18:54:13 -05:00
|
|
|
fn map<T, IT: BaseIter<T>, U, BU: buildable<U>>
|
2012-08-02 18:01:38 -05:00
|
|
|
(v: IT, f: fn(T) -> U) -> BU {
|
|
|
|
do build |push| {
|
|
|
|
for v.each() |elem| {
|
2012-09-19 18:55:01 -05:00
|
|
|
push(f(*elem));
|
2012-08-02 18:01:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn seq_range<BT: buildable<int>>(lo: uint, hi: uint) -> BT {
|
|
|
|
do build_sized(hi-lo) |push| {
|
|
|
|
for uint::range(lo, hi) |i| {
|
|
|
|
push(i as int);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2012-08-27 18:26:35 -05:00
|
|
|
let v: @[int] = seq_range(0, 10);
|
|
|
|
assert v == @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
2012-08-02 18:01:38 -05:00
|
|
|
|
2012-08-27 18:26:35 -05:00
|
|
|
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];
|
2012-08-02 18:01:38 -05:00
|
|
|
|
|
|
|
assert select(true, 9, 14) == 9;
|
|
|
|
assert !andand(true, false);
|
|
|
|
assert andand(7, 12) == 12;
|
|
|
|
assert andand(0, 12) == 0;
|
|
|
|
}
|