1
Fork 0

core: changes in response to #5656

This commit is contained in:
Niko Matsakis 2013-04-10 13:11:35 -07:00
parent 49de82cdca
commit 61b9e0ebfa
12 changed files with 700 additions and 5 deletions

View file

@ -28,7 +28,7 @@ pub struct Condition<'self, T, U> {
}
pub impl<'self, T, U> Condition<'self, T, U> {
fn trap(&self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
fn trap(&'self self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
unsafe {
let p : *RustClosure = ::cast::transmute(&h);
let prev = task::local_data::local_data_get(self.key);

View file

@ -25,6 +25,7 @@ pub trait Mutable: Container {
fn clear(&mut self);
}
#[cfg(stage0)]
pub trait Map<K, V>: Mutable {
/// Return true if the map contains a value for the specified key
fn contains_key(&self, key: &K) -> bool;
@ -57,6 +58,41 @@ pub trait Map<K, V>: Mutable {
fn remove(&mut self, key: &K) -> bool;
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub trait Map<K, V>: Mutable {
/// Return true if the map contains a value for the specified key
fn contains_key(&self, key: &K) -> bool;
// Visits all keys and values
fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool);
/// Visit all keys
fn each_key(&self, f: &fn(&K) -> bool);
/// Visit all values
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool);
/// Iterate over the map and mutate the contained values
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool);
/// Return a reference to the value corresponding to the key
fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
/// Return a mutable reference to the value corresponding to the key
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
/// Insert a key-value pair into the map. An existing value for a
/// key is replaced by the new value. Return true if the key did
/// not already exist in the map.
fn insert(&mut self, key: K, value: V) -> bool;
/// Remove a key-value pair from the map. Return true if the key
/// was present in the map, otherwise false.
fn remove(&mut self, key: &K) -> bool;
}
pub trait Set<T>: Mutable {
/// Return true if the set contains a value
fn contains(&self, value: &T) -> bool;

View file

@ -186,6 +186,7 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
}
}
#[cfg(stage0)]
#[inline(always)]
fn value_for_bucket(&self, idx: uint) -> &'self V {
match self.buckets[idx] {
@ -194,6 +195,18 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
match self.buckets[idx] {
Some(ref bkt) => &bkt.value,
None => fail!(~"HashMap::find: internal logic error"),
}
}
#[cfg(stage0)]
#[inline(always)]
fn mut_value_for_bucket(&mut self, idx: uint) -> &'self mut V {
match self.buckets[idx] {
@ -202,6 +215,17 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
match self.buckets[idx] {
Some(ref mut bkt) => &mut bkt.value,
None => unreachable()
}
}
/// Inserts the key value pair into the buckets.
/// Assumes that there will be a bucket.
/// True if there was no previous entry with that key
@ -307,6 +331,7 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
}
/// Visit all key-value pairs
#[cfg(stage0)]
fn each(&self, blk: &fn(&'self K, &'self V) -> bool) {
for uint::range(0, self.buckets.len()) |i| {
for self.buckets[i].each |bucket| {
@ -317,19 +342,41 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
}
}
/// Visit all key-value pairs
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each<'a>(&'a self, blk: &fn(&'a K, &'a V) -> bool) {
for uint::range(0, self.buckets.len()) |i| {
for self.buckets[i].each |bucket| {
if !blk(&bucket.key, &bucket.value) {
return;
}
}
}
}
/// Visit all keys
fn each_key(&self, blk: &fn(k: &K) -> bool) {
self.each(|k, _| blk(k))
}
/// Visit all values
#[cfg(stage0)]
fn each_value(&self, blk: &fn(v: &V) -> bool) {
self.each(|_, v| blk(v))
}
/// Visit all values
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) {
self.each(|_, v| blk(v))
}
/// Iterate over the map and mutate the contained values
fn mutate_values(&mut self, blk: &fn(&'self K,
&'self mut V) -> bool) {
fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) {
for uint::range(0, self.buckets.len()) |i| {
match self.buckets[i] {
Some(Bucket{key: ref key, value: ref mut value, _}) => {
@ -341,6 +388,7 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
}
/// Return a reference to the value corresponding to the key
#[cfg(stage0)]
fn find(&self, k: &K) -> Option<&'self V> {
match self.bucket_for_key(k) {
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
@ -348,7 +396,19 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
}
}
/// Return a reference to the value corresponding to the key
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
match self.bucket_for_key(k) {
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
TableFull | FoundHole(_) => None,
}
}
/// Return a mutable reference to the value corresponding to the key
#[cfg(stage0)]
fn find_mut(&mut self, k: &K) -> Option<&'self mut V> {
let idx = match self.bucket_for_key(k) {
FoundEntry(idx) => idx,
@ -359,6 +419,20 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
}
}
/// Return a mutable reference to the value corresponding to the key
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
let idx = match self.bucket_for_key(k) {
FoundEntry(idx) => idx,
TableFull | FoundHole(_) => return None
};
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx)))
}
}
/// Insert a key-value pair into the map. An existing value for a
/// key is replaced by the new value. Return true if the key did
/// not already exist in the map.
@ -431,6 +505,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
/// Return the value corresponding to the key in the map, or insert
/// and return the value if it doesn't exist.
#[cfg(stage0)]
fn find_or_insert(&mut self, k: K, v: V) -> &'self V {
if self.size >= self.resize_at {
// n.b.: We could also do this after searching, so
@ -459,8 +534,42 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
}
}
/// Return the value corresponding to the key in the map, or insert
/// and return the value if it doesn't exist.
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
if self.size >= self.resize_at {
// n.b.: We could also do this after searching, so
// that we do not resize if this call to insert is
// simply going to update a key in place. My sense
// though is that it's worse to have to search through
// buckets to find the right spot twice than to just
// resize in this corner case.
self.expand();
}
let hash = k.hash_keyed(self.k0, self.k1) as uint;
let idx = match self.bucket_for_key_with_hash(hash, &k) {
TableFull => fail!(~"Internal logic error"),
FoundEntry(idx) => idx,
FoundHole(idx) => {
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
value: v});
self.size += 1;
idx
},
};
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
::cast::transmute_region(self.value_for_bucket(idx))
}
}
/// Return the value corresponding to the key in the map, or create,
/// insert, and return a new value if it doesn't exist.
#[cfg(stage0)]
fn find_or_insert_with(&mut self, k: K, f: &fn(&K) -> V) -> &'self V {
if self.size >= self.resize_at {
// n.b.: We could also do this after searching, so
@ -490,6 +599,40 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
}
}
/// Return the value corresponding to the key in the map, or create,
/// insert, and return a new value if it doesn't exist.
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
if self.size >= self.resize_at {
// n.b.: We could also do this after searching, so
// that we do not resize if this call to insert is
// simply going to update a key in place. My sense
// though is that it's worse to have to search through
// buckets to find the right spot twice than to just
// resize in this corner case.
self.expand();
}
let hash = k.hash_keyed(self.k0, self.k1) as uint;
let idx = match self.bucket_for_key_with_hash(hash, &k) {
TableFull => fail!(~"Internal logic error"),
FoundEntry(idx) => idx,
FoundHole(idx) => {
let v = f(&k);
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
value: v});
self.size += 1;
idx
},
};
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
::cast::transmute_region(self.value_for_bucket(idx))
}
}
fn consume(&mut self, f: &fn(K, V)) {
let mut buckets = ~[];
self.buckets <-> buckets;
@ -506,6 +649,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
}
}
#[cfg(stage0)]
fn get(&self, k: &K) -> &'self V {
match self.find(k) {
Some(v) => v,
@ -513,6 +657,16 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn get<'a>(&'a self, k: &K) -> &'a V {
match self.find(k) {
Some(v) => v,
None => fail!(fmt!("No entry found for key: %?", k)),
}
}
/// Return true if the map contains a value for the specified key,
/// using equivalence
fn contains_key_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, key: &Q)
@ -525,6 +679,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
/// Return the value corresponding to the key in the map, using
/// equivalence
#[cfg(stage0)]
fn find_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, k: &Q)
-> Option<&'self V> {
match self.bucket_for_key_equiv(k) {
@ -532,6 +687,20 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
TableFull | FoundHole(_) => None,
}
}
/// Return the value corresponding to the key in the map, using
/// equivalence
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn find_equiv<'a, Q:Hash + IterBytes + Equiv<K>>(
&'a self, k: &Q) -> Option<&'a V>
{
match self.bucket_for_key_equiv(k) {
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
TableFull | FoundHole(_) => None,
}
}
}
impl<K:Hash + IterBytes + Eq,V:Eq> Eq for HashMap<K, V> {

View file

@ -101,11 +101,21 @@ impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
impl<T> BaseIter<T> for Option<T> {
/// Performs an operation on the contained value by reference
#[cfg(stage0)]
#[inline(always)]
fn each(&self, f: &fn(x: &'self T) -> bool) {
match *self { None => (), Some(ref t) => { f(t); } }
}
/// Performs an operation on the contained value by reference
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) {
match *self { None => (), Some(ref t) => { f(t); } }
}
#[inline(always)]
fn size_hint(&self) -> Option<uint> {
if self.is_some() { Some(1) } else { Some(0) }
@ -113,10 +123,19 @@ impl<T> BaseIter<T> for Option<T> {
}
impl<T> MutableIter<T> for Option<T> {
#[cfg(stage0)]
#[inline(always)]
fn each_mut(&mut self, f: &fn(&'self mut T) -> bool) {
match *self { None => (), Some(ref mut t) => { f(t); } }
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) {
match *self { None => (), Some(ref mut t) => { f(t); } }
}
}
impl<A> ExtendedIter<A> for Option<A> {
@ -182,17 +201,40 @@ pub impl<T> Option<T> {
* Update an optional value by optionally running its content by reference
* through a function that returns an option.
*/
#[cfg(stage0)]
#[inline(always)]
fn chain_ref<U>(&self, f: &fn(x: &'self T) -> Option<U>) -> Option<U> {
match *self { Some(ref x) => f(x), None => None }
}
/**
* Update an optional value by optionally running its content by reference
* through a function that returns an option.
*/
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
match *self { Some(ref x) => f(x), None => None }
}
/// Maps a `some` value from one type to another by reference
#[cfg(stage0)]
#[inline(always)]
fn map<U>(&self, f: &fn(&'self T) -> U) -> Option<U> {
match *self { Some(ref x) => Some(f(x)), None => None }
}
/// Maps a `some` value from one type to another by reference
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
match *self { Some(ref x) => Some(f(x)), None => None }
}
/// As `map`, but consumes the option and gives `f` ownership to avoid
/// copying.
#[inline(always)]
@ -201,11 +243,21 @@ pub impl<T> Option<T> {
}
/// Applies a function to the contained value or returns a default
#[cfg(stage0)]
#[inline(always)]
fn map_default<U>(&self, def: U, f: &fn(&'self T) -> U) -> U {
match *self { None => def, Some(ref t) => f(t) }
}
/// Applies a function to the contained value or returns a default
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
match *self { None => def, Some(ref t) => f(t) }
}
/// As `map_default`, but consumes the option and gives `f`
/// ownership to avoid copying.
#[inline(always)]
@ -244,6 +296,7 @@ pub impl<T> Option<T> {
case explicitly.
*/
#[inline(always)]
#[cfg(stage0)]
fn get_ref(&self) -> &'self T {
match *self {
Some(ref x) => x,
@ -251,6 +304,31 @@ pub impl<T> Option<T> {
}
}
/**
Gets an immutable reference to the value inside an option.
# Failure
Fails if the value equals `None`
# Safety note
In general, because this function may fail, its use is discouraged
(calling `get` on `None` is akin to dereferencing a null pointer).
Instead, prefer to use pattern matching and handle the `None`
case explicitly.
*/
#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn get_ref<'a>(&'a self) -> &'a T {
match *self {
Some(ref x) => x,
None => fail!(~"option::get_ref none")
}
}
/**
Gets a mutable reference to the value inside an option.
@ -266,6 +344,7 @@ pub impl<T> Option<T> {
case explicitly.
*/
#[inline(always)]
#[cfg(stage0)]
fn get_mut_ref(&mut self) -> &'self mut T {
match *self {
Some(ref mut x) => x,
@ -273,6 +352,31 @@ pub impl<T> Option<T> {
}
}
/**
Gets a mutable reference to the value inside an option.
# Failure
Fails if the value equals `None`
# Safety note
In general, because this function may fail, its use is discouraged
(calling `get` on `None` is akin to dereferencing a null pointer).
Instead, prefer to use pattern matching and handle the `None`
case explicitly.
*/
#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
match *self {
Some(ref mut x) => x,
None => fail!(~"option::get_mut_ref none")
}
}
#[inline(always)]
fn unwrap(self) -> T {
/*!

View file

@ -226,9 +226,16 @@ pub fn map_err<T:Copy,E,F:Copy>(res: &Result<T, E>, op: &fn(&E) -> F)
}
pub impl<T, E> Result<T, E> {
#[cfg(stage0)]
#[inline(always)]
fn get_ref(&self) -> &'self T { get_ref(self) }
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }
#[inline(always)]
fn is_ok(&self) -> bool { is_ok(self) }

View file

@ -22,7 +22,12 @@ pub trait EventLoop {
fn run(&mut self);
fn callback(&mut self, ~fn());
/// The asynchronous I/O services. Not all event loops may provide one
#[cfg(stage0)]
fn io(&mut self) -> Option<&'self mut IoFactoryObject>;
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn io<'a>(&'a mut self) -> Option<&'a mut IoFactoryObject>;
}
pub trait IoFactory {

View file

@ -272,6 +272,7 @@ pub impl Scheduler {
// XXX: Hack. This should return &'self mut but I don't know how to
// make the borrowcheck happy
#[cfg(stage0)]
fn task_from_last_cleanup_job(&mut self) -> &mut Task {
assert!(!self.cleanup_jobs.is_empty());
let last_job: &'self mut CleanupJob = &mut self.cleanup_jobs[0];
@ -285,6 +286,25 @@ pub impl Scheduler {
// borrows
return unsafe { transmute::<&Task, &mut Task>(last_task) };
}
// XXX: Hack. This should return &'self mut but I don't know how to
// make the borrowcheck happy
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn task_from_last_cleanup_job<'a>(&'a mut self) -> &mut Task {
assert!(!self.cleanup_jobs.is_empty());
let last_job: &'a mut CleanupJob = &mut self.cleanup_jobs[0];
let last_task: &'a Task = match last_job {
&RescheduleTask(~ref task) => task,
&RecycleTask(~ref task) => task,
&GiveTask(~ref task, _) => task,
};
// XXX: Pattern matching mutable pointers above doesn't work
// because borrowck thinks the three patterns are conflicting
// borrows
return unsafe { transmute::<&Task, &mut Task>(last_task) };
}
}
static TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack
@ -354,6 +374,7 @@ impl ThreadLocalScheduler {
}
}
#[cfg(stage0)]
fn get_scheduler(&mut self) -> &'self mut Scheduler {
unsafe {
let key = match self { &ThreadLocalScheduler(key) => key };
@ -370,6 +391,25 @@ impl ThreadLocalScheduler {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn get_scheduler<'a>(&'a mut self) -> &'a mut Scheduler {
unsafe {
let key = match self { &ThreadLocalScheduler(key) => key };
let mut value: *mut c_void = tls::get(key);
assert!(value.is_not_null());
{
let value_ptr = &mut value;
let sched: &mut ~Scheduler = {
transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr)
};
let sched: &mut Scheduler = &mut **sched;
return sched;
}
}
}
fn take_scheduler(&mut self) -> ~Scheduler {
unsafe {
let key = match self { &ThreadLocalScheduler(key) => key };

View file

@ -67,9 +67,17 @@ impl EventLoop for UvEventLoop {
}
}
#[cfg(stage0)]
fn io(&mut self) -> Option<&'self mut IoFactoryObject> {
Some(&mut self.uvio)
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn io<'a>(&'a mut self) -> Option<&'a mut IoFactoryObject> {
Some(&mut self.uvio)
}
}
#[test]
@ -89,9 +97,17 @@ fn test_callback_run_once() {
pub struct UvIoFactory(Loop);
pub impl UvIoFactory {
#[cfg(stage0)]
fn uv_loop(&mut self) -> &'self mut Loop {
match self { &UvIoFactory(ref mut ptr) => ptr }
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn uv_loop<'a>(&'a mut self) -> &'a mut Loop {
match self { &UvIoFactory(ref mut ptr) => ptr }
}
}
impl IoFactory for UvIoFactory {

View file

@ -39,7 +39,7 @@ use result::Result;
use comm::{stream, Chan, GenericChan, GenericPort, Port};
use prelude::*;
use result;
use task::rt::{task_id, sched_id, rust_task};
use task::rt::{task_id, sched_id};
use util;
use util::replace;
use unstable::finally::Finally;

View file

@ -56,10 +56,20 @@ impl<T> Map<uint, T> for TrieMap<T> {
/// Visit all key-value pairs in order
#[inline(always)]
#[cfg(stage0)]
fn each(&self, f: &fn(&uint, &'self T) -> bool) {
self.root.each(f);
}
/// Visit all key-value pairs in order
#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) {
self.root.each(f);
}
/// Visit all keys in order
#[inline(always)]
fn each_key(&self, f: &fn(&uint) -> bool) {
@ -68,10 +78,20 @@ impl<T> Map<uint, T> for TrieMap<T> {
/// Visit all values in order
#[inline(always)]
#[cfg(stage0)]
fn each_value(&self, f: &fn(&T) -> bool) {
self.each(|_, v| f(v))
}
/// Visit all values in order
#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) {
self.each(|_, v| f(v))
}
/// Iterate over the map and mutate the contained values
#[inline(always)]
fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) {
@ -79,6 +99,7 @@ impl<T> Map<uint, T> for TrieMap<T> {
}
/// Return a reference to the value corresponding to the key
#[cfg(stage0)]
#[inline(hint)]
fn find(&self, key: &uint) -> Option<&'self T> {
let mut node: &'self TrieNode<T> = &self.root;
@ -99,12 +120,46 @@ impl<T> Map<uint, T> for TrieMap<T> {
}
}
/// Return a reference to the value corresponding to the key
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(hint)]
fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
let mut node: &'a TrieNode<T> = &self.root;
let mut idx = 0;
loop {
match node.children[chunk(*key, idx)] {
Internal(ref x) => node = &**x,
External(stored, ref value) => {
if stored == *key {
return Some(value)
} else {
return None
}
}
Nothing => return None
}
idx += 1;
}
}
/// Return a mutable reference to the value corresponding to the key
#[cfg(stage0)]
#[inline(always)]
fn find_mut(&mut self, key: &uint) -> Option<&'self mut T> {
find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
}
/// Return a mutable reference to the value corresponding to the key
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
#[inline(always)]
fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
}
/// Insert a key-value pair into the map. An existing value for a
/// key is replaced by the new value. Return true if the key did
/// not already exist in the map.
@ -138,10 +193,20 @@ pub impl<T> TrieMap<T> {
/// Visit all key-value pairs in reverse order
#[inline(always)]
#[cfg(stage0)]
fn each_reverse(&self, f: &fn(&uint, &'self T) -> bool) {
self.root.each_reverse(f);
}
/// Visit all key-value pairs in reverse order
#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) {
self.root.each_reverse(f);
}
/// Visit all keys in reverse order
#[inline(always)]
fn each_key_reverse(&self, f: &fn(&uint) -> bool) {
@ -233,6 +298,7 @@ impl<T> TrieNode<T> {
}
impl<T> TrieNode<T> {
#[cfg(stage0)]
fn each(&self, f: &fn(&uint, &'self T) -> bool) -> bool {
for uint::range(0, self.children.len()) |idx| {
match self.children[idx] {
@ -244,6 +310,21 @@ impl<T> TrieNode<T> {
true
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
for uint::range(0, self.children.len()) |idx| {
match self.children[idx] {
Internal(ref x) => if !x.each(f) { return false },
External(k, ref v) => if !f(&k, v) { return false },
Nothing => ()
}
}
true
}
#[cfg(stage0)]
fn each_reverse(&self, f: &fn(&uint, &'self T) -> bool) -> bool {
for uint::range_rev(self.children.len(), 0) |idx| {
match self.children[idx - 1] {
@ -255,7 +336,21 @@ impl<T> TrieNode<T> {
true
}
fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
for uint::range_rev(self.children.len(), 0) |idx| {
match self.children[idx - 1] {
Internal(ref x) => if !x.each_reverse(f) { return false },
External(k, ref v) => if !f(&k, v) { return false },
Nothing => ()
}
}
true
}
fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
for vec::each_mut(self.children) |child| {
match *child {
Internal(ref mut x) => if !x.mutate_values(f) {

View file

@ -56,11 +56,13 @@ impl<T:Clone,U:Clone> Clone for (T, U) {
}
}
#[cfg(stage0)]
pub trait ImmutableTuple<T, U> {
fn first_ref(&self) -> &'self T;
fn second_ref(&self) -> &'self U;
}
#[cfg(stage0)]
impl<T, U> ImmutableTuple<T, U> for (T, U) {
#[inline(always)]
fn first_ref(&self) -> &'self T {
@ -76,6 +78,32 @@ impl<T, U> ImmutableTuple<T, U> for (T, U) {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub trait ImmutableTuple<T, U> {
fn first_ref<'a>(&'a self) -> &'a T;
fn second_ref<'a>(&'a self) -> &'a U;
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<T, U> ImmutableTuple<T, U> for (T, U) {
#[inline(always)]
fn first_ref<'a>(&'a self) -> &'a T {
match *self {
(ref t, _) => t,
}
}
#[inline(always)]
fn second_ref<'a>(&'a self) -> &'a U {
match *self {
(_, ref u) => u,
}
}
}
pub trait ExtendedTupleOps<A,B> {
fn zip(&self) -> ~[(A, B)];
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];

View file

@ -1763,6 +1763,7 @@ impl<'self,T:Copy> CopyableVector<T> for &'self const [T] {
}
}
#[cfg(stage0)]
pub trait ImmutableVector<T> {
fn slice(&self, start: uint, end: uint) -> &'self [T];
fn head(&self) -> &'self T;
@ -1785,6 +1786,7 @@ pub trait ImmutableVector<T> {
}
/// Extension methods for vectors
#[cfg(stage0)]
impl<'self,T> ImmutableVector<T> for &'self [T] {
/// Return a slice that points into another slice.
#[inline]
@ -1893,6 +1895,142 @@ impl<'self,T> ImmutableVector<T> for &'self [T] {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub trait ImmutableVector<'self, T> {
fn slice(&self, start: uint, end: uint) -> &'self [T];
fn head(&self) -> &'self T;
fn head_opt(&self) -> Option<&'self T>;
fn tail(&self) -> &'self [T];
fn tailn(&self, n: uint) -> &'self [T];
fn init(&self) -> &'self [T];
fn initn(&self, n: uint) -> &'self [T];
fn last(&self) -> &'self T;
fn last_opt(&self) -> Option<&'self T>;
fn each_reverse(&self, blk: &fn(&T) -> bool);
fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool);
fn foldr<U: Copy>(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U;
fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U];
fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U];
fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U];
fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool;
fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U];
fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U];
}
/// Extension methods for vectors
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
/// Return a slice that points into another slice.
#[inline]
fn slice(&self, start: uint, end: uint) -> &'self [T] {
slice(*self, start, end)
}
/// Returns the first element of a vector, failing if the vector is empty.
#[inline]
fn head(&self) -> &'self T { head(*self) }
/// Returns the first element of a vector
#[inline]
fn head_opt(&self) -> Option<&'self T> { head_opt(*self) }
/// Returns all but the first element of a vector
#[inline]
fn tail(&self) -> &'self [T] { tail(*self) }
/// Returns all but the first `n' elements of a vector
#[inline]
fn tailn(&self, n: uint) -> &'self [T] { tailn(*self, n) }
/// Returns all but the last elemnt of a vector
#[inline]
fn init(&self) -> &'self [T] { init(*self) }
/// Returns all but the last `n' elemnts of a vector
#[inline]
fn initn(&self, n: uint) -> &'self [T] { initn(*self, n) }
/// Returns the last element of a `v`, failing if the vector is empty.
#[inline]
fn last(&self) -> &'self T { last(*self) }
/// Returns the last element of a `v`, failing if the vector is empty.
#[inline]
fn last_opt(&self) -> Option<&'self T> { last_opt(*self) }
/// Iterates over a vector's elements in reverse.
#[inline]
fn each_reverse(&self, blk: &fn(&T) -> bool) {
each_reverse(*self, blk)
}
/// Iterates over a vector's elements and indices in reverse.
#[inline]
fn eachi_reverse(&self, blk: &fn(uint, &T) -> bool) {
eachi_reverse(*self, blk)
}
/// Reduce a vector from right to left
#[inline]
fn foldr<U:Copy>(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U {
foldr(*self, z, p)
}
/// Apply a function to each element of a vector and return the results
#[inline]
fn map<U>(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) }
/**
* Apply a function to the index and value of each element in the vector
* and return the results
*/
fn mapi<U>(&self, f: &fn(uint, t: &T) -> U) -> ~[U] {
mapi(*self, f)
}
#[inline]
fn map_r<U>(&self, f: &fn(x: &T) -> U) -> ~[U] {
let mut r = ~[];
let mut i = 0;
while i < self.len() {
r.push(f(&self[i]));
i += 1;
}
r
}
/**
* Returns true if the function returns true for all elements.
*
* If the vector is empty, true is returned.
*/
fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool {
alli(*self, f)
}
/**
* Apply a function to each element of a vector and return a concatenation
* of each result vector
*/
#[inline]
fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] {
flat_map(*self, f)
}
/**
* Apply a function to each element of a vector and return the results
*
* If function `f` returns `none` then that element is excluded from
* the resulting vector.
*/
#[inline]
fn filter_mapped<U:Copy>(&self, f: &fn(t: &T) -> Option<U>) -> ~[U] {
filter_mapped(*self, f)
}
}
pub trait ImmutableEqVector<T:Eq> {
fn position(&self, f: &fn(t: &T) -> bool) -> Option<uint>;
fn position_elem(&self, t: &T) -> Option<uint>;
@ -2353,6 +2491,7 @@ pub mod bytes {
// ___________________________________________________________________________
// ITERATION TRAIT METHODS
#[cfg(stage0)]
impl<'self,A> iter::BaseIter<A> for &'self [A] {
#[inline(always)]
fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) }
@ -2360,7 +2499,18 @@ impl<'self,A> iter::BaseIter<A> for &'self [A] {
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<'self,A> iter::BaseIter<A> for &'self [A] {
#[inline(always)]
fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) }
#[inline(always)]
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
// FIXME(#4148): This should be redundant
#[cfg(stage0)]
impl<A> iter::BaseIter<A> for ~[A] {
#[inline(always)]
fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) }
@ -2369,6 +2519,18 @@ impl<A> iter::BaseIter<A> for ~[A] {
}
// FIXME(#4148): This should be redundant
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<A> iter::BaseIter<A> for ~[A] {
#[inline(always)]
fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) }
#[inline(always)]
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
// FIXME(#4148): This should be redundant
#[cfg(stage0)]
impl<A> iter::BaseIter<A> for @[A] {
#[inline(always)]
fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) }
@ -2376,6 +2538,18 @@ impl<A> iter::BaseIter<A> for @[A] {
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
// FIXME(#4148): This should be redundant
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<A> iter::BaseIter<A> for @[A] {
#[inline(always)]
fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) }
#[inline(always)]
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
#[cfg(stage0)]
impl<'self,A> iter::MutableIter<A> for &'self mut [A] {
#[inline(always)]
fn each_mut(&mut self, blk: &fn(v: &'self mut A) -> bool) {
@ -2383,7 +2557,18 @@ impl<'self,A> iter::MutableIter<A> for &'self mut [A] {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<'self,A> iter::MutableIter<A> for &'self mut [A] {
#[inline(always)]
fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) {
each_mut(*self, blk)
}
}
// FIXME(#4148): This should be redundant
#[cfg(stage0)]
impl<A> iter::MutableIter<A> for ~[A] {
#[inline(always)]
fn each_mut(&mut self, blk: &fn(v: &'self mut A) -> bool) {
@ -2391,6 +2576,16 @@ impl<A> iter::MutableIter<A> for ~[A] {
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
impl<A> iter::MutableIter<A> for ~[A] {
#[inline(always)]
fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) {
each_mut(*self, blk)
}
}
// FIXME(#4148): This should be redundant
impl<A> iter::MutableIter<A> for @mut [A] {
#[inline(always)]