2012-12-10 19:32:48 -06:00
|
|
|
// 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 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-05-22 12:54:12 -05:00
|
|
|
// xfail-test
|
|
|
|
|
2012-09-11 19:46:20 -05:00
|
|
|
extern mod std;
|
2013-02-01 01:13:36 -06:00
|
|
|
use std::oldmap::*;
|
2012-09-05 14:32:05 -05:00
|
|
|
use vec::*;
|
|
|
|
use dvec::{dvec, extensions};
|
2012-04-13 14:22:35 -05:00
|
|
|
|
|
|
|
enum furniture { chair, couch, bed }
|
|
|
|
enum body_part { finger, toe, nose, ear }
|
|
|
|
|
2012-07-31 12:27:51 -05:00
|
|
|
trait noisy {
|
2012-04-13 14:22:35 -05:00
|
|
|
fn speak() -> int;
|
|
|
|
}
|
|
|
|
|
2012-07-31 12:27:51 -05:00
|
|
|
trait scratchy {
|
2013-01-25 13:31:45 -06:00
|
|
|
fn scratch() -> Option<furniture>;
|
2012-04-13 14:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-07-31 12:27:51 -05:00
|
|
|
trait bitey {
|
2012-04-13 14:22:35 -05:00
|
|
|
fn bite() -> body_part;
|
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
fn vec_includes<T>(xs: ~[T], x: T) -> bool {
|
2012-08-01 19:30:05 -05:00
|
|
|
for each(xs) |y| { if y == x { return true; }}
|
|
|
|
return false;
|
2012-04-13 14:22:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// vtables other than the 1st one don't seem to work
|
2012-06-22 20:19:35 -05:00
|
|
|
class cat : noisy, scratchy, bitey {
|
2012-04-13 14:22:35 -05:00
|
|
|
priv {
|
|
|
|
let meows : @mut uint;
|
2012-06-04 12:44:19 -05:00
|
|
|
let scratched : dvec<furniture>;
|
2012-04-13 14:22:35 -05:00
|
|
|
let bite_counts : hashmap<body_part, uint>;
|
|
|
|
|
|
|
|
fn meow() -> uint {
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("Meow: %u", *self.meows);
|
2012-04-13 14:22:35 -05:00
|
|
|
*self.meows += 1u;
|
|
|
|
if *self.meows % 5u == 0u {
|
|
|
|
*self.how_hungry += 1;
|
|
|
|
}
|
|
|
|
*self.meows
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let how_hungry : @mut int;
|
|
|
|
let name : str;
|
|
|
|
|
|
|
|
new(in_x : uint, in_y : int, in_name: str)
|
|
|
|
{ self.meows = @mut in_x; self.how_hungry = @mut in_y;
|
2012-06-04 12:44:19 -05:00
|
|
|
self.name = in_name; self.scratched = dvec();
|
2013-03-01 17:55:31 -06:00
|
|
|
let hsher: hashfn<body_part> = |p| int::hash(p as int);
|
|
|
|
let eqer : eqfn<body_part> = |p, q| p == q;
|
2012-04-13 14:22:35 -05:00
|
|
|
let t : hashmap<body_part, uint> =
|
|
|
|
hashmap::<body_part, uint>(hsher, eqer);
|
|
|
|
self.bite_counts = t;
|
2012-06-30 18:19:07 -05:00
|
|
|
do iter(~[finger, toe, nose, ear]) |p| {
|
2012-04-13 14:22:35 -05:00
|
|
|
self.bite_counts.insert(p, 0u);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn speak() -> int { self.meow() as int }
|
|
|
|
fn meow_count() -> uint { *self.meows }
|
2013-01-25 13:31:45 -06:00
|
|
|
fn scratch() -> Option<furniture> {
|
2012-06-29 18:26:56 -05:00
|
|
|
let all = ~[chair, couch, bed];
|
2012-06-04 12:44:19 -05:00
|
|
|
log(error, self.scratched);
|
2013-01-25 13:31:45 -06:00
|
|
|
let mut rslt = None;
|
2012-06-30 18:19:07 -05:00
|
|
|
for each(all) |thing| { if !self.scratched.contains(thing) {
|
2012-06-04 12:44:19 -05:00
|
|
|
self.scratched.push(thing);
|
2013-01-25 13:31:45 -06:00
|
|
|
return Some(thing); }}
|
2012-04-13 14:22:35 -05:00
|
|
|
rslt
|
|
|
|
}
|
|
|
|
fn bite() -> body_part {
|
2012-08-22 19:24:52 -05:00
|
|
|
error!("In bite()");
|
2012-06-29 18:26:56 -05:00
|
|
|
let all = ~[toe, nose, ear];
|
2012-04-13 14:22:35 -05:00
|
|
|
let mut min = finger;
|
2012-06-30 18:19:07 -05:00
|
|
|
do iter(all) |next| {
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("min = %?", min);
|
2012-04-13 14:22:35 -05:00
|
|
|
if self.bite_counts.get(next) < self.bite_counts.get(min) {
|
|
|
|
min = next;
|
|
|
|
}};
|
|
|
|
self.bite_counts.insert(min, self.bite_counts.get(min) + 1u);
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("Bit %?", min);
|
2012-04-13 14:22:35 -05:00
|
|
|
min
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 19:07:17 -06:00
|
|
|
fn annoy_neighbors<T:noisy>(critter: T) {
|
2012-06-30 18:19:07 -05:00
|
|
|
for uint::range(0u, 10u) |i| {
|
2012-04-13 14:22:35 -05:00
|
|
|
let what = critter.speak();
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("%u %d", i, what);
|
2012-04-13 14:22:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-20 19:07:17 -06:00
|
|
|
fn bite_everything<T:bitey>(critter: T) -> bool {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut left : ~[body_part] = ~[finger, toe, nose, ear];
|
2012-04-13 14:22:35 -05:00
|
|
|
while vec::len(left) > 0u {
|
|
|
|
let part = critter.bite();
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("%? %?", left, part);
|
2012-04-13 14:22:35 -05:00
|
|
|
if vec_includes(left, part) {
|
2012-06-30 18:19:07 -05:00
|
|
|
left = vec::filter(left, |p| p != part );
|
2012-04-13 14:22:35 -05:00
|
|
|
}
|
|
|
|
else {
|
2012-08-01 19:30:05 -05:00
|
|
|
return false;
|
2012-04-13 14:22:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2013-02-20 19:07:17 -06:00
|
|
|
fn scratched_something<T:scratchy>(critter: T) -> bool {
|
2012-04-13 14:22:35 -05:00
|
|
|
option::is_some(critter.scratch())
|
|
|
|
}
|
|
|
|
|
2013-02-01 21:43:17 -06:00
|
|
|
pub fn main() {
|
2012-04-13 14:22:35 -05:00
|
|
|
let nyan : cat = cat(0u, 2, "nyan");
|
|
|
|
annoy_neighbors(nyan as noisy);
|
2013-03-28 20:39:09 -05:00
|
|
|
assert!((nyan.meow_count() == 10u));
|
|
|
|
assert!((bite_everything(nyan as bitey)));
|
|
|
|
assert!((scratched_something(nyan as scratchy)));
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|