Skip to content

Commit 61b9e0e

Browse files
committed
core: changes in response to rust-lang#5656
1 parent 49de82c commit 61b9e0e

12 files changed

+700
-5
lines changed

src/libcore/condition.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct Condition<'self, T, U> {
2828
}
2929

3030
pub impl<'self, T, U> Condition<'self, T, U> {
31-
fn trap(&self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
31+
fn trap(&'self self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
3232
unsafe {
3333
let p : *RustClosure = ::cast::transmute(&h);
3434
let prev = task::local_data::local_data_get(self.key);

src/libcore/container.rs

+36
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub trait Mutable: Container {
2525
fn clear(&mut self);
2626
}
2727

28+
#[cfg(stage0)]
2829
pub trait Map<K, V>: Mutable {
2930
/// Return true if the map contains a value for the specified key
3031
fn contains_key(&self, key: &K) -> bool;
@@ -57,6 +58,41 @@ pub trait Map<K, V>: Mutable {
5758
fn remove(&mut self, key: &K) -> bool;
5859
}
5960

61+
#[cfg(stage1)]
62+
#[cfg(stage2)]
63+
#[cfg(stage3)]
64+
pub trait Map<K, V>: Mutable {
65+
/// Return true if the map contains a value for the specified key
66+
fn contains_key(&self, key: &K) -> bool;
67+
68+
// Visits all keys and values
69+
fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool);
70+
71+
/// Visit all keys
72+
fn each_key(&self, f: &fn(&K) -> bool);
73+
74+
/// Visit all values
75+
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool);
76+
77+
/// Iterate over the map and mutate the contained values
78+
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool);
79+
80+
/// Return a reference to the value corresponding to the key
81+
fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
82+
83+
/// Return a mutable reference to the value corresponding to the key
84+
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
85+
86+
/// Insert a key-value pair into the map. An existing value for a
87+
/// key is replaced by the new value. Return true if the key did
88+
/// not already exist in the map.
89+
fn insert(&mut self, key: K, value: V) -> bool;
90+
91+
/// Remove a key-value pair from the map. Return true if the key
92+
/// was present in the map, otherwise false.
93+
fn remove(&mut self, key: &K) -> bool;
94+
}
95+
6096
pub trait Set<T>: Mutable {
6197
/// Return true if the set contains a value
6298
fn contains(&self, value: &T) -> bool;

src/libcore/hashmap.rs

+171-2
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
186186
}
187187
}
188188

189+
#[cfg(stage0)]
189190
#[inline(always)]
190191
fn value_for_bucket(&self, idx: uint) -> &'self V {
191192
match self.buckets[idx] {
@@ -194,6 +195,18 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
194195
}
195196
}
196197
198+
#[cfg(stage1)]
199+
#[cfg(stage2)]
200+
#[cfg(stage3)]
201+
#[inline(always)]
202+
fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
203+
match self.buckets[idx] {
204+
Some(ref bkt) => &bkt.value,
205+
None => fail!(~"HashMap::find: internal logic error"),
206+
}
207+
}
208+
209+
#[cfg(stage0)]
197210
#[inline(always)]
198211
fn mut_value_for_bucket(&mut self, idx: uint) -> &'self mut V {
199212
match self.buckets[idx] {
@@ -202,6 +215,17 @@ priv impl<K:Hash + IterBytes + Eq,V> HashMap<K, V> {
202215
}
203216
}
204217
218+
#[cfg(stage1)]
219+
#[cfg(stage2)]
220+
#[cfg(stage3)]
221+
#[inline(always)]
222+
fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
223+
match self.buckets[idx] {
224+
Some(ref mut bkt) => &mut bkt.value,
225+
None => unreachable()
226+
}
227+
}
228+
205229
/// Inserts the key value pair into the buckets.
206230
/// Assumes that there will be a bucket.
207231
/// 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> {
307331
}
308332
309333
/// Visit all key-value pairs
334+
#[cfg(stage0)]
310335
fn each(&self, blk: &fn(&'self K, &'self V) -> bool) {
311336
for uint::range(0, self.buckets.len()) |i| {
312337
for self.buckets[i].each |bucket| {
@@ -317,19 +342,41 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
317342
}
318343
}
319344
345+
/// Visit all key-value pairs
346+
#[cfg(stage1)]
347+
#[cfg(stage2)]
348+
#[cfg(stage3)]
349+
fn each<'a>(&'a self, blk: &fn(&'a K, &'a V) -> bool) {
350+
for uint::range(0, self.buckets.len()) |i| {
351+
for self.buckets[i].each |bucket| {
352+
if !blk(&bucket.key, &bucket.value) {
353+
return;
354+
}
355+
}
356+
}
357+
}
358+
320359
/// Visit all keys
321360
fn each_key(&self, blk: &fn(k: &K) -> bool) {
322361
self.each(|k, _| blk(k))
323362
}
324363
325364
/// Visit all values
365+
#[cfg(stage0)]
326366
fn each_value(&self, blk: &fn(v: &V) -> bool) {
327367
self.each(|_, v| blk(v))
328368
}
329369
370+
/// Visit all values
371+
#[cfg(stage1)]
372+
#[cfg(stage2)]
373+
#[cfg(stage3)]
374+
fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) {
375+
self.each(|_, v| blk(v))
376+
}
377+
330378
/// Iterate over the map and mutate the contained values
331-
fn mutate_values(&mut self, blk: &fn(&'self K,
332-
&'self mut V) -> bool) {
379+
fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) {
333380
for uint::range(0, self.buckets.len()) |i| {
334381
match self.buckets[i] {
335382
Some(Bucket{key: ref key, value: ref mut value, _}) => {
@@ -341,14 +388,27 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
341388
}
342389
343390
/// Return a reference to the value corresponding to the key
391+
#[cfg(stage0)]
344392
fn find(&self, k: &K) -> Option<&'self V> {
345393
match self.bucket_for_key(k) {
346394
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
347395
TableFull | FoundHole(_) => None,
348396
}
349397
}
350398
399+
/// Return a reference to the value corresponding to the key
400+
#[cfg(stage1)]
401+
#[cfg(stage2)]
402+
#[cfg(stage3)]
403+
fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
404+
match self.bucket_for_key(k) {
405+
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
406+
TableFull | FoundHole(_) => None,
407+
}
408+
}
409+
351410
/// Return a mutable reference to the value corresponding to the key
411+
#[cfg(stage0)]
352412
fn find_mut(&mut self, k: &K) -> Option<&'self mut V> {
353413
let idx = match self.bucket_for_key(k) {
354414
FoundEntry(idx) => idx,
@@ -359,6 +419,20 @@ impl<K:Hash + IterBytes + Eq,V> Map<K, V> for HashMap<K, V> {
359419
}
360420
}
361421
422+
/// Return a mutable reference to the value corresponding to the key
423+
#[cfg(stage1)]
424+
#[cfg(stage2)]
425+
#[cfg(stage3)]
426+
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
427+
let idx = match self.bucket_for_key(k) {
428+
FoundEntry(idx) => idx,
429+
TableFull | FoundHole(_) => return None
430+
};
431+
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
432+
Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx)))
433+
}
434+
}
435+
362436
/// Insert a key-value pair into the map. An existing value for a
363437
/// key is replaced by the new value. Return true if the key did
364438
/// not already exist in the map.
@@ -431,6 +505,7 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
431505
432506
/// Return the value corresponding to the key in the map, or insert
433507
/// and return the value if it doesn't exist.
508+
#[cfg(stage0)]
434509
fn find_or_insert(&mut self, k: K, v: V) -> &'self V {
435510
if self.size >= self.resize_at {
436511
// n.b.: We could also do this after searching, so
@@ -459,8 +534,42 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
459534
}
460535
}
461536
537+
/// Return the value corresponding to the key in the map, or insert
538+
/// and return the value if it doesn't exist.
539+
#[cfg(stage1)]
540+
#[cfg(stage2)]
541+
#[cfg(stage3)]
542+
fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
543+
if self.size >= self.resize_at {
544+
// n.b.: We could also do this after searching, so
545+
// that we do not resize if this call to insert is
546+
// simply going to update a key in place. My sense
547+
// though is that it's worse to have to search through
548+
// buckets to find the right spot twice than to just
549+
// resize in this corner case.
550+
self.expand();
551+
}
552+
553+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
554+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
555+
TableFull => fail!(~"Internal logic error"),
556+
FoundEntry(idx) => idx,
557+
FoundHole(idx) => {
558+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
559+
value: v});
560+
self.size += 1;
561+
idx
562+
},
563+
};
564+
565+
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
566+
::cast::transmute_region(self.value_for_bucket(idx))
567+
}
568+
}
569+
462570
/// Return the value corresponding to the key in the map, or create,
463571
/// insert, and return a new value if it doesn't exist.
572+
#[cfg(stage0)]
464573
fn find_or_insert_with(&mut self, k: K, f: &fn(&K) -> V) -> &'self V {
465574
if self.size >= self.resize_at {
466575
// n.b.: We could also do this after searching, so
@@ -490,6 +599,40 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
490599
}
491600
}
492601
602+
/// Return the value corresponding to the key in the map, or create,
603+
/// insert, and return a new value if it doesn't exist.
604+
#[cfg(stage1)]
605+
#[cfg(stage2)]
606+
#[cfg(stage3)]
607+
fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
608+
if self.size >= self.resize_at {
609+
// n.b.: We could also do this after searching, so
610+
// that we do not resize if this call to insert is
611+
// simply going to update a key in place. My sense
612+
// though is that it's worse to have to search through
613+
// buckets to find the right spot twice than to just
614+
// resize in this corner case.
615+
self.expand();
616+
}
617+
618+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
619+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
620+
TableFull => fail!(~"Internal logic error"),
621+
FoundEntry(idx) => idx,
622+
FoundHole(idx) => {
623+
let v = f(&k);
624+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
625+
value: v});
626+
self.size += 1;
627+
idx
628+
},
629+
};
630+
631+
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
632+
::cast::transmute_region(self.value_for_bucket(idx))
633+
}
634+
}
635+
493636
fn consume(&mut self, f: &fn(K, V)) {
494637
let mut buckets = ~[];
495638
self.buckets <-> buckets;
@@ -506,13 +649,24 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
506649
}
507650
}
508651
652+
#[cfg(stage0)]
509653
fn get(&self, k: &K) -> &'self V {
510654
match self.find(k) {
511655
Some(v) => v,
512656
None => fail!(fmt!("No entry found for key: %?", k)),
513657
}
514658
}
515659
660+
#[cfg(stage1)]
661+
#[cfg(stage2)]
662+
#[cfg(stage3)]
663+
fn get<'a>(&'a self, k: &K) -> &'a V {
664+
match self.find(k) {
665+
Some(v) => v,
666+
None => fail!(fmt!("No entry found for key: %?", k)),
667+
}
668+
}
669+
516670
/// Return true if the map contains a value for the specified key,
517671
/// using equivalence
518672
fn contains_key_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, key: &Q)
@@ -525,13 +679,28 @@ pub impl<K: Hash + IterBytes + Eq, V> HashMap<K, V> {
525679

526680
/// Return the value corresponding to the key in the map, using
527681
/// equivalence
682+
#[cfg(stage0)]
528683
fn find_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, k: &Q)
529684
-> Option<&'self V> {
530685
match self.bucket_for_key_equiv(k) {
531686
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
532687
TableFull | FoundHole(_) => None,
533688
}
534689
}
690+
691+
/// Return the value corresponding to the key in the map, using
692+
/// equivalence
693+
#[cfg(stage1)]
694+
#[cfg(stage2)]
695+
#[cfg(stage3)]
696+
fn find_equiv<'a, Q:Hash + IterBytes + Equiv<K>>(
697+
&'a self, k: &Q) -> Option<&'a V>
698+
{
699+
match self.bucket_for_key_equiv(k) {
700+
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
701+
TableFull | FoundHole(_) => None,
702+
}
703+
}
535704
}
536705

537706
impl<K:Hash + IterBytes + Eq,V:Eq> Eq for HashMap<K, V> {

0 commit comments

Comments
 (0)