summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorStefan Plantikow <stefan.plantikow@googlemail.com>2012-01-05 00:11:25 +0100
committerStefan Plantikow <stefan.plantikow@googlemail.com>2012-01-05 02:07:12 +0100
commit6284190ef9918e05cb9147a2a81100ddcb06fea8 (patch)
treee5e8075a4de03db9c4efee2b6d994343a674b3b5 /src/libcore
parent16405386f0a843167e234d8d54855a537b0f261d (diff)
parent3971b520bcdd556ff78120c77ffd13785e1c3695 (diff)
downloadrust-6284190ef9918e05cb9147a2a81100ddcb06fea8.tar.gz
rust-6284190ef9918e05cb9147a2a81100ddcb06fea8.zip
Merge branch 'master' into kmath
Conflicts:
	src/libcore/cmath.rs
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/char.rs32
-rw-r--r--src/libcore/cmath.rs38
-rw-r--r--src/libcore/either.rs18
-rw-r--r--src/libcore/f32.rs59
-rw-r--r--src/libcore/f64.rs58
-rw-r--r--src/libcore/option.rs6
-rw-r--r--src/libcore/result.rs4
-rw-r--r--src/libcore/str.rs47
-rw-r--r--src/libcore/vec.rs11
9 files changed, 214 insertions, 59 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 0bdda6f0afb..5475e695a79 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -41,7 +41,7 @@ export is_alphabetic,
        is_XID_start, is_XID_continue,
        is_lowercase, is_uppercase,
        is_whitespace, is_alphanumeric,
-       to_digit, maybe_digit, cmp;
+       to_digit, to_lower, to_upper, maybe_digit, cmp;
 
 import is_alphabetic = unicode::derived_property::Alphabetic;
 import is_XID_start = unicode::derived_property::XID_Start;
