Migrate std::map to use core:#️⃣:Hash trait. Disable many hokey hashes.
This commit is contained in:
parent
f5093dff7b
commit
5d823d46ad
@ -64,7 +64,7 @@ impl <A: IterBytes> A: Hash {
|
||||
pure fn hash_keyed(k0: u64, k1: u64) -> u64 {
|
||||
unchecked {
|
||||
let s = &State(k0, k1);
|
||||
for self.iter_le_bytes |bytes| {
|
||||
for self.iter_bytes(true) |bytes| {
|
||||
s.input(bytes);
|
||||
}
|
||||
s.result_u64()
|
||||
@ -79,8 +79,8 @@ pure fn hash_keyed_2<A: IterBytes,
|
||||
k0: u64, k1: u64) -> u64 {
|
||||
unchecked {
|
||||
let s = &State(k0, k1);
|
||||
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
s.result_u64()
|
||||
}
|
||||
}
|
||||
@ -91,9 +91,9 @@ pure fn hash_keyed_3<A: IterBytes,
|
||||
k0: u64, k1: u64) -> u64 {
|
||||
unchecked {
|
||||
let s = &State(k0, k1);
|
||||
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for c.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for c.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
s.result_u64()
|
||||
}
|
||||
}
|
||||
@ -105,10 +105,10 @@ pure fn hash_keyed_4<A: IterBytes,
|
||||
k0: u64, k1: u64) -> u64 {
|
||||
unchecked {
|
||||
let s = &State(k0, k1);
|
||||
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for c.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for d.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for c.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for d.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
s.result_u64()
|
||||
}
|
||||
}
|
||||
@ -121,11 +121,11 @@ pure fn hash_keyed_5<A: IterBytes,
|
||||
k0: u64, k1: u64) -> u64 {
|
||||
unchecked {
|
||||
let s = &State(k0, k1);
|
||||
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for c.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for d.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for e.iter_le_bytes |bytes| { s.input(bytes); }
|
||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for c.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for d.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
for e.iter_bytes(true) |bytes| { s.input(bytes); }
|
||||
s.result_u64()
|
||||
}
|
||||
}
|
||||
|
@ -7,221 +7,273 @@ use io::Writer;
|
||||
type Cb = fn(buf: &[const u8]) -> bool;
|
||||
|
||||
trait IterBytes {
|
||||
fn iter_le_bytes(f: Cb);
|
||||
fn iter_be_bytes(f: Cb);
|
||||
fn iter_bytes(lsb0: bool, f: Cb);
|
||||
}
|
||||
|
||||
impl u8: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
fn iter_bytes(_lsb0: bool, f: Cb) {
|
||||
f([
|
||||
self,
|
||||
]);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
f([
|
||||
self as u8
|
||||
self
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
impl u16: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
f([
|
||||
self as u8,
|
||||
(self >> 8) as u8
|
||||
]);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
f([
|
||||
(self >> 8) as u8,
|
||||
self as u8
|
||||
]);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
if lsb0 {
|
||||
f([
|
||||
self as u8,
|
||||
(self >> 8) as u8
|
||||
]);
|
||||
} else {
|
||||
f([
|
||||
(self >> 8) as u8,
|
||||
self as u8
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl u32: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
f([
|
||||
self as u8,
|
||||
(self >> 8) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 24) as u8,
|
||||
]);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
f([
|
||||
(self >> 24) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 8) as u8,
|
||||
self as u8
|
||||
]);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
if lsb0 {
|
||||
f([
|
||||
self as u8,
|
||||
(self >> 8) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 24) as u8,
|
||||
]);
|
||||
} else {
|
||||
f([
|
||||
(self >> 24) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 8) as u8,
|
||||
self as u8
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl u64: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
f([
|
||||
self as u8,
|
||||
(self >> 8) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 24) as u8,
|
||||
(self >> 32) as u8,
|
||||
(self >> 40) as u8,
|
||||
(self >> 48) as u8,
|
||||
(self >> 56) as u8
|
||||
]);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
f([
|
||||
(self >> 56) as u8,
|
||||
(self >> 48) as u8,
|
||||
(self >> 40) as u8,
|
||||
(self >> 32) as u8,
|
||||
(self >> 24) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 8) as u8,
|
||||
self as u8
|
||||
]);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
if lsb0 {
|
||||
f([
|
||||
self as u8,
|
||||
(self >> 8) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 24) as u8,
|
||||
(self >> 32) as u8,
|
||||
(self >> 40) as u8,
|
||||
(self >> 48) as u8,
|
||||
(self >> 56) as u8
|
||||
]);
|
||||
} else {
|
||||
f([
|
||||
(self >> 56) as u8,
|
||||
(self >> 48) as u8,
|
||||
(self >> 40) as u8,
|
||||
(self >> 32) as u8,
|
||||
(self >> 24) as u8,
|
||||
(self >> 16) as u8,
|
||||
(self >> 8) as u8,
|
||||
self as u8
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl i8: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as u8).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as u8).iter_be_bytes(f) }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl i16: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as u16).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as u16).iter_be_bytes(f) }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as u16).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl i32: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as u32).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as u32).iter_be_bytes(f) }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as u32).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl i64: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as u64).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as u64).iter_be_bytes(f) }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as u64).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_word_size = "32")]
|
||||
impl uint: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as u32).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as u32).iter_be_bytes(f) }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as u32).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_word_size = "64")]
|
||||
impl uint: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as u64).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as u64).iter_be_bytes(f) }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as u64).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl int: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { (self as uint).iter_le_bytes(f) }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { (self as uint).iter_be_bytes(f) }
|
||||
}
|
||||
|
||||
impl ~[const u8]: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { f(self); }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { f(self); }
|
||||
}
|
||||
|
||||
impl @[const u8]: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) { f(self); }
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) { f(self); }
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as uint).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: IterBytes> &[const A]: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
for self.each |elt| {
|
||||
do elt.iter_le_bytes |bytes| {
|
||||
do elt.iter_bytes(lsb0) |bytes| {
|
||||
f(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move this to vec, probably.
|
||||
fn borrow<A>(a: &x/[const A]) -> &x/[const A] {
|
||||
a
|
||||
}
|
||||
|
||||
impl<A: IterBytes> ~[const A]: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
for self.each |elt| {
|
||||
do elt.iter_be_bytes |bytes| {
|
||||
f(bytes)
|
||||
}
|
||||
}
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
borrow(self).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_le_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B, f: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||
|
||||
impl<A: IterBytes> @[const A]: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
borrow(self).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_be_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B, f: Cb) {
|
||||
fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
|
||||
lsb0: bool, z: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
}
|
||||
|
||||
fn iter_le_bytes_3<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes>(a: &A, b: &B, c: &C, f: Cb) {
|
||||
fn iter_bytes_3<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes>(a: &A, b: &B, c: &C,
|
||||
lsb0: bool, z: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_le_bytes(|bytes| { flag = f(bytes); flag});
|
||||
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
c.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||
c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
}
|
||||
|
||||
fn iter_be_bytes_3<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes>(a: &A, b: &B, c: &C, f: Cb) {
|
||||
fn iter_bytes_4<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes,
|
||||
D: IterBytes>(a: &A, b: &B, c: &C,
|
||||
d: &D,
|
||||
lsb0: bool, z: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
c.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||
c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
}
|
||||
|
||||
fn iter_bytes_5<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes,
|
||||
D: IterBytes,
|
||||
E: IterBytes>(a: &A, b: &B, c: &C,
|
||||
d: &D, e: &E,
|
||||
lsb0: bool, z: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
}
|
||||
|
||||
fn iter_bytes_6<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes,
|
||||
D: IterBytes,
|
||||
E: IterBytes,
|
||||
F: IterBytes>(a: &A, b: &B, c: &C,
|
||||
d: &D, e: &E, f: &F,
|
||||
lsb0: bool, z: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
}
|
||||
|
||||
fn iter_bytes_7<A: IterBytes,
|
||||
B: IterBytes,
|
||||
C: IterBytes,
|
||||
D: IterBytes,
|
||||
E: IterBytes,
|
||||
F: IterBytes,
|
||||
G: IterBytes>(a: &A, b: &B, c: &C,
|
||||
d: &D, e: &E, f: &F,
|
||||
g: &G,
|
||||
lsb0: bool, z: Cb) {
|
||||
let mut flag = true;
|
||||
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
if !flag { return; }
|
||||
g.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
|
||||
}
|
||||
|
||||
impl &str: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
do str::byte_slice(self) |bytes| {
|
||||
f(bytes);
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
fn iter_bytes(_lsb0: bool, f: Cb) {
|
||||
do str::byte_slice(self) |bytes| {
|
||||
f(bytes);
|
||||
}
|
||||
@ -230,13 +282,7 @@ impl &str: IterBytes {
|
||||
|
||||
impl ~str: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
do str::byte_slice(self) |bytes| {
|
||||
f(bytes);
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
fn iter_bytes(_lsb0: bool, f: Cb) {
|
||||
do str::byte_slice(self) |bytes| {
|
||||
f(bytes);
|
||||
}
|
||||
@ -245,48 +291,41 @@ impl ~str: IterBytes {
|
||||
|
||||
impl @str: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
do str::byte_slice(self) |bytes| {
|
||||
f(bytes);
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
fn iter_bytes(_lsb0: bool, f: Cb) {
|
||||
do str::byte_slice(self) |bytes| {
|
||||
f(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: IterBytes> Option<A>: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
match self {
|
||||
Some(a) => iter_bytes_2(&0u8, &a, lsb0, f),
|
||||
None => 1u8.iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: IterBytes> &A: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
(*self).iter_le_bytes(f);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
(*self).iter_be_bytes(f);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(*self).iter_bytes(lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: IterBytes> @A: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
(*self).iter_le_bytes(f);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
(*self).iter_be_bytes(f);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(*self).iter_bytes(lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: IterBytes> ~A: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
(*self).iter_le_bytes(f);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
(*self).iter_be_bytes(f);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(*self).iter_bytes(lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,35 +333,22 @@ impl<A: IterBytes> ~A: IterBytes {
|
||||
// to the target; it just gives you the pointer-bytes.
|
||||
impl<A> *A: IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_le_bytes(f: Cb) {
|
||||
(self as uint).iter_le_bytes(f);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn iter_be_bytes(f: Cb) {
|
||||
(self as uint).iter_be_bytes(f);
|
||||
fn iter_bytes(lsb0: bool, f: Cb) {
|
||||
(self as uint).iter_bytes(lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
trait ToBytes {
|
||||
fn to_le_bytes() -> ~[u8];
|
||||
fn to_be_bytes() -> ~[u8];
|
||||
fn to_bytes(lsb0: bool) -> ~[u8];
|
||||
}
|
||||
|
||||
impl<A: IterBytes> A: ToBytes {
|
||||
fn to_le_bytes() -> ~[u8] {
|
||||
fn to_bytes(lsb0: bool) -> ~[u8] {
|
||||
let buf = io::mem_buffer();
|
||||
for self.iter_le_bytes |bytes| {
|
||||
for self.iter_bytes(lsb0) |bytes| {
|
||||
buf.write(bytes)
|
||||
}
|
||||
io::mem_buffer_buf(buf)
|
||||
}
|
||||
fn to_be_bytes() -> ~[u8] {
|
||||
let buf = io::mem_buffer();
|
||||
for self.iter_be_bytes |bytes| {
|
||||
buf.write(bytes)
|
||||
}
|
||||
io::mem_buffer_buf(buf)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,21 +19,12 @@ export hash_from_vec, hash_from_strs, hash_from_bytes;
|
||||
export hash_from_ints, hash_from_uints;
|
||||
export vec_from_set;
|
||||
|
||||
/**
|
||||
* A function that returns a hash of a value
|
||||
*
|
||||
* The hash should concentrate entropy in the lower bits.
|
||||
*/
|
||||
type hashfn<K> = fn~(key: &K) -> uint;
|
||||
|
||||
type eqfn<K> = fn~(key1: &K, key2: &K) -> bool;
|
||||
|
||||
/// A convenience type to treat a hashmap as a set
|
||||
type set<K> = hashmap<K, ()>;
|
||||
type set<K:Eq IterBytes Hash> = hashmap<K, ()>;
|
||||
|
||||
type hashmap<K, V> = chained::t<K, V>;
|
||||
type hashmap<K:Eq IterBytes Hash, V> = chained::t<K, V>;
|
||||
|
||||
trait map<K: copy, V: copy> {
|
||||
trait map<K:Eq IterBytes Hash copy, V: copy> {
|
||||
/// Return the number of elements in the map
|
||||
pure fn size() -> uint;
|
||||
|
||||
@ -119,14 +110,12 @@ mod chained {
|
||||
mut next: Option<@entry<K, V>>
|
||||
}
|
||||
|
||||
struct hashmap_<K, V> {
|
||||
struct hashmap_<K:Eq IterBytes Hash, V> {
|
||||
mut count: uint,
|
||||
mut chains: ~[mut Option<@entry<K,V>>],
|
||||
hasher: hashfn<K>,
|
||||
eqer: eqfn<K>
|
||||
mut chains: ~[mut Option<@entry<K,V>>]
|
||||
}
|
||||
|
||||
type t<K, V> = @hashmap_<K, V>;
|
||||
type t<K:Eq IterBytes Hash, V> = @hashmap_<K, V>;
|
||||
|
||||
enum search_result<K, V> {
|
||||
not_found,
|
||||
@ -134,7 +123,7 @@ mod chained {
|
||||
found_after(@entry<K,V>, @entry<K,V>)
|
||||
}
|
||||
|
||||
priv impl<K, V: copy> t<K, V> {
|
||||
priv impl<K:Eq IterBytes Hash, V: copy> t<K, V> {
|
||||
pure fn search_rem(k: &K, h: uint, idx: uint,
|
||||
e_root: @entry<K,V>) -> search_result<K,V> {
|
||||
let mut e0 = e_root;
|
||||
@ -149,7 +138,7 @@ mod chained {
|
||||
Some(e1) => {
|
||||
comp += 1u;
|
||||
unchecked {
|
||||
if e1.hash == h && self.eqer(&e1.key, k) {
|
||||
if e1.hash == h && e1.key == *k {
|
||||
debug!("search_tbl: present, comp %u, \
|
||||
hash %u, idx %u",
|
||||
comp, h, idx);
|
||||
@ -173,7 +162,7 @@ mod chained {
|
||||
}
|
||||
Some(e) => {
|
||||
unchecked {
|
||||
if e.hash == h && self.eqer(&e.key, k) {
|
||||
if e.hash == h && e.key == *k {
|
||||
debug!("search_tbl: present, comp %u, hash %u, \
|
||||
idx %u", 1u, h, idx);
|
||||
return found_first(idx, e);
|
||||
@ -218,7 +207,7 @@ mod chained {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: copy, V: copy> t<K, V>: map<K, V> {
|
||||
impl<K:Eq IterBytes Hash copy, V: copy> t<K, V>: map<K, V> {
|
||||
pure fn size() -> uint { self.count }
|
||||
|
||||
fn contains_key(+k: K) -> bool {
|
||||
@ -226,7 +215,7 @@ mod chained {
|
||||
}
|
||||
|
||||
fn contains_key_ref(k: &K) -> bool {
|
||||
let hash = self.hasher(k);
|
||||
let hash = k.hash_keyed(0,0) as uint;
|
||||
match self.search_tbl(k, hash) {
|
||||
not_found => false,
|
||||
found_first(*) | found_after(*) => true
|
||||
@ -234,7 +223,7 @@ mod chained {
|
||||
}
|
||||
|
||||
fn insert(+k: K, +v: V) -> bool {
|
||||
let hash = self.hasher(&k);
|
||||
let hash = k.hash_keyed(0,0) as uint;
|
||||
match self.search_tbl(&k, hash) {
|
||||
not_found => {
|
||||
self.count += 1u;
|
||||
@ -277,7 +266,7 @@ mod chained {
|
||||
|
||||
pure fn find(+k: K) -> Option<V> {
|
||||
unchecked {
|
||||
match self.search_tbl(&k, self.hasher(&k)) {
|
||||
match self.search_tbl(&k, k.hash_keyed(0,0) as uint) {
|
||||
not_found => None,
|
||||
found_first(_, entry) => Some(entry.value),
|
||||
found_after(_, entry) => Some(entry.value)
|
||||
@ -294,7 +283,7 @@ mod chained {
|
||||
}
|
||||
|
||||
fn remove(+k: K) -> bool {
|
||||
match self.search_tbl(&k, self.hasher(&k)) {
|
||||
match self.search_tbl(&k, k.hash_keyed(0,0) as uint) {
|
||||
not_found => false,
|
||||
found_first(idx, entry) => {
|
||||
self.count -= 1u;
|
||||
@ -341,7 +330,7 @@ mod chained {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: copy ToStr, V: ToStr copy> t<K, V>: ToStr {
|
||||
impl<K:Eq IterBytes Hash copy ToStr, V: ToStr copy> t<K, V>: ToStr {
|
||||
fn to_writer(wr: io::Writer) {
|
||||
if self.count == 0u {
|
||||
wr.write_str(~"{}");
|
||||
@ -367,7 +356,7 @@ mod chained {
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: copy, V: copy> t<K, V>: ops::Index<K, V> {
|
||||
impl<K:Eq IterBytes Hash copy, V: copy> t<K, V>: ops::Index<K, V> {
|
||||
pure fn index(&&k: K) -> V {
|
||||
unchecked {
|
||||
self.get(k)
|
||||
@ -379,11 +368,9 @@ mod chained {
|
||||
vec::to_mut(vec::from_elem(nchains, None))
|
||||
}
|
||||
|
||||
fn mk<K, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>) -> t<K,V> {
|
||||
fn mk<K:Eq IterBytes Hash, V: copy>() -> t<K,V> {
|
||||
let slf: t<K, V> = @hashmap_ {count: 0u,
|
||||
chains: chains(initial_capacity),
|
||||
hasher: hasher,
|
||||
eqer: eqer};
|
||||
chains: chains(initial_capacity)};
|
||||
slf
|
||||
}
|
||||
}
|
||||
@ -392,56 +379,49 @@ mod chained {
|
||||
Function: hashmap
|
||||
|
||||
Construct a hashmap.
|
||||
|
||||
Parameters:
|
||||
|
||||
hasher - The hash function for key type K
|
||||
eqer - The equality function for key type K
|
||||
*/
|
||||
fn hashmap<K: const, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>)
|
||||
fn hashmap<K:Eq IterBytes Hash const, V: copy>()
|
||||
-> hashmap<K, V> {
|
||||
chained::mk(hasher, eqer)
|
||||
chained::mk()
|
||||
}
|
||||
|
||||
/// Construct a hashmap for string-slice keys
|
||||
fn str_slice_hash<V: copy>() -> hashmap<&str, V> {
|
||||
return hashmap(|s| hash::hash_str(*s) as uint,
|
||||
|a,b| str::eq_slice(*a, *b));
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
/// Construct a hashmap for string keys
|
||||
fn str_hash<V: copy>() -> hashmap<~str, V> {
|
||||
return hashmap(str::hash, str::eq);
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
/// Construct a hashmap for boxed string keys
|
||||
fn box_str_hash<V: copy>() -> hashmap<@~str, V> {
|
||||
hashmap(|x: &@~str| str::hash(&**x),
|
||||
|x: &@~str, y: &@~str| str::eq(&**x, &**y))
|
||||
hashmap()
|
||||
}
|
||||
|
||||
/// Construct a hashmap for byte string keys
|
||||
fn bytes_hash<V: copy>() -> hashmap<~[u8], V> {
|
||||
return hashmap(vec::u8::hash, vec::u8::eq);
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
/// Construct a hashmap for int keys
|
||||
fn int_hash<V: copy>() -> hashmap<int, V> {
|
||||
return hashmap(|x| { int::hash(*x) }, |x, y| { int::eq(*x, *y)});
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
/// Construct a hashmap for uint keys
|
||||
fn uint_hash<V: copy>() -> hashmap<uint, V> {
|
||||
return hashmap(|x| { uint::hash(*x) }, |x, y| { uint::eq(*x, *y) } );
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
/// Convenience function for adding keys to a hashmap with nil type keys
|
||||
fn set_add<K: const copy>(set: set<K>, +key: K) -> bool {
|
||||
fn set_add<K:Eq IterBytes Hash const copy>(set: set<K>, +key: K) -> bool {
|
||||
set.insert(key, ())
|
||||
}
|
||||
|
||||
/// Convert a set into a vector.
|
||||
fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
|
||||
fn vec_from_set<T:Eq IterBytes Hash copy>(s: set<T>) -> ~[T] {
|
||||
let mut v = ~[];
|
||||
vec::reserve(v, s.size());
|
||||
do s.each_key() |k| {
|
||||
@ -452,9 +432,9 @@ fn vec_from_set<T: copy>(s: set<T>) -> ~[T] {
|
||||
}
|
||||
|
||||
/// Construct a hashmap from a vector
|
||||
fn hash_from_vec<K: const copy, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>,
|
||||
items: &[(K, V)]) -> hashmap<K, V> {
|
||||
let map = hashmap(hasher, eqer);
|
||||
fn hash_from_vec<K: Eq IterBytes Hash const copy, V: copy>(
|
||||
items: &[(K, V)]) -> hashmap<K, V> {
|
||||
let map = hashmap();
|
||||
do vec::iter(items) |item| {
|
||||
let (key, value) = item;
|
||||
map.insert(key, value);
|
||||
@ -464,22 +444,22 @@ fn hash_from_vec<K: const copy, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>,
|
||||
|
||||
/// Construct a hashmap from a vector with string keys
|
||||
fn hash_from_strs<V: copy>(items: &[(~str, V)]) -> hashmap<~str, V> {
|
||||
hash_from_vec(str::hash, str::eq, items)
|
||||
hash_from_vec(items)
|
||||
}
|
||||
|
||||
/// Construct a hashmap from a vector with byte keys
|
||||
fn hash_from_bytes<V: copy>(items: &[(~[u8], V)]) -> hashmap<~[u8], V> {
|
||||
hash_from_vec(vec::u8::hash, vec::u8::eq, items)
|
||||
hash_from_vec(items)
|
||||
}
|
||||
|
||||
/// Construct a hashmap from a vector with int keys
|
||||
fn hash_from_ints<V: copy>(items: &[(int, V)]) -> hashmap<int, V> {
|
||||
hash_from_vec(|x| { int::hash(*x) }, |x, y| { int::eq(*x, *y) }, items)
|
||||
hash_from_vec(items)
|
||||
}
|
||||
|
||||
/// Construct a hashmap from a vector with uint keys
|
||||
fn hash_from_uints<V: copy>(items: &[(uint, V)]) -> hashmap<uint, V> {
|
||||
hash_from_vec(|x| { uint::hash(*x) }, |x, y| { uint::eq(*x, *y) } , items)
|
||||
hash_from_vec(items)
|
||||
}
|
||||
|
||||
// XXX Transitional
|
||||
@ -594,13 +574,9 @@ mod tests {
|
||||
debug!("*** starting test_simple");
|
||||
pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
|
||||
pure fn uint_id(x: &uint) -> uint { *x }
|
||||
let hasher_uint: map::hashfn<uint> = uint_id;
|
||||
let eqer_uint: map::eqfn<uint> = eq_uint;
|
||||
let hasher_str: map::hashfn<~str> = str::hash;
|
||||
let eqer_str: map::eqfn<~str> = str::eq;
|
||||
debug!("uint -> uint");
|
||||
let hm_uu: map::hashmap<uint, uint> =
|
||||
map::hashmap::<uint, uint>(copy hasher_uint, copy eqer_uint);
|
||||
map::hashmap::<uint, uint>();
|
||||
assert (hm_uu.insert(10u, 12u));
|
||||
assert (hm_uu.insert(11u, 13u));
|
||||
assert (hm_uu.insert(12u, 14u));
|
||||
@ -616,7 +592,7 @@ mod tests {
|
||||
let twelve: ~str = ~"twelve";
|
||||
debug!("str -> uint");
|
||||
let hm_su: map::hashmap<~str, uint> =
|
||||
map::hashmap::<~str, uint>(copy hasher_str, copy eqer_str);
|
||||
map::hashmap::<~str, uint>();
|
||||
assert (hm_su.insert(~"ten", 12u));
|
||||
assert (hm_su.insert(eleven, 13u));
|
||||
assert (hm_su.insert(~"twelve", 14u));
|
||||
@ -630,7 +606,7 @@ mod tests {
|
||||
assert (hm_su.get(~"twelve") == 12u);
|
||||
debug!("uint -> str");
|
||||
let hm_us: map::hashmap<uint, ~str> =
|
||||
map::hashmap::<uint, ~str>(copy hasher_uint, copy eqer_uint);
|
||||
map::hashmap::<uint, ~str>();
|
||||
assert (hm_us.insert(10u, ~"twelve"));
|
||||
assert (hm_us.insert(11u, ~"thirteen"));
|
||||
assert (hm_us.insert(12u, ~"fourteen"));
|
||||
@ -643,7 +619,7 @@ mod tests {
|
||||
assert hm_us.get(12u) == ~"twelve";
|
||||
debug!("str -> str");
|
||||
let hm_ss: map::hashmap<~str, ~str> =
|
||||
map::hashmap::<~str, ~str>(copy hasher_str, copy eqer_str);
|
||||
map::hashmap::<~str, ~str>();
|
||||
assert (hm_ss.insert(ten, ~"twelve"));
|
||||
assert (hm_ss.insert(eleven, ~"thirteen"));
|
||||
assert (hm_ss.insert(twelve, ~"fourteen"));
|
||||
@ -668,10 +644,8 @@ mod tests {
|
||||
pure fn eq_uint(x: &uint, y: &uint) -> bool { *x == *y }
|
||||
pure fn uint_id(x: &uint) -> uint { *x }
|
||||
debug!("uint -> uint");
|
||||
let hasher_uint: map::hashfn<uint> = uint_id;
|
||||
let eqer_uint: map::eqfn<uint> = eq_uint;
|
||||
let hm_uu: map::hashmap<uint, uint> =
|
||||
map::hashmap::<uint, uint>(hasher_uint, eqer_uint);
|
||||
map::hashmap::<uint, uint>();
|
||||
let mut i: uint = 0u;
|
||||
while i < num_to_insert {
|
||||
assert (hm_uu.insert(i, i * i));
|
||||
@ -695,10 +669,8 @@ mod tests {
|
||||
i += 1u;
|
||||
}
|
||||
debug!("str -> str");
|
||||
let hasher_str: map::hashfn<~str> = str::hash;
|
||||
let eqer_str: map::eqfn<~str> = str::eq;
|
||||
let hm_ss: map::hashmap<~str, ~str> =
|
||||
map::hashmap::<~str, ~str>(hasher_str, eqer_str);
|
||||
map::hashmap::<~str, ~str>();
|
||||
i = 0u;
|
||||
while i < num_to_insert {
|
||||
assert hm_ss.insert(uint::to_str(i, 2u), uint::to_str(i * i, 2u));
|
||||
@ -745,10 +717,8 @@ mod tests {
|
||||
assert (hash(&0u) == hash(&1u));
|
||||
assert (hash(&2u) == hash(&3u));
|
||||
assert (hash(&0u) != hash(&2u));
|
||||
let hasher: map::hashfn<uint> = hash;
|
||||
let eqer: map::eqfn<uint> = eq;
|
||||
let hm: map::hashmap<uint, uint> =
|
||||
map::hashmap::<uint, uint>(hasher, eqer);
|
||||
map::hashmap::<uint, uint>();
|
||||
let mut i: uint = 0u;
|
||||
while i < num_to_insert {
|
||||
assert (hm.insert(i, i * i));
|
||||
@ -808,7 +778,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_contains_key() {
|
||||
let key = ~"k";
|
||||
let map = map::hashmap::<~str, ~str>(str::hash, str::eq);
|
||||
let map = map::hashmap::<~str, ~str>();
|
||||
assert (!map.contains_key(key));
|
||||
map.insert(key, ~"val");
|
||||
assert (map.contains_key(key));
|
||||
@ -817,7 +787,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_find() {
|
||||
let key = ~"k";
|
||||
let map = map::hashmap::<~str, ~str>(str::hash, str::eq);
|
||||
let map = map::hashmap::<~str, ~str>();
|
||||
assert (option::is_none(map.find(key)));
|
||||
map.insert(key, ~"val");
|
||||
assert (option::get(map.find(key)) == ~"val");
|
||||
@ -826,7 +796,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_clear() {
|
||||
let key = ~"k";
|
||||
let map = map::hashmap::<~str, ~str>(str::hash, str::eq);
|
||||
let map = map::hashmap::<~str, ~str>();
|
||||
map.insert(key, ~"val");
|
||||
assert (map.size() == 1);
|
||||
assert (map.contains_key(key));
|
||||
|
@ -310,6 +310,22 @@ enum binding_mode {
|
||||
bind_by_implicit_ref
|
||||
}
|
||||
|
||||
impl binding_mode : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
bind_by_value => 0u8.iter_bytes(lsb0, f),
|
||||
|
||||
bind_by_move => 1u8.iter_bytes(lsb0, f),
|
||||
|
||||
bind_by_ref(ref m) =>
|
||||
to_bytes::iter_bytes_2(&2u8, m, lsb0, f),
|
||||
|
||||
bind_by_implicit_ref =>
|
||||
3u8.iter_bytes(lsb0, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl binding_mode : cmp::Eq {
|
||||
pure fn eq(&&other: binding_mode) -> bool {
|
||||
match self {
|
||||
@ -368,6 +384,12 @@ enum pat_ {
|
||||
#[auto_serialize]
|
||||
enum mutability { m_mutbl, m_imm, m_const, }
|
||||
|
||||
impl mutability : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl mutability: cmp::Eq {
|
||||
pure fn eq(&&other: mutability) -> bool {
|
||||
(self as uint) == (other as uint)
|
||||
@ -443,6 +465,18 @@ enum inferable<T> {
|
||||
infer(node_id)
|
||||
}
|
||||
|
||||
impl<T: to_bytes::IterBytes> inferable<T> : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
expl(ref t) =>
|
||||
to_bytes::iter_bytes_2(&0u8, t, lsb0, f),
|
||||
|
||||
infer(ref n) =>
|
||||
to_bytes::iter_bytes_2(&1u8, n, lsb0, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:cmp::Eq> inferable<T> : cmp::Eq {
|
||||
pure fn eq(&&other: inferable<T>) -> bool {
|
||||
match self {
|
||||
@ -467,6 +501,13 @@ impl<T:cmp::Eq> inferable<T> : cmp::Eq {
|
||||
#[auto_serialize]
|
||||
enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
|
||||
|
||||
impl rmode : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl rmode : cmp::Eq {
|
||||
pure fn eq(&&other: rmode) -> bool {
|
||||
(self as uint) == (other as uint)
|
||||
@ -822,6 +863,12 @@ enum trait_method {
|
||||
#[auto_serialize]
|
||||
enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
|
||||
|
||||
impl int_ty : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl int_ty: cmp::Eq {
|
||||
pure fn eq(&&other: int_ty) -> bool {
|
||||
match (self, other) {
|
||||
@ -845,6 +892,12 @@ impl int_ty: cmp::Eq {
|
||||
#[auto_serialize]
|
||||
enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
|
||||
|
||||
impl uint_ty : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl uint_ty: cmp::Eq {
|
||||
pure fn eq(&&other: uint_ty) -> bool {
|
||||
match (self, other) {
|
||||
@ -866,6 +919,11 @@ impl uint_ty: cmp::Eq {
|
||||
#[auto_serialize]
|
||||
enum float_ty { ty_f, ty_f32, ty_f64, }
|
||||
|
||||
impl float_ty : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
impl float_ty: cmp::Eq {
|
||||
pure fn eq(&&other: float_ty) -> bool {
|
||||
match (self, other) {
|
||||
@ -954,6 +1012,24 @@ enum ty_ {
|
||||
ty_infer,
|
||||
}
|
||||
|
||||
// Equality and byte-iter (hashing) can be quite approximate for AST types.
|
||||
// since we only care about this for normalizing them to "real" types.
|
||||
impl ty : cmp::Eq {
|
||||
pure fn eq(&&other: ty) -> bool {
|
||||
ptr::addr_of(self) == ptr::addr_of(other)
|
||||
}
|
||||
pure fn ne(&&other: ty) -> bool {
|
||||
ptr::addr_of(self) != ptr::addr_of(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl ty : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[auto_serialize]
|
||||
type arg = {mode: mode, ty: @ty, ident: ident, id: node_id};
|
||||
|
||||
@ -971,6 +1047,12 @@ enum purity {
|
||||
extern_fn, // declared with "extern fn"
|
||||
}
|
||||
|
||||
impl purity : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl purity : cmp::Eq {
|
||||
pure fn eq(&&other: purity) -> bool {
|
||||
(self as uint) == (other as uint)
|
||||
@ -985,6 +1067,12 @@ enum ret_style {
|
||||
return_val, // everything else
|
||||
}
|
||||
|
||||
impl ret_style : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ret_style : cmp::Eq {
|
||||
pure fn eq(&&other: ret_style) -> bool {
|
||||
match (self, other) {
|
||||
@ -1276,6 +1364,12 @@ enum item_ {
|
||||
#[auto_serialize]
|
||||
enum class_mutability { class_mutable, class_immutable }
|
||||
|
||||
impl class_mutability : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl class_mutability : cmp::Eq {
|
||||
pure fn eq(&&other: class_mutability) -> bool {
|
||||
match (self, other) {
|
||||
|
@ -251,28 +251,16 @@ pure fn is_call_expr(e: @expr) -> bool {
|
||||
match e.node { expr_call(_, _, _) => true, _ => false }
|
||||
}
|
||||
|
||||
pure fn eq_ty(a: &@ty, b: &@ty) -> bool { box::ptr_eq(*a, *b) }
|
||||
|
||||
pure fn hash_ty(t: &@ty) -> uint {
|
||||
let res = (t.span.lo << 16u) + t.span.hi;
|
||||
return res;
|
||||
}
|
||||
|
||||
pure fn def_eq(a: &ast::def_id, b: &ast::def_id) -> bool {
|
||||
a.crate == b.crate && a.node == b.node
|
||||
}
|
||||
|
||||
pure fn hash_def(d: &ast::def_id) -> uint {
|
||||
let mut h = 5381u;
|
||||
h = (h << 5u) + h ^ (d.crate as uint);
|
||||
h = (h << 5u) + h ^ (d.node as uint);
|
||||
return h;
|
||||
// This makes def_id hashable
|
||||
impl def_id : core::to_bytes::IterBytes {
|
||||
#[inline(always)]
|
||||
fn iter_bytes(lsb0: bool, f: core::to_bytes::Cb) {
|
||||
core::to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
fn new_def_hash<V: copy>() -> std::map::hashmap<ast::def_id, V> {
|
||||
let hasher: std::map::hashfn<ast::def_id> = hash_def;
|
||||
let eqer: std::map::eqfn<ast::def_id> = def_eq;
|
||||
return std::map::hashmap::<ast::def_id, V>(hasher, eqer);
|
||||
return std::map::hashmap::<ast::def_id, V>();
|
||||
}
|
||||
|
||||
fn block_from_expr(e: @expr) -> blk {
|
||||
|
@ -345,8 +345,7 @@ fn mk_ident_interner() -> ident_interner {
|
||||
@~"dtor", @~"main", @~"<opaque>", @~"blk", @~"static",
|
||||
@~"intrinsic", @~"__foreign_mod__"];
|
||||
|
||||
let rv = interner::mk_prefill::<@~str>(|x| str::hash(*x),
|
||||
|x,y| str::eq(*x, *y), init_vec);
|
||||
let rv = interner::mk_prefill::<@~str>(init_vec);
|
||||
|
||||
/* having multiple interners will just confuse the serializer */
|
||||
unsafe{ assert task::local_data_get(interner_key!()).is_none() };
|
||||
@ -357,7 +356,7 @@ fn mk_ident_interner() -> ident_interner {
|
||||
/* for when we don't care about the contents; doesn't interact with TLD or
|
||||
serialization */
|
||||
fn mk_fake_ident_interner() -> ident_interner {
|
||||
interner::mk::<@~str>(|x| str::hash(*x), |x,y| str::eq(*x, *y))
|
||||
interner::mk::<@~str>()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,40 +2,39 @@
|
||||
// allows bidirectional lookup; i.e. given a value, one can easily find the
|
||||
// type, and vice versa.
|
||||
use std::map;
|
||||
use std::map::{hashmap, hashfn, eqfn};
|
||||
use std::map::hashmap;
|
||||
use dvec::DVec;
|
||||
use cmp::Eq;
|
||||
use hash::Hash;
|
||||
use to_bytes::IterBytes;
|
||||
|
||||
type hash_interner<T: const> =
|
||||
{map: hashmap<T, uint>,
|
||||
vect: DVec<T>,
|
||||
hasher: hashfn<T>,
|
||||
eqer: eqfn<T>};
|
||||
vect: DVec<T>};
|
||||
|
||||
fn mk<T: const copy>(+hasher: hashfn<T>, +eqer: eqfn<T>) -> interner<T> {
|
||||
let m = map::hashmap::<T, uint>(copy hasher, copy eqer);
|
||||
fn mk<T:Eq IterBytes Hash const copy>() -> interner<T> {
|
||||
let m = map::hashmap::<T, uint>();
|
||||
let hi: hash_interner<T> =
|
||||
{map: m, vect: DVec(), hasher: hasher, eqer: eqer};
|
||||
{map: m, vect: DVec()};
|
||||
return hi as interner::<T>;
|
||||
}
|
||||
|
||||
fn mk_prefill<T: const copy>(hasher: hashfn<T>, eqer: eqfn<T>,
|
||||
init: ~[T]) -> interner<T> {
|
||||
|
||||
let rv = mk(copy hasher, copy eqer);
|
||||
fn mk_prefill<T:Eq IterBytes Hash const copy>(init: ~[T]) -> interner<T> {
|
||||
let rv = mk();
|
||||
for init.each() |v| { rv.intern(v); }
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* when traits can extend traits, we should extend index<uint,T> to get [] */
|
||||
trait interner<T: const copy> {
|
||||
trait interner<T:Eq IterBytes Hash const copy> {
|
||||
fn intern(T) -> uint;
|
||||
fn gensym(T) -> uint;
|
||||
pure fn get(uint) -> T;
|
||||
fn len() -> uint;
|
||||
}
|
||||
|
||||
impl <T: const copy> hash_interner<T>: interner<T> {
|
||||
impl <T:Eq IterBytes Hash const copy> hash_interner<T>: interner<T> {
|
||||
fn intern(val: T) -> uint {
|
||||
match self.map.find(val) {
|
||||
Some(idx) => return idx,
|
||||
|
@ -1057,7 +1057,7 @@ fn name_has_type(tn: type_names, s: ~str) -> Option<TypeRef> {
|
||||
fn mk_type_names() -> type_names {
|
||||
pure fn hash(t: &TypeRef) -> uint { *t as uint }
|
||||
pure fn eq(a: &TypeRef, b: &TypeRef) -> bool { *a == *b }
|
||||
@{type_names: std::map::hashmap(hash, eq),
|
||||
@{type_names: std::map::hashmap(),
|
||||
named_types: std::map::str_hash()}
|
||||
}
|
||||
|
||||
|
@ -404,8 +404,24 @@ fn save_and_restore<T:copy,U>(&save_and_restore_t: T, f: fn() -> U) -> U {
|
||||
}
|
||||
|
||||
/// Creates and returns a new root_map
|
||||
|
||||
impl root_map_key : cmp::Eq {
|
||||
pure fn eq(&&other: root_map_key) -> bool {
|
||||
self.id == other.id && self.derefs == other.derefs
|
||||
}
|
||||
pure fn ne(&&other: root_map_key) -> bool {
|
||||
! (self == other)
|
||||
}
|
||||
}
|
||||
|
||||
impl root_map_key : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
fn root_map() -> root_map {
|
||||
return hashmap(root_map_key_hash, root_map_key_eq);
|
||||
return hashmap();
|
||||
|
||||
pure fn root_map_key_eq(k1: &root_map_key, k2: &root_map_key) -> bool {
|
||||
k1.id == k2.id && k1.derefs == k2.derefs
|
||||
|
@ -309,7 +309,7 @@ fn Atom(n: uint) -> Atom {
|
||||
|
||||
/// Creates a hash table of atoms.
|
||||
fn atom_hashmap<V:copy>() -> hashmap<Atom,V> {
|
||||
hashmap::<Atom,V>(|x| { uint::hash(*x) }, |x, y| { uint::eq(*x, *y) })
|
||||
hashmap::<Atom,V>()
|
||||
}
|
||||
|
||||
/// One local scope.
|
||||
|
@ -2658,10 +2658,10 @@ fn trans_crate(sess: session::session,
|
||||
tydescs: ty::new_ty_hash(),
|
||||
mut finished_tydescs: false,
|
||||
external: ast_util::new_def_hash(),
|
||||
monomorphized: map::hashmap(hash_mono_id, sys::shape_eq),
|
||||
monomorphized: map::hashmap(),
|
||||
monomorphizing: ast_util::new_def_hash(),
|
||||
type_use_cache: ast_util::new_def_hash(),
|
||||
vtables: map::hashmap(hash_mono_id, sys::shape_eq),
|
||||
vtables: map::hashmap(),
|
||||
const_cstr_cache: map::str_hash(),
|
||||
const_globals: int_hash::<ValueRef>(),
|
||||
module_data: str_hash::<ValueRef>(),
|
||||
|
@ -1125,24 +1125,24 @@ impl mono_id_: cmp::Eq {
|
||||
pure fn ne(&&other: mono_id_) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
pure fn hash_mono_id(mi: &mono_id) -> uint {
|
||||
let mut h = syntax::ast_util::hash_def(&mi.def);
|
||||
for vec::each(mi.params) |param| {
|
||||
h = h * match param {
|
||||
mono_precise(ty, vts) => {
|
||||
let mut h = ty::type_id(ty);
|
||||
do option::iter(vts) |vts| {
|
||||
for vec::each(vts) |vt| {
|
||||
h += hash_mono_id(&vt);
|
||||
}
|
||||
}
|
||||
h
|
||||
}
|
||||
mono_any => 1u,
|
||||
mono_repr(sz, align) => sz * (align + 2u)
|
||||
impl mono_param_id : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
mono_precise(t, mids) =>
|
||||
to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f),
|
||||
|
||||
mono_any => 1u8.iter_bytes(lsb0, f),
|
||||
|
||||
mono_repr(a,b) =>
|
||||
to_bytes::iter_bytes_3(&2u8, &a, &b, lsb0, f)
|
||||
}
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
impl mono_id_ : core::to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
|
||||
|
@ -22,8 +22,34 @@ use option::is_some;
|
||||
|
||||
use ty_ctxt = middle::ty::ctxt;
|
||||
|
||||
type nominal_id = @{did: ast::def_id, parent_id: Option<ast::def_id>,
|
||||
type nominal_id_ = {did: ast::def_id, parent_id: Option<ast::def_id>,
|
||||
tps: ~[ty::t]};
|
||||
type nominal_id = @nominal_id_;
|
||||
|
||||
impl nominal_id_ : core::cmp::Eq {
|
||||
pure fn eq(&&other: nominal_id_) -> bool {
|
||||
if self.did != other.did ||
|
||||
self.parent_id != other.parent_id {
|
||||
false
|
||||
} else {
|
||||
do vec::all2(self.tps, other.tps) |m_tp, n_tp| {
|
||||
ty::type_id(m_tp) == ty::type_id(n_tp)
|
||||
}
|
||||
}
|
||||
}
|
||||
pure fn ne(&&other: nominal_id_) -> bool {
|
||||
! (self == other)
|
||||
}
|
||||
}
|
||||
|
||||
impl nominal_id_ : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.did, &self.parent_id, lsb0, f);
|
||||
for self.tps.each |t| {
|
||||
ty::type_id(t).iter_bytes(lsb0, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id,
|
||||
parent_id: Option<ast::def_id>,
|
||||
@ -32,31 +58,8 @@ fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id,
|
||||
@{did: did, parent_id: parent_id, tps: tps_norm}
|
||||
}
|
||||
|
||||
pure fn hash_nominal_id(ri: &nominal_id) -> uint {
|
||||
let mut h = 5381u;
|
||||
h *= 33u;
|
||||
h += ri.did.crate as uint;
|
||||
h *= 33u;
|
||||
h += ri.did.node as uint;
|
||||
for vec::each(ri.tps) |t| {
|
||||
h *= 33u;
|
||||
h += ty::type_id(t);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
pure fn eq_nominal_id(mi: &nominal_id, ni: &nominal_id) -> bool {
|
||||
if mi.did != ni.did {
|
||||
false
|
||||
} else {
|
||||
do vec::all2(mi.tps, ni.tps) |m_tp, n_tp| {
|
||||
ty::type_id(m_tp) == ty::type_id(n_tp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_nominal_id_hash<T: copy>() -> hashmap<nominal_id, T> {
|
||||
return hashmap(hash_nominal_id, eq_nominal_id);
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
type enum_data = {did: ast::def_id, substs: ty::substs};
|
||||
@ -193,7 +196,7 @@ fn mk_ctxt(llmod: ModuleRef) -> ctxt {
|
||||
pad: 0u16,
|
||||
tag_id_to_index: new_nominal_id_hash(),
|
||||
tag_order: DVec(),
|
||||
resources: interner::mk(hash_nominal_id, eq_nominal_id),
|
||||
resources: interner::mk(),
|
||||
llshapetablesty: llshapetablesty,
|
||||
llshapetables: llshapetables};
|
||||
}
|
||||
|
@ -226,7 +226,25 @@ type field_ty = {
|
||||
|
||||
// Contains information needed to resolve types and (in the future) look up
|
||||
// the types of AST nodes.
|
||||
type creader_cache = hashmap<{cnum: int, pos: uint, len: uint}, t>;
|
||||
type creader_cache_key = {cnum: int, pos: uint, len: uint};
|
||||
type creader_cache = hashmap<creader_cache_key, t>;
|
||||
|
||||
impl creader_cache_key : cmp::Eq {
|
||||
pure fn eq(&&other: creader_cache_key) -> bool {
|
||||
self.cnum == other.cnum &&
|
||||
self.pos == other.pos &&
|
||||
self.len == other.len
|
||||
}
|
||||
pure fn ne(&&other: creader_cache_key) -> bool {
|
||||
!(self == other)
|
||||
}
|
||||
}
|
||||
|
||||
impl creader_cache_key : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
type intern_key = {struct: sty, o_def_id: Option<ast::def_id>};
|
||||
|
||||
@ -237,6 +255,12 @@ impl intern_key: cmp::Eq {
|
||||
pure fn ne(&&other: intern_key) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl intern_key : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.struct, &self.o_def_id, lsb0, f);
|
||||
}
|
||||
}
|
||||
|
||||
enum ast_ty_to_ty_cache_entry {
|
||||
atttce_unresolved, /* not resolved yet */
|
||||
atttce_resolved(t) /* resolved to a type, irrespective of region */
|
||||
@ -366,6 +390,12 @@ enum closure_kind {
|
||||
ck_uniq,
|
||||
}
|
||||
|
||||
impl closure_kind : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(self as u8).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl closure_kind : cmp::Eq {
|
||||
pure fn eq(&&other: closure_kind) -> bool {
|
||||
(self as uint) == (other as uint)
|
||||
@ -378,6 +408,18 @@ enum fn_proto {
|
||||
proto_vstore(vstore)
|
||||
}
|
||||
|
||||
impl fn_proto : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
proto_bare =>
|
||||
0u8.iter_bytes(lsb0, f),
|
||||
|
||||
proto_vstore(ref v) =>
|
||||
to_bytes::iter_bytes_2(&1u8, v, lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fn_proto : cmp::Eq {
|
||||
pure fn eq(&&other: fn_proto) -> bool {
|
||||
match self {
|
||||
@ -444,6 +486,13 @@ impl param_ty: cmp::Eq {
|
||||
pure fn ne(&&other: param_ty) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl param_ty : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.idx, &self.def_id, lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Representation of regions:
|
||||
enum region {
|
||||
/// Bound regions are found (primarily) in function types. They indicate
|
||||
@ -606,6 +655,28 @@ enum InferTy {
|
||||
IntVar(IntVid)
|
||||
}
|
||||
|
||||
impl InferTy : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f),
|
||||
IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl param_bound : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
bound_copy => 0u8.iter_bytes(lsb0, f),
|
||||
bound_owned => 1u8.iter_bytes(lsb0, f),
|
||||
bound_send => 2u8.iter_bytes(lsb0, f),
|
||||
bound_const => 3u8.iter_bytes(lsb0, f),
|
||||
bound_trait(ref t) =>
|
||||
to_bytes::iter_bytes_2(&4u8, t, lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait vid {
|
||||
pure fn to_uint() -> uint;
|
||||
pure fn to_str() -> ~str;
|
||||
@ -657,6 +728,30 @@ impl purity: purity_to_str {
|
||||
}
|
||||
}
|
||||
|
||||
impl RegionVid : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(*self).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl TyVid : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(*self).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntVid : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(*self).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl FnVid : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
(*self).iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
fn param_bounds_to_kind(bounds: param_bounds) -> kind {
|
||||
let mut kind = kind_noncopyable();
|
||||
for vec::each(*bounds) |bound| {
|
||||
@ -701,18 +796,11 @@ type node_type_table = @smallintmap::SmallIntMap<t>;
|
||||
|
||||
fn mk_rcache() -> creader_cache {
|
||||
type val = {cnum: int, pos: uint, len: uint};
|
||||
pure fn hash_cache_entry(k: &val) -> uint {
|
||||
(k.cnum as uint) + k.pos + k.len
|
||||
}
|
||||
pure fn eq_cache_entries(a: &val, b: &val) -> bool {
|
||||
a.cnum == b.cnum && a.pos == b.pos && a.len == b.len
|
||||
}
|
||||
return map::hashmap(hash_cache_entry, eq_cache_entries);
|
||||
return map::hashmap();
|
||||
}
|
||||
|
||||
fn new_ty_hash<V: copy>() -> map::hashmap<t, V> {
|
||||
map::hashmap(|t: &t| type_id(*t),
|
||||
|a: &t, b: &t| type_id(*a) == type_id(*b))
|
||||
map::hashmap()
|
||||
}
|
||||
|
||||
fn mk_ctxt(s: session::session,
|
||||
@ -721,11 +809,7 @@ fn mk_ctxt(s: session::session,
|
||||
freevars: freevars::freevar_map,
|
||||
region_map: middle::region::region_map,
|
||||
region_paramd_items: middle::region::region_paramd_items) -> ctxt {
|
||||
pure fn hash_intern_key(k: &intern_key) -> uint {
|
||||
hash_type_structure(&k.struct) +
|
||||
option::map_default(k.o_def_id, 0u, |d| ast_util::hash_def(&d))
|
||||
}
|
||||
let interner = map::hashmap(hash_intern_key, sys::shape_eq);
|
||||
let interner = map::hashmap();
|
||||
let vecs_implicitly_copyable =
|
||||
get_lint_level(s.lint_settings.default_settings,
|
||||
lint::vecs_implicitly_copyable) == allow;
|
||||
@ -750,8 +834,7 @@ fn mk_ctxt(s: session::session,
|
||||
needs_drop_cache: new_ty_hash(),
|
||||
needs_unwind_cleanup_cache: new_ty_hash(),
|
||||
kind_cache: new_ty_hash(),
|
||||
ast_ty_to_ty_cache: map::hashmap(
|
||||
ast_util::hash_ty, ast_util::eq_ty),
|
||||
ast_ty_to_ty_cache: map::hashmap(),
|
||||
enum_var_cache: new_def_hash(),
|
||||
trait_method_cache: new_def_hash(),
|
||||
ty_param_bounds: map::int_hash(),
|
||||
@ -2314,6 +2397,167 @@ fn index_sty(cx: ctxt, sty: &sty) -> Option<mt> {
|
||||
}
|
||||
}
|
||||
|
||||
impl bound_region : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
ty::br_self => 0u8.iter_bytes(lsb0, f),
|
||||
|
||||
ty::br_anon(ref idx) =>
|
||||
to_bytes::iter_bytes_2(&1u8, idx, lsb0, f),
|
||||
|
||||
ty::br_named(ref ident) =>
|
||||
to_bytes::iter_bytes_2(&2u8, ident, lsb0, f),
|
||||
|
||||
ty::br_cap_avoid(ref id, ref br) =>
|
||||
to_bytes::iter_bytes_3(&3u8, id, br, lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl region : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
re_bound(ref br) =>
|
||||
to_bytes::iter_bytes_2(&0u8, br, lsb0, f),
|
||||
|
||||
re_free(ref id, ref br) =>
|
||||
to_bytes::iter_bytes_3(&1u8, id, br, lsb0, f),
|
||||
|
||||
re_scope(ref id) =>
|
||||
to_bytes::iter_bytes_2(&2u8, id, lsb0, f),
|
||||
|
||||
re_var(ref id) =>
|
||||
to_bytes::iter_bytes_2(&3u8, id, lsb0, f),
|
||||
|
||||
re_static => 4u8.iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl vstore : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
vstore_fixed(ref u) =>
|
||||
to_bytes::iter_bytes_2(&0u8, u, lsb0, f),
|
||||
|
||||
vstore_uniq => 1u8.iter_bytes(lsb0, f),
|
||||
vstore_box => 2u8.iter_bytes(lsb0, f),
|
||||
|
||||
vstore_slice(ref r) =>
|
||||
to_bytes::iter_bytes_2(&3u8, r, lsb0, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl substs : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_3(&self.self_r,
|
||||
&self.self_ty,
|
||||
&self.tps, lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl mt : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.ty,
|
||||
&self.mutbl, lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl field : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.ident,
|
||||
&self.mt, lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl arg : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.mode,
|
||||
&self.ty, lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl sty : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
ty_nil => 0u8.iter_bytes(lsb0, f),
|
||||
ty_bool => 1u8.iter_bytes(lsb0, f),
|
||||
|
||||
ty_int(ref t) =>
|
||||
to_bytes::iter_bytes_2(&2u8, t, lsb0, f),
|
||||
|
||||
ty_uint(ref t) =>
|
||||
to_bytes::iter_bytes_2(&3u8, t, lsb0, f),
|
||||
|
||||
ty_float(ref t) =>
|
||||
to_bytes::iter_bytes_2(&4u8, t, lsb0, f),
|
||||
|
||||
ty_estr(ref v) =>
|
||||
to_bytes::iter_bytes_2(&5u8, v, lsb0, f),
|
||||
|
||||
ty_enum(ref did, ref substs) =>
|
||||
to_bytes::iter_bytes_3(&6u8, did, substs, lsb0, f),
|
||||
|
||||
ty_box(ref mt) =>
|
||||
to_bytes::iter_bytes_2(&7u8, mt, lsb0, f),
|
||||
|
||||
ty_evec(ref mt, ref v) =>
|
||||
to_bytes::iter_bytes_3(&8u8, mt, v, lsb0, f),
|
||||
|
||||
ty_unboxed_vec(ref mt) =>
|
||||
to_bytes::iter_bytes_2(&9u8, mt, lsb0, f),
|
||||
|
||||
ty_tup(ref ts) =>
|
||||
to_bytes::iter_bytes_2(&10u8, ts, lsb0, f),
|
||||
|
||||
ty_rec(ref fs) =>
|
||||
to_bytes::iter_bytes_2(&11u8, fs, lsb0, f),
|
||||
|
||||
ty_fn(ref ft) =>
|
||||
to_bytes::iter_bytes_7(&12u8,
|
||||
&ft.meta.purity,
|
||||
&ft.meta.proto,
|
||||
&ft.meta.bounds,
|
||||
&ft.sig.inputs,
|
||||
&ft.sig.output,
|
||||
&ft.meta.ret_style,
|
||||
lsb0, f),
|
||||
|
||||
ty_self => 13u8.iter_bytes(lsb0, f),
|
||||
|
||||
ty_infer(ref v) =>
|
||||
to_bytes::iter_bytes_2(&14u8, v, lsb0, f),
|
||||
|
||||
ty_param(ref p) =>
|
||||
to_bytes::iter_bytes_2(&15u8, p, lsb0, f),
|
||||
|
||||
ty_type => 16u8.iter_bytes(lsb0, f),
|
||||
ty_bot => 17u8.iter_bytes(lsb0, f),
|
||||
|
||||
ty_ptr(ref mt) =>
|
||||
to_bytes::iter_bytes_2(&18u8, mt, lsb0, f),
|
||||
|
||||
ty_uniq(ref mt) =>
|
||||
to_bytes::iter_bytes_2(&19u8, mt, lsb0, f),
|
||||
|
||||
ty_trait(ref did, ref substs, ref v) =>
|
||||
to_bytes::iter_bytes_4(&20u8, did, substs, v, lsb0, f),
|
||||
|
||||
ty_opaque_closure_ptr(ref ck) =>
|
||||
to_bytes::iter_bytes_2(&21u8, ck, lsb0, f),
|
||||
|
||||
ty_opaque_box => 22u8.iter_bytes(lsb0, f),
|
||||
|
||||
ty_class(ref did, ref substs) =>
|
||||
to_bytes::iter_bytes_3(&23u8, did, substs, lsb0, f),
|
||||
|
||||
ty_rptr(ref r, ref mt) =>
|
||||
to_bytes::iter_bytes_3(&24u8, r, mt, lsb0, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pure fn hash_bound_region(br: &bound_region) -> uint {
|
||||
match *br { // no idea if this is any good
|
||||
ty::br_self => 0u,
|
||||
@ -2325,7 +2569,7 @@ pure fn hash_bound_region(br: &bound_region) -> uint {
|
||||
}
|
||||
|
||||
fn br_hashmap<V:copy>() -> hashmap<bound_region, V> {
|
||||
map::hashmap(hash_bound_region, sys::shape_eq)
|
||||
map::hashmap()
|
||||
}
|
||||
|
||||
pure fn hash_region(r: ®ion) -> uint {
|
||||
@ -3328,7 +3572,7 @@ fn enum_variant_with_id(cx: ctxt, enum_id: ast::def_id,
|
||||
let mut i = 0u;
|
||||
while i < vec::len::<variant_info>(*variants) {
|
||||
let variant = variants[i];
|
||||
if ast_util::def_eq(&variant.id, &variant_id) { return variant; }
|
||||
if variant.id == variant_id { return variant; }
|
||||
i += 1u;
|
||||
}
|
||||
cx.sess.bug(~"enum_variant_with_id(): no variant exists with that ID");
|
||||
|
@ -349,6 +349,21 @@ impl Constraint: cmp::Eq {
|
||||
pure fn ne(&&other: Constraint) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl Constraint : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
match self {
|
||||
ConstrainVarSubVar(ref v0, ref v1) =>
|
||||
to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f),
|
||||
|
||||
ConstrainRegSubVar(ref ra, ref va) =>
|
||||
to_bytes::iter_bytes_3(&1u8, ra, va, lsb0, f),
|
||||
|
||||
ConstrainVarSubReg(ref va, ref ra) =>
|
||||
to_bytes::iter_bytes_3(&2u8, va, ra, lsb0, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TwoRegions {
|
||||
a: region,
|
||||
b: region,
|
||||
@ -361,6 +376,12 @@ impl TwoRegions: cmp::Eq {
|
||||
pure fn ne(&&other: TwoRegions) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl TwoRegions : to_bytes::IterBytes {
|
||||
fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
to_bytes::iter_bytes_2(&self.a, &self.b, lsb0, f)
|
||||
}
|
||||
}
|
||||
|
||||
enum UndoLogEntry {
|
||||
Snapshot,
|
||||
AddVar(RegionVid),
|
||||
@ -394,7 +415,7 @@ fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings {
|
||||
tcx: tcx,
|
||||
var_spans: DVec(),
|
||||
values: empty_cell(),
|
||||
constraints: hashmap(hash_constraint, sys::shape_eq),
|
||||
constraints: hashmap(),
|
||||
lubs: CombineMap(),
|
||||
glbs: CombineMap(),
|
||||
undo_log: DVec()
|
||||
@ -405,16 +426,7 @@ fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings {
|
||||
// `b`! Not obvious that this is the most efficient way to go about
|
||||
// it.
|
||||
fn CombineMap() -> CombineMap {
|
||||
return hashmap(hash_two_regions, eq_two_regions);
|
||||
|
||||
pure fn hash_two_regions(rc: &TwoRegions) -> uint {
|
||||
hash_region(&rc.a) ^ hash_region(&rc.b)
|
||||
}
|
||||
|
||||
pure fn eq_two_regions(rc1: &TwoRegions, rc2: &TwoRegions) -> bool {
|
||||
(rc1.a == rc2.a && rc1.b == rc2.b) ||
|
||||
(rc1.a == rc2.b && rc1.b == rc2.a)
|
||||
}
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
pure fn hash_constraint(rc: &Constraint) -> uint {
|
||||
@ -795,11 +807,7 @@ struct SpannedRegion {
|
||||
type TwoRegionsMap = hashmap<TwoRegions, ()>;
|
||||
|
||||
fn TwoRegionsMap() -> TwoRegionsMap {
|
||||
return hashmap(hash_two_regions, sys::shape_eq);
|
||||
|
||||
pure fn hash_two_regions(rc: &TwoRegions) -> uint {
|
||||
hash_region(&rc.a) ^ (hash_region(&rc.b) << 2)
|
||||
}
|
||||
return hashmap();
|
||||
}
|
||||
|
||||
impl RegionVarBindings {
|
||||
|
@ -5,8 +5,7 @@ use std::map;
|
||||
|
||||
fn main() {
|
||||
let buggy_map :hashmap<uint, &uint> =
|
||||
hashmap::<uint, &uint>(|x| { uint::hash(*x) },
|
||||
|x, y| { uint::eq(*x, *y) });
|
||||
hashmap::<uint, &uint>();
|
||||
buggy_map.insert(42, ~1); //~ ERROR illegal borrow
|
||||
|
||||
// but it is ok if we use a temporary
|
||||
|
@ -1,7 +1,6 @@
|
||||
mod argparse {
|
||||
use std;
|
||||
|
||||
import std::map;
|
||||
import either::{Either, Left, Right};
|
||||
|
||||
struct Flag {
|
||||
|
@ -6,19 +6,13 @@ use std::map::hashmap;
|
||||
|
||||
fn main() {
|
||||
let count = @mut 0u;
|
||||
pure fn hash(s: &~[@~str]) -> uint {
|
||||
if vec::len(*s) > 0u && *s[0] == ~"boom" { fail; }
|
||||
return 10u;
|
||||
}
|
||||
pure fn eq(s: &~[@~str], t: &~[@~str]) -> bool {
|
||||
return *s == *t;
|
||||
}
|
||||
|
||||
let map = map::hashmap(hash, eq);
|
||||
let map = map::hashmap();
|
||||
let mut arr = ~[];
|
||||
for uint::range(0u, 10u) |i| {
|
||||
arr += ~[@~"key stuff"];
|
||||
map.insert(arr, arr + ~[@~"value stuff"]);
|
||||
if arr.len() == 5 {
|
||||
fail;
|
||||
}
|
||||
}
|
||||
map.insert(~[@~"boom"], ~[]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user