// 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-test extern mod std; use std::oldmap::*; use vec::*; use dvec::{dvec, extensions}; enum furniture { chair, couch, bed } enum body_part { finger, toe, nose, ear } trait noisy { fn speak() -> int; } trait scratchy { fn scratch() -> Option; } trait bitey { fn bite() -> body_part; } fn vec_includes(xs: ~[T], x: T) -> bool { for each(xs) |y| { if y == x { return true; }} return false; } // vtables other than the 1st one don't seem to work class cat : noisy, scratchy, bitey { priv { let meows : @mut uint; let scratched : dvec; let bite_counts : hashmap; fn meow() -> uint { debug!("Meow: %u", *self.meows); *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; self.name = in_name; self.scratched = dvec(); let hsher: hashfn = |p| int::hash(p as int); let eqer : eqfn = |p, q| p == q; let t : hashmap = hashmap::(hsher, eqer); self.bite_counts = t; do iter(~[finger, toe, nose, ear]) |p| { self.bite_counts.insert(p, 0u); }; } fn speak() -> int { self.meow() as int } fn meow_count() -> uint { *self.meows } fn scratch() -> Option { let all = ~[chair, couch, bed]; log(error, self.scratched); let mut rslt = None; for each(all) |thing| { if !self.scratched.contains(thing) { self.scratched.push(thing); return Some(thing); }} rslt } fn bite() -> body_part { error!("In bite()"); let all = ~[toe, nose, ear]; let mut min = finger; do iter(all) |next| { debug!("min = %?", min); if self.bite_counts.get(next) < self.bite_counts.get(min) { min = next; }}; self.bite_counts.insert(min, self.bite_counts.get(min) + 1u); debug!("Bit %?", min); min } } fn annoy_neighbors(critter: T) { for uint::range(0u, 10u) |i| { let what = critter.speak(); debug!("%u %d", i, what); } } fn bite_everything(critter: T) -> bool { let mut left : ~[body_part] = ~[finger, toe, nose, ear]; while vec::len(left) > 0u { let part = critter.bite(); debug!("%? %?", left, part); if vec_includes(left, part) { left = vec::filter(left, |p| p != part ); } else { return false; } } true } fn scratched_something(critter: T) -> bool { option::is_some(critter.scratch()) } pub fn main() { let nyan : cat = cat(0u, 2, "nyan"); annoy_neighbors(nyan as noisy); assert!((nyan.meow_count() == 10u)); assert!((bite_everything(nyan as bitey))); assert!((scratched_something(nyan as scratchy))); }