@@ -122,7 +122,7 @@ pure fn to_digit(c: char) -> u8 unsafe {
 }
 
 /*
- Function: to_digit
+ Function: maybe_digit
 
  Convert a char to the corresponding digit. Returns none when the
  character is not a valid hexadecimal digit.
@@ -137,6 +137,34 @@ pure fn maybe_digit(c: char) -> option::t<u8> {
 }
 
 /*
+ Function: to_lower
+
+ Convert a char to the corresponding lower case.
+
+ FIXME: works only on ASCII
+*/
+pure fn to_lower(c: char) -> char {
+    alt c {
+      'A' to 'Z' { ((c as u8) + 32u8) as char }
+      _ { c }
+    }
+}
+
+/*
+ Function: to_upper
+
+ Convert a char to the corresponding upper case.
+
+ FIXME: works only on ASCII
+*/
+pure fn to_upper(c: char) -> char {
+    alt c {
+      'a' to 'z' { ((c as u8) - 32u8) as char }
+      _ { c }
+    }
+}
+
+/*
  Function: cmp
 
  Compare two chars.
diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs
index dd922ddf1bc..4f3c5a8d68b 100644
--- a/src/libcore/cmath.rs
+++ b/src/libcore/cmath.rs
@@ -5,6 +5,9 @@ import ctypes::c_int;
 import ctypes::c_float;
 import ctypes::c_double;
 
+// function names are almost identical to C's libmath, a few have been
+// renamed, grep for "rename:"
+
 #[link_name = "m"]
 #[abi = "cdecl"]
 native mod c_double {
@@ -26,8 +29,10 @@ native mod c_double {
     pure fn expm1(n: c_double) -> c_double;
     pure fn exp2(n: c_double) -> c_double;
     #[link_name="fabs"] pure fn abs(n: c_double) -> c_double;
-    #[link_name="fdim"] pure fn sub_pos(a: c_double, b: c_double) -> c_double;
+    // rename: for clarity and consistency with add/sub/mul/div
+    #[link_name="fdim"] pure fn abs_sub(a: c_double, b: c_double) -> c_double;
     pure fn floor(n: c_double) -> c_double;
+    // rename: for clarity and consistency with add/sub/mul/div
     #[link_name="fma"] pure fn mul_add(a: c_double, b: c_double,
                                        c: c_double) -> c_double;
     #[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
@@ -38,17 +43,26 @@ native mod c_double {
     pure fn ldexp(x: c_double, n: c_int) -> c_double;
     #[link_name="lgamma_r"] pure fn lgamma(n: c_double,
                                            &sign: c_int) -> c_double;
+    // renamed: log is a reserved keyword; ln seems more natural, too
     #[link_name="log"] pure fn ln(n: c_double) -> c_double;
-    pure fn logb(n: c_double) -> c_double;
+    // renamed: "logb" /often/ is confused for log2 by beginners
+    #[link_name="logb"] pure fn log_radix(n: c_double) -> c_double;
+    // renamed: to be consitent with log as ln
     #[link_name="log1p"] pure fn ln1p(n: c_double) -> c_double;
     pure fn log10(n: c_double) -> c_double;
+    #[cfg(target_os="linux")]
+    #[cfg(target_os="macos")]
+    #[cfg(target_os="win32")]
     pure fn log2(n: c_double) -> c_double;
-    pure fn ilogb(n: c_double) -> c_int;
+    #[link_name="ilogb"] pure fn ilogradix(n: c_double) -> c_int;
     pure fn modf(n: c_double, &iptr: c_double) -> c_double;
     pure fn pow(n: c_double, e: c_double) -> c_double;
-    pure fn rint(n: c_double) -> c_double;
+// FIXME enable when rounding modes become available
+//    pure fn rint(n: c_double) -> c_double;
     pure fn round(n: c_double) -> c_double;
-    pure fn scalbn(n: c_double, i: c_int) -> c_double;
+    // rename: for consistency with logradix
+    #[link_name="scalbn"] pure fn ldexp_radix(n: c_double, i: c_int) ->
+        c_double;
     pure fn sin(n: c_double) -> c_double;
     pure fn sinh(n: c_double) -> c_double;
     pure fn sqrt(n: c_double) -> c_double;
@@ -90,7 +104,7 @@ native mod c_float {
     #[link_name="expm1f"]pure fn expm1(n: c_float) -> c_float;
     #[link_name="exp2f"] pure fn exp2(n: c_float) -> c_float;
     #[link_name="fabsf"] pure fn abs(n: c_float) -> c_float;
-    #[link_name="fdimf"] pure fn sub_pos(a: c_float, b: c_float) -> c_float;
+    #[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
     #[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
     #[link_name="frexpf"] pure fn frexp(n: c_float,
                                         &value: c_int) -> c_float;
@@ -105,17 +119,21 @@ native mod c_float {
     #[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
                                             &sign: c_int) -> c_float;
     #[link_name="logf"] pure fn ln(n: c_float) -> c_float;
-    #[link_name="logbf"] pure fn logb(n: c_float) -> c_float;
+    #[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
     #[link_name="log1pf"] pure fn ln1p(n: c_float) -> c_float;
+    #[cfg(target_os="linux")]
+    #[cfg(target_os="macos")]
+    #[cfg(target_os="win32")]
     #[link_name="log2f"] pure fn log2(n: c_float) -> c_float;
     #[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
-    #[link_name="ilogbf"] pure fn ilogb(n: c_float) -> c_int;
+    #[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
     #[link_name="modff"] pure fn modf(n: c_float,
                                       &iptr: c_float) -> c_float;
     #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
-    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
+// FIXME enable when rounding modes become available
+//    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
     #[link_name="roundf"] pure fn round(n: c_float) -> c_float;
-    #[link_name="scalbnf"] pure fn scalbn(n: c_float, i: c_int) -> c_float;
+    #[link_name="scalbnf"] pure fn ldexp_radix(n: c_float, i: c_int) -> c_float;
     #[link_name="sinf"] pure fn sin(n: c_float) -> c_float;
     #[link_name="sinhf"] pure fn sinh(n: c_float) -> c_float;
     #[link_name="sqrtf"] pure fn sqrt(n: c_float) -> c_float;
diff --git a/src/libcore/either.rs b/src/libcore/either.rs
index 60ad12d2e02..f3571ea5bcf 100644
--- a/src/libcore/either.rs
+++ b/src/libcore/either.rs
@@ -103,6 +103,24 @@ pure fn to_result<copy T, copy U>(eith: t<T, U>) -> result::t<U, T> {
     }
 }
 
+/*
+Function: is_left
+
+Checks whether the given value is a left
+*/
+pure fn is_left<T, U>(eith: t<T, U>) -> bool {
+    alt eith { left(_) { true } _ { false } }
+}
+
+/*
+Function: is_left
+
+Checks whether the given value is a right
+*/
+pure fn is_right<T, U>(eith: t<T, U>) -> bool {
+    alt eith { right(_) { true } _ { false } }
+}
+
 //
 // Local Variables:
 // mode: rust
