From ae225e2b6c8dfe7a24444bd5b11b8b21df7d5f9d Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 26 Dec 2011 18:15:17 -0800 Subject: [PATCH 1/5] libcore: Add binop functions to u32 and u64 --- src/libcore/u32.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ src/libcore/u64.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/libcore/u32.rs b/src/libcore/u32.rs index f33b8414a4d2e..569d59b981aef 100644 --- a/src/libcore/u32.rs +++ b/src/libcore/u32.rs @@ -16,6 +16,49 @@ Return the maximal value for a u32 */ const max_value: u32 = 0xffff_ffffu32; +/* Function: add */ +pure fn add(x: u32, y: u32) -> u32 { ret x + y; } + +/* Function: sub */ +pure fn sub(x: u32, y: u32) -> u32 { ret x - y; } + +/* Function: mul */ +pure fn mul(x: u32, y: u32) -> u32 { ret x * y; } + +/* Function: div */ +pure fn div(x: u32, y: u32) -> u32 { ret x / y; } + +/* Function: rem */ +pure fn rem(x: u32, y: u32) -> u32 { ret x % y; } + +/* Predicate: lt */ +pure fn lt(x: u32, y: u32) -> bool { ret x < y; } + +/* Predicate: le */ +pure fn le(x: u32, y: u32) -> bool { ret x <= y; } + +/* Predicate: eq */ +pure fn eq(x: u32, y: u32) -> bool { ret x == y; } + +/* Predicate: ne */ +pure fn ne(x: u32, y: u32) -> bool { ret x != y; } + +/* Predicate: ge */ +pure fn ge(x: u32, y: u32) -> bool { ret x >= y; } + +/* Predicate: gt */ +pure fn gt(x: u32, y: u32) -> bool { ret x > y; } + +/* +Function: range + +Iterate over the range [`lo`..`hi`) +*/ +fn range(lo: u32, hi: u32, it: block(u32)) { + let i = lo; + while i < hi { it(i); i += 1u32; } +} + // // Local Variables: // mode: rust diff --git a/src/libcore/u64.rs b/src/libcore/u64.rs index a7cd9af35bc88..bce99f02b87fe 100644 --- a/src/libcore/u64.rs +++ b/src/libcore/u64.rs @@ -16,6 +16,49 @@ Return the maximal value for a u64 */ const max_value: u64 = 18446744073709551615u64; +/* Function: add */ +pure fn add(x: u64, y: u64) -> u64 { ret x + y; } + +/* Function: sub */ +pure fn sub(x: u64, y: u64) -> u64 { ret x - y; } + +/* Function: mul */ +pure fn mul(x: u64, y: u64) -> u64 { ret x * y; } + +/* Function: div */ +pure fn div(x: u64, y: u64) -> u64 { ret x / y; } + +/* Function: rem */ +pure fn rem(x: u64, y: u64) -> u64 { ret x % y; } + +/* Predicate: lt */ +pure fn lt(x: u64, y: u64) -> bool { ret x < y; } + +/* Predicate: le */ +pure fn le(x: u64, y: u64) -> bool { ret x <= y; } + +/* Predicate: eq */ +pure fn eq(x: u64, y: u64) -> bool { ret x == y; } + +/* Predicate: ne */ +pure fn ne(x: u64, y: u64) -> bool { ret x != y; } + +/* Predicate: ge */ +pure fn ge(x: u64, y: u64) -> bool { ret x >= y; } + +/* Predicate: gt */ +pure fn gt(x: u64, y: u64) -> bool { ret x > y; } + +/* +Function: range + +Iterate over the range [`lo`..`hi`) +*/ +fn range(lo: u64, hi: u64, it: block(u64)) { + let i = lo; + while i < hi { it(i); i += 1u64; } +} + /* Function: to_str From 7806180557d971b1292249f3cad92444c05cd77e Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 26 Dec 2011 18:58:40 -0800 Subject: [PATCH 2/5] libcore: add a trivial uint hash function. --- src/libcore/uint.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcore/uint.rs b/src/libcore/uint.rs index aa38a6d40dc5b..ee28c07de3d79 100644 --- a/src/libcore/uint.rs +++ b/src/libcore/uint.rs @@ -103,6 +103,13 @@ pure fn ge(x: uint, y: uint) -> bool { ret x >= y; } /* Predicate: gt */ pure fn gt(x: uint, y: uint) -> bool { ret x > y; } +/* +Function: hash + +Produce a uint suitable for use in a hash table +*/ +fn hash(x: uint) -> uint { ret x; } + /* Function: range From eade7844a339557e57b2ba0503d8edf19ff60f43 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 26 Dec 2011 18:59:50 -0800 Subject: [PATCH 3/5] libstd: switch map to use libcore's hash functions. --- src/libstd/map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/map.rs b/src/libstd/map.rs index db47160216c44..53e59e210f8a8 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -384,7 +384,7 @@ Function: new_int_hash Construct a hashmap for int keys */ fn new_int_hash() -> hashmap { - fn hash_int(&&x: int) -> uint { ret x as uint; } + fn hash_int(&&x: int) -> uint { int::hash(x) } fn eq_int(&&a: int, &&b: int) -> bool { ret a == b; } ret mk_hashmap(hash_int, eq_int); } @@ -395,7 +395,7 @@ Function: new_uint_hash Construct a hashmap for uint keys */ fn new_uint_hash() -> hashmap { - fn hash_uint(&&x: uint) -> uint { ret x; } + fn hash_uint(&&x: uint) -> uint { uint::hash(x) } fn eq_uint(&&a: uint, &&b: uint) -> bool { ret a == b; } ret mk_hashmap(hash_uint, eq_uint); } From 3e68803891dc384e8c3e5a24bb17700187d86cf7 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 6 Jan 2012 07:36:56 -0800 Subject: [PATCH 4/5] libcore: add [u8] helper functions to vec. --- src/libcore/vec.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++- src/libstd/map.rs | 9 +++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 32bb2f46a4917..311d5e6e4bf35 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -709,7 +709,7 @@ Function: enum_chars Returns a vector containing a range of chars */ -fn enum_chars(start: u8, end: u8) : u8::le(start, end) -> [char] { +fn enum_chars(start: u8, end: u8) : ::u8::le(start, end) -> [char] { let i = start; let r = []; while i <= end { r += [i as char]; i += 1u as u8; } @@ -879,6 +879,99 @@ mod unsafe { } } +/* +Module: u8 +*/ +mod u8 { + export cmp; + export lt, le, eq, ne, ge, gt; + export hash; + + #[nolink] + #[abi = "cdecl"] + native mod libc { + fn memcmp(s1: *u8, s2: *u8, n: ctypes::size_t) -> ctypes::c_int; + } + + /* + Function cmp + + Bytewise string comparison + */ + pure fn cmp(&&a: [u8], &&b: [u8]) -> int unsafe { + let a_len = len(a); + let b_len = len(b); + let n = math::min(a_len, b_len) as ctypes::size_t; + let r = libc::memcmp(to_ptr(a), to_ptr(b), n) as int; + + if r != 0 { r } else { + if a_len == b_len { + 0 + } else if a_len < b_len { + -1 + } else { + 1 + } + } + } + + /* + Function: lt + + Bytewise less than or equal + */ + pure fn lt(&&a: [u8], &&b: [u8]) -> bool { cmp(a, b) < 0 } + + /* + Function: le + + Bytewise less than or equal + */ + pure fn le(&&a: [u8], &&b: [u8]) -> bool { cmp(a, b) <= 0 } + + /* + Function: eq + + Bytewise equality + */ + pure fn eq(&&a: [u8], &&b: [u8]) -> bool unsafe { cmp(a, b) == 0 } + + /* + Function: ne + + Bytewise inequality + */ + pure fn ne(&&a: [u8], &&b: [u8]) -> bool unsafe { cmp(a, b) != 0 } + + /* + Function: ge + + Bytewise greater than or equal + */ + pure fn ge(&&a: [u8], &&b: [u8]) -> bool { cmp(a, b) >= 0 } + + /* + Function: gt + + Bytewise greater than + */ + pure fn gt(&&a: [u8], &&b: [u8]) -> bool { cmp(a, b) > 0 } + + /* + Function: hash + + String hash function + */ + fn hash(&&s: [u8]) -> uint { + // djb hash. + // FIXME: replace with murmur. + + let u: uint = 5381u; + vec::iter(s, { |c| u *= 33u; u += c as uint; }); + ret u; + } +} + // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 53e59e210f8a8..727d32ef65a24 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -378,6 +378,15 @@ fn new_str_hash() -> hashmap { ret mk_hashmap(str::hash, str::eq); } +/* +Function: new_bytes_hash + +Construct a hashmap for byte string keys +*/ +fn new_bytes_hash() -> hashmap<[u8], V> { + ret mk_hashmap(vec::u8::hash, vec::u8::eq); +} + /* Function: new_int_hash From 6cfc196d424d50e39c3f697b213a62ff8df9979b Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 6 Jan 2012 08:12:18 -0800 Subject: [PATCH 5/5] libstd: rename c_vec::size to len. --- src/libstd/c_vec.rs | 31 +++++++++++++++---------------- src/test/stdtest/c_vec.rs | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 4374a7ffb9936..949c8d007a764 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -31,7 +31,7 @@ taken to ensure that a reference to the c_vec::t is still held if needed. export t; export create, create_with_dtor; export get, set; -export size; +export len; export ptr; /* @@ -43,7 +43,7 @@ export ptr; */ tag t { - t({ base: *mutable T, size: uint, rsrc: @dtor_res}); + t({ base: *mutable T, len: uint, rsrc: @dtor_res}); } resource dtor_res(dtor: option::t) { @@ -60,16 +60,16 @@ resource dtor_res(dtor: option::t) { /* Function: create -Create a c_vec::t from a native buffer with a given size. +Create a c_vec::t from a native buffer with a given length. Parameters: base - A native pointer to a buffer -size - The number of elements in the buffer +len - The number of elements in the buffer */ -unsafe fn create(base: *mutable T, size: uint) -> t { +unsafe fn create(base: *mutable T, len: uint) -> t { ret t({base: base, - size: size, + len: len, rsrc: @dtor_res(option::none) }); } @@ -77,20 +77,20 @@ unsafe fn create(base: *mutable T, size: uint) -> t { /* Function: create_with_dtor -Create a c_vec::t from a native buffer, with a given size, +Create a c_vec::t from a native buffer, with a given length, and a function to run upon destruction. Parameters: base - A native pointer to a buffer -size - The number of elements in the buffer +len - The number of elements in the buffer dtor - A function to run when the value is destructed, useful for freeing the buffer, etc. */ -unsafe fn create_with_dtor(base: *mutable T, size: uint, dtor: fn@()) +unsafe fn create_with_dtor(base: *mutable T, len: uint, dtor: fn@()) -> t { ret t({base: base, - size: size, + len: len, rsrc: @dtor_res(option::some(dtor)) }); } @@ -109,7 +109,7 @@ Failure: If `ofs` is greater or equal to the length of the vector */ fn get(t: t, ofs: uint) -> T { - assert ofs < (*t).size; + assert ofs < len(t); ret unsafe { *ptr::mut_offset((*t).base, ofs) }; } @@ -123,7 +123,7 @@ Failure: If `ofs` is greater or equal to the length of the vector */ fn set(t: t, ofs: uint, v: T) { - assert ofs < (*t).size; + assert ofs < len(t); unsafe { *ptr::mut_offset((*t).base, ofs) = v }; } @@ -131,14 +131,13 @@ fn set(t: t, ofs: uint, v: T) { Section: Elimination forms */ -// FIXME: Rename to len /* -Function: size +Function: len Returns the length of the vector */ -fn size(t: t) -> uint { - ret (*t).size; +fn len(t: t) -> uint { + ret (*t).len; } /* diff --git a/src/test/stdtest/c_vec.rs b/src/test/stdtest/c_vec.rs index 65a6fc9c0bee1..26a67e03f6349 100644 --- a/src/test/stdtest/c_vec.rs +++ b/src/test/stdtest/c_vec.rs @@ -28,7 +28,7 @@ fn test_basic() { set(cv, 4u, 9u8); assert get(cv, 3u) == 8u8; assert get(cv, 4u) == 9u8; - assert size(cv) == 16u; + assert len(cv) == 16u; } #[test]