diff --git a/src/libcore/f32.rs b/src/libcore/f32.rs
index 26ec20a2ed9..7c7d45694e5 100644
--- a/src/libcore/f32.rs
+++ b/src/libcore/f32.rs
@@ -16,6 +16,8 @@ type t = f32;
 
 // PORT check per architecture
 
+// FIXME obtain these in a different way
+
 const radix: uint = 2u;
 
 const mantissa_digits: uint = 24u;
@@ -42,7 +44,7 @@ const infinity: f32 = 1.0_f32/0.0_f32;
 const neg_infinity: f32 = -1.0_f32/0.0_f32;
 
 /* Predicate: isNaN */
-pure fn isNaN(f: f32) -> bool { f != f }
+pure fn is_NaN(f: f32) -> bool { f != f }
 
 /* Function: add */
 pure fn add(x: f32, y: f32) -> f32 { ret x + y; }
@@ -77,29 +79,32 @@ pure fn ge(x: f32, y: f32) -> bool { ret x >= y; }
 /* Predicate: gt */
 pure fn gt(x: f32, y: f32) -> bool { ret x > y; }
 
+// FIXME replace the predicates below with llvm intrinsics or calls
+// to the libmath macros in the rust runtime for performance
+
 /*
-Predicate: positive
+Predicate: is_positive
 
 Returns true if `x` is a positive number, including +0.0f320 and +Infinity.
  */
-pure fn positive(x: f32) -> bool
+pure fn is_positive(x: f32) -> bool
     { ret x > 0.0f32 || (1.0f32/x) == infinity; }
 
 /*
-Predicate: negative
+Predicate: is_negative
 
 Returns true if `x` is a negative number, including -0.0f320 and -Infinity.
  */
-pure fn negative(x: f32) -> bool
+pure fn is_negative(x: f32) -> bool
     { ret x < 0.0f32 || (1.0f32/x) == neg_infinity; }
 
 /*
-Predicate: nonpositive
+Predicate: is_nonpositive
 
 Returns true if `x` is a negative number, including -0.0f320 and -Infinity.
 (This is the same as `f32::negative`.)
 */
-pure fn nonpositive(x: f32) -> bool {
+pure fn is_nonpositive(x: f32) -> bool {
   ret x < 0.0f32 || (1.0f32/x) == neg_infinity;
 }
 
@@ -109,10 +114,39 @@ Predicate: nonnegative
 Returns true if `x` is a positive number, including +0.0f320 and +Infinity.
 (This is the same as `f32::positive`.)
 */
-pure fn nonnegative(x: f32) -> bool {
+pure fn is_nonnegative(x: f32) -> bool {
   ret x > 0.0f32 || (1.0f32/x) == infinity;
 }
 
+/*
+Predicate: is_zero
+
+Returns true if `x` is a zero number (positive or negative zero)
+*/
+pure fn is_zero(x: f32) -> bool {
+    ret x == 0.0f32 || x == -0.0f32;
+}
+
+/*
+Predicate: is_infinite
+
+Returns true if `x`is an infinite numer
+*/
+pure fn is_infinite(x: f32) -> bool {
+    ret x == infinity || x == neg_infinity;
+}
+
+/*
+Predicate: is_finite
+
+Returns true if `x`is a finite numer
+*/
+pure fn is_finite(x: f32) -> bool {
+    ret !(is_nan(x) || is_infinite(x));
+}
+
+// FIXME add is_normal, is_subnormal, and fpclassify
+
 /* Module: consts */
 mod consts {
 
@@ -208,6 +242,15 @@ mod consts {
     const ln_10: f32 = 2.30258509299404568401799145468436421_f32;
 }
 
+pure fn logarithm(n: f32, b: f32) -> f32 {
+    ret ln(n) / ln(b);
+}
+
+#[cfg(target_os="freebsd")]
+pure fn log2(n: f32) -> f32 {
+    ret ln(n) / consts::ln_2;
+}
+
 //
 // Local Variables:
 // mode: rust
diff --git a/src/libcore/f64.rs b/src/libcore/f64.rs
index c7ee7e1a5db..058d6620106 100644
--- a/src/libcore/f64.rs
+++ b/src/libcore/f64.rs
@@ -16,6 +16,8 @@ type t = f64;
 
 // PORT check per architecture
 
+// FIXME obtain these in a different way
+
 const radix: uint = 2u;
 
 const mantissa_digits: uint = 53u;
@@ -42,7 +44,7 @@ const infinity: f64 = 1.0_f64/0.0_f64;
 const neg_infinity: f64 = -1.0_f64/0.0_f64;
 
 /* Predicate: isNaN */
-pure fn isNaN(f: f64) -> bool { f != f }
+pure fn is_NaN(f: f64) -> bool { f != f }
 
 /* Function: add */
 pure fn add(x: f64, y: f64) -> f64 { ret x + y; }
@@ -78,41 +80,70 @@ pure fn ge(x: f64, y: f64) -> bool { ret x >= y; }
 pure fn gt(x: f64, y: f64) -> bool { ret x > y; }
 
 /*
-Predicate: positive
+Predicate: is_positive
 
 Returns true if `x` is a positive number, including +0.0f640 and +Infinity.
  */
-pure fn positive(x: f64) -> bool
+pure fn is_positive(x: f64) -> bool
     { ret x > 0.0f64 || (1.0f64/x) == infinity; }
 
 /*
-Predicate: negative
+Predicate: is_negative
 
 Returns true if `x` is a negative number, including -0.0f640 and -Infinity.
  */
-pure fn negative(x: f64) -> bool
+pure fn is_negative(x: f64) -> bool
     { ret x < 0.0f64 || (1.0f64/x) == neg_infinity; }
 
 /*
-Predicate: nonpositive
+Predicate: is_nonpositive
 
 Returns true if `x` is a negative number, including -0.0f640 and -Infinity.
 (This is the same as `f64::negative`.)
 */
-pure fn nonpositive(x: f64) -> bool {
+pure fn is_nonpositive(x: f64) -> bool {
   ret x < 0.0f64 || (1.0f64/x) == neg_infinity;
 }
 
 /*
-Predicate: nonnegative
+Predicate: is_nonnegative
 
 Returns true if `x` is a positive number, including +0.0f640 and +Infinity.
 (This is the same as `f64::positive`.)
 */
-pure fn nonnegative(x: f64) -> bool {
+pure fn is_nonnegative(x: f64) -> bool {
   ret x > 0.0f64 || (1.0f64/x) == infinity;
 }
 
+/*
+Predicate: is_zero
+
+Returns true if `x` is a zero number (positive or negative zero)
+*/
+pure fn is_zero(x: f64) -> bool {
+    ret x == 0.0f64 || x == -0.0f64;
+}
+
+/*
+Predicate: is_infinite
+
+Returns true if `x`is an infinite numer
+*/
+pure fn is_infinite(x: f64) -> bool {
+    ret x == infinity || x == neg_infinity;
+}
+
+/*
+Predicate: is_finite
+
+Returns true if `x`is a finite numer
+*/
+pure fn is_finite(x: f64) -> bool {
+    ret !(is_nan(x) || is_infinite(x));
+}
+
+// FIXME add is_normal, is_subnormal, and fpclassify
+
 /* Module: consts */
 mod consts {
 
@@ -208,6 +239,15 @@ mod consts {
     const ln_10: f64 = 2.30258509299404568401799145468436421_f64;
 }
 
+pure fn logarithm(n: f64, b: f64) -> f64 {
+    ret ln(n) / ln(b);
+}
+
+#[cfg(target_os="freebsd")]
+pure fn log2(n: f64) -> f64 {
+    ret ln(n) / consts::ln_2;
+}
+
 //
 // Local Variables:
 // mode: rust
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index aaaf82eb7cd..e0a137ca9e8 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -36,7 +36,7 @@ pure fn get<copy T>(opt: t<T>) -> T {
 
 /*
 */
-fn map<T, U>(opt: t<T>, f: block(T) -> U) -> t<U> {
+fn map<T, copy U>(opt: t<T>, f: block(T) -> U) -> t<U> {
     alt opt { some(x) { some(f(x)) } none. { none } }
 }
 
@@ -61,7 +61,7 @@ Function: from_maybe
 
 Returns the contained value or a default
 */
-pure fn from_maybe<T>(def: T, opt: t<T>) -> T {
+pure fn from_maybe<copy T>(def: T, opt: t<T>) -> T {
     alt opt { some(x) { x } none. { def } }
 }
 
@@ -70,7 +70,7 @@ Function: maybe
 
 Applies a function to the contained value or returns a default
 */
-fn maybe<T, U>(def: U, opt: t<T>, f: block(T) -> U) -> U {
+fn maybe<T, copy U>(def: U, opt: t<T>, f: block(T) -> U) -> U {
     alt opt { none. { def } some(t) { f(t) } }
 }
 
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 84fbc3b7f90..91038474ead 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -37,7 +37,7 @@ Failure:
 
 If the result is an error
 */
-fn get<T, U>(res: t<T, U>) -> T {
+fn get<copy T, U>(res: t<T, U>) -> T {
     alt res {
       ok(t) { t }
       err(_) {
@@ -57,7 +57,7 @@ Failure:
 
 If the result is not an error
 */
-fn get_err<T, U>(res: t<T, U>) -> U {
+fn get_err<T, copy U>(res: t<T, U>) -> U {
     alt res {
       err(u) { u }
       ok(_) {
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 6cb3ada6a88..cba9b11cb3d 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -7,12 +7,12 @@ String manipulation.
 export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len,
        byte_len_range, index,
        rindex, find, starts_with, ends_with, substr, slice, split, splitn,
-       split_str, concat, connect, to_upper, replace, char_slice, trim_left,
-       trim_right, trim, unshift_char, shift_char, pop_char, push_char,
-       is_utf8, from_chars, to_chars, char_len, char_len_range, char_at,
-       bytes, is_ascii, shift_byte, pop_byte,
+       split_str, concat, connect, to_lower, to_upper, replace, char_slice,
+       trim_left, trim_right, trim, unshift_char, shift_char, pop_char,
+       push_char, is_utf8, from_chars, to_chars, char_len, char_len_range,
+       char_at, bytes, is_ascii, shift_byte, pop_byte,
        unsafe_from_byte, unsafe_from_bytes, from_char, char_range_at,
-       str_from_cstr, sbuf, as_buf, push_byte, utf8_char_width, safe_slice,
+       from_cstr, sbuf, as_buf, push_byte, utf8_char_width, safe_slice,
        contains, iter_chars, loop_chars, loop_chars_sub,
        escape;
 
@@ -116,14 +116,7 @@ Function: is_whitespace
 Returns true if the string contains only whitespace
 */
 fn is_whitespace(s: str) -> bool {
-    let i = 0u;
-    let len = char_len(s);
-    while i < len {
-        // FIXME: This is not how char_at works
-        if !char::is_whitespace(char_at(s, i)) { ret false; }
-        i += 1u;
-    }
-    ret true;
+    ret loop_chars(s, char::is_whitespace);
 }
 
 /*
@@ -832,7 +825,18 @@ fn connect(v: [str], sep: str) -> str {
     ret s;
 }
 
-// FIXME: This only handles ASCII
+/*
+Function: to_lower
+
+Convert a string to lowercase
+*/
+fn to_lower(s: str) -> str {
+    let outstr = "";
+    iter_chars(s) { |c|
+        push_char(outstr, char::to_lower(c));
+    }
+    ret outstr;
+}
 /*
 Function: to_upper
 
@@ -840,15 +844,8 @@ Convert a string to uppercase
 */
 fn to_upper(s: str) -> str {
     let outstr = "";
-    let ascii_a = 'a' as u8;
-    let ascii_z = 'z' as u8;
-    let diff = 32u8;
-    for byte: u8 in s {
-        let next;
-        if ascii_a <= byte && byte <= ascii_z {
-            next = byte - diff;
-        } else { next = byte; }
-        push_byte(outstr, next);
+    iter_chars(s) { |c|
+        push_char(outstr, char::to_upper(c));
     }
     ret outstr;
 }
@@ -976,11 +973,11 @@ fn as_buf<T>(s: str, f: block(sbuf) -> T) -> T unsafe {
 }
 
 /*
-Function: str_from_cstr
+Function: from_cstr
 
 Create a Rust string from a null-terminated C string
 */
-unsafe fn str_from_cstr(cstr: sbuf) -> str {
+unsafe fn from_cstr(cstr: sbuf) -> str {
     let res = "";
     let start = cstr;
     let curr = start;
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 90e1ff37864..0c1db7119af 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -743,6 +743,17 @@ fn iter<T>(v: [const T], f: block(T)) {
 }
 
 /*
+Function: iter2
+
+Iterates over two vectors in parallel
+
+*/
+fn iter2<U, T>(v: [U], v2: [T], f: block(U, T)) {
+    let i = 0;
+    for elt in v { f(elt, v2[i]); i += 1; }
+}
+
+/*
 Function: iteri
 
 Iterates over a vector's elements and indexes