提交 4c30cb25 编写于 作者: J Jakub Bukaj

rollup merge of #18976: bjz/rfc369-numerics

......@@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::from_str::FromStr;
use std::fmt;
use std::str::FromStr;
use regex::Regex;
#[deriving(Clone, PartialEq)]
......
......@@ -22,7 +22,7 @@
use std::os;
use std::io;
use std::io::fs;
use std::from_str::FromStr;
use std::str::FromStr;
use getopts::{optopt, optflag, reqopt};
use common::Config;
use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Codegen};
......
......@@ -12,8 +12,6 @@
use common;
use util;
use std::from_str::FromStr;
pub struct TestProps {
// Lines that should be expected, in order, on standard out
pub error_patterns: Vec<String> ,
......@@ -353,8 +351,8 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
panic!("{}", error_string);
}
let major: int = FromStr::from_str(components[0]).expect(error_string);
let minor: int = FromStr::from_str(components[1]).expect(error_string);
let major: int = from_str(components[0]).expect(error_string);
let minor: int = from_str(components[1]).expect(error_string);
return major * 1000 + minor;
}
......@@ -364,6 +362,6 @@ pub fn lldb_version_to_int(version_string: &str) -> int {
"Encountered LLDB version string with unexpected format: {}",
version_string);
let error_string = error_string.as_slice();
let major: int = FromStr::from_str(version_string).expect(error_string);
let major: int = from_str(version_string).expect(error_string);
return major;
}
......@@ -3108,11 +3108,10 @@ then the expression completes.
Some examples of call expressions:
```
# use std::from_str::FromStr;
# fn add(x: int, y: int) -> int { 0 }
let x: int = add(1, 2);
let pi: Option<f32> = FromStr::from_str("3.14");
let pi: Option<f32> = from_str("3.14");
```
### Lambda expressions
......
......@@ -105,7 +105,7 @@ syn keyword rustTrait RawPtr
syn keyword rustTrait Buffer Writer Reader Seek
syn keyword rustTrait Str StrVector StrSlice
syn keyword rustTrait IntoMaybeOwned StrAllocating UnicodeStrSlice
syn keyword rustTrait ToString IntoStr
syn keyword rustTrait ToString IntoString
syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
......
......@@ -73,6 +73,7 @@
pub use core::str::{Utf16CodeUnits, eq_slice, is_utf8, is_utf16, Utf16Items};
pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
pub use core::str::{FromStr, from_str};
pub use core::str::{Str, StrPrelude};
pub use unicode::str::{UnicodeStrPrelude, Words, Graphemes, GraphemeIndices};
......
......@@ -25,7 +25,7 @@
use hash;
use slice::CloneSliceAllocPrelude;
use str;
use str::{CharRange, StrAllocating, MaybeOwned, Owned};
use str::{CharRange, FromStr, StrAllocating, MaybeOwned, Owned};
use str::Slice as MaybeOwnedSlice; // So many `Slice`s...
use vec::{DerefVec, Vec, as_vec};
......@@ -795,6 +795,33 @@ pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
DerefString { x: as_vec(x.as_bytes()) }
}
impl FromStr for String {
#[inline]
fn from_str(s: &str) -> Option<String> {
Some(String::from_str(s))
}
}
/// Trait for converting a type to a string, consuming it in the process.
pub trait IntoString {
/// Consume and convert to a string.
fn into_string(self) -> String;
}
/// A generic trait for converting a value to a string
pub trait ToString {
/// Converts the value of `self` to an owned string
fn to_string(&self) -> String;
}
impl<T: fmt::Show> ToString for T {
fn to_string(&self) -> String {
let mut buf = Vec::<u8>::new();
let _ = format_args!(|args| fmt::write(&mut buf, args), "{}", self);
String::from_utf8(buf).unwrap()
}
}
/// Unsafe operations
#[unstable = "waiting on raw module conventions"]
pub mod raw {
......@@ -860,7 +887,7 @@ mod tests {
use str;
use str::{Str, StrPrelude, Owned};
use super::{as_string, String};
use super::{as_string, String, ToString};
use vec::Vec;
use slice::CloneSliceAllocPrelude;
......@@ -1164,6 +1191,28 @@ fn test_slicing() {
assert_eq!("oob", s[1..4]);
}
#[test]
fn test_simple_types() {
assert_eq!(1i.to_string(), "1".to_string());
assert_eq!((-1i).to_string(), "-1".to_string());
assert_eq!(200u.to_string(), "200".to_string());
assert_eq!(2u8.to_string(), "2".to_string());
assert_eq!(true.to_string(), "true".to_string());
assert_eq!(false.to_string(), "false".to_string());
assert_eq!(().to_string(), "()".to_string());
assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
}
#[test]
fn test_vectors() {
let x: Vec<int> = vec![];
assert_eq!(x.to_string(), "[]".to_string());
assert_eq!((vec![1i]).to_string(), "[1]".to_string());
assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
"[[], [1], [1, 1]]".to_string());
}
#[bench]
fn bench_with_capacity(b: &mut Bencher) {
b.iter(|| {
......
......@@ -1652,6 +1652,13 @@ pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
}
}
impl<'a> fmt::FormatWriter for Vec<u8> {
fn write(&mut self, buf: &[u8]) -> fmt::Result {
self.push_all(buf);
Ok(())
}
}
#[cfg(test)]
mod tests {
extern crate test;
......
......@@ -16,8 +16,8 @@
use intrinsics;
use mem;
use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
use num::Float;
use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
use num::from_str_radix;
use option::Option;
pub const RADIX: uint = 2u;
......@@ -424,3 +424,10 @@ fn to_radians(self) -> f32 {
self * (value / 180.0f32)
}
}
#[inline]
#[allow(missing_docs)]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f32> {
from_str_radix(src, 16)
}
......@@ -16,8 +16,8 @@
use intrinsics;
use mem;
use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
use num::Float;
use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
use num::from_str_radix;
use option::Option;
// FIXME(#5527): These constants should be deprecated once associated
......@@ -430,3 +430,10 @@ fn to_radians(self) -> f64 {
self * (value / 180.0)
}
}
#[inline]
#[allow(missing_docs)]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f64> {
from_str_radix(src, 16)
}
......@@ -14,18 +14,21 @@
#![allow(missing_docs)]
use intrinsics;
use {int, i8, i16, i32, i64};
use {uint, u8, u16, u32, u64};
use {f32, f64};
use char::Char;
use clone::Clone;
use cmp::{PartialEq, Eq};
use cmp::{PartialOrd, Ord};
use intrinsics;
use iter::Iterator;
use kinds::Copy;
use mem::size_of;
use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::{Option, Some, None};
use str::{FromStr, from_str, StrPrelude};
/// Simultaneous division and remainder
#[inline]
......@@ -1372,6 +1375,290 @@ pub trait Float
fn to_radians(self) -> Self;
}
/// A generic trait for converting a string with a radix (base) to a value
#[experimental = "might need to return Result"]
pub trait FromStrRadix {
fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
}
/// A utility function that just calls FromStrRadix::from_str_radix.
#[experimental = "might need to return Result"]
pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
FromStrRadix::from_str_radix(str, radix)
}
macro_rules! from_str_radix_float_impl {
($T:ty) => {
#[experimental = "might need to return Result"]
impl FromStr for $T {
/// Convert a string in base 10 to a float.
/// Accepts an optional decimal exponent.
///
/// This function accepts strings such as
///
/// * '3.14'
/// * '+3.14', equivalent to '3.14'
/// * '-3.14'
/// * '2.5E10', or equivalently, '2.5e10'
/// * '2.5E-10'
/// * '.' (understood as 0)
/// * '5.'
/// * '.5', or, equivalently, '0.5'
/// * '+inf', 'inf', '-inf', 'NaN'
///
/// Leading and trailing whitespace represent an error.
///
/// # Arguments
///
/// * src - A string
///
/// # Return value
///
/// `None` if the string did not represent a valid number. Otherwise,
/// `Some(n)` where `n` is the floating-point number represented by `src`.
#[inline]
fn from_str(src: &str) -> Option<$T> {
from_str_radix(src, 10)
}
}
#[experimental = "might need to return Result"]
impl FromStrRadix for $T {
/// Convert a string in a given base to a float.
///
/// Due to possible conflicts, this function does **not** accept
/// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
/// does it recognize exponents of any kind.
///
/// Leading and trailing whitespace represent an error.
///
/// # Arguments
///
/// * src - A string
/// * radix - The base to use. Must lie in the range [2 .. 36]
///
/// # Return value
///
/// `None` if the string did not represent a valid number. Otherwise,
/// `Some(n)` where `n` is the floating-point number represented by `src`.
fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
assert!(radix >= 2 && radix <= 36,
"from_str_radix_float: must lie in the range `[2, 36]` - found {}",
radix);
// Special values
match src {
"inf" => return Some(Float::infinity()),
"-inf" => return Some(Float::neg_infinity()),
"NaN" => return Some(Float::nan()),
_ => {},
}
let (is_positive, src) = match src.slice_shift_char() {
(None, _) => return None,
(Some('-'), "") => return None,
(Some('-'), src) => (false, src),
(Some(_), _) => (true, src),
};
// The significand to accumulate
let mut sig = if is_positive { 0.0 } else { -0.0 };
// Necessary to detect overflow
let mut prev_sig = sig;
let mut cs = src.chars().enumerate();
// Exponent prefix and exponent index offset
let mut exp_info = None::<(char, uint)>;
// Parse the integer part of the significand
for (i, c) in cs {
match c.to_digit(radix) {
Some(digit) => {
// shift significand one digit left
sig = sig * (radix as $T);
// add/subtract current digit depending on sign
if is_positive {
sig = sig + ((digit as int) as $T);
} else {
sig = sig - ((digit as int) as $T);
}
// Detect overflow by comparing to last value, except
// if we've not seen any non-zero digits.
if prev_sig != 0.0 {
if is_positive && sig <= prev_sig
{ return Some(Float::infinity()); }
if !is_positive && sig >= prev_sig
{ return Some(Float::neg_infinity()); }
// Detect overflow by reversing the shift-and-add process
if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
{ return Some(Float::infinity()); }
if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
{ return Some(Float::neg_infinity()); }
}
prev_sig = sig;
},
None => match c {
'e' | 'E' | 'p' | 'P' => {
exp_info = Some((c, i + 1));
break; // start of exponent
},
'.' => {
break; // start of fractional part
},
_ => {
return None;
},
},
}
}
// If we are not yet at the exponent parse the fractional
// part of the significand
if exp_info.is_none() {
let mut power = 1.0;
for (i, c) in cs {
match c.to_digit(radix) {
Some(digit) => {
// Decrease power one order of magnitude
power = power / (radix as $T);
// add/subtract current digit depending on sign
sig = if is_positive {
sig + (digit as $T) * power
} else {
sig - (digit as $T) * power
};
// Detect overflow by comparing to last value
if is_positive && sig < prev_sig
{ return Some(Float::infinity()); }
if !is_positive && sig > prev_sig
{ return Some(Float::neg_infinity()); }
prev_sig = sig;
},
None => match c {
'e' | 'E' | 'p' | 'P' => {
exp_info = Some((c, i + 1));
break; // start of exponent
},
_ => {
return None; // invalid number
},
},
}
}
}
// Parse and calculate the exponent
let exp = match exp_info {
Some((c, offset)) => {
let base = match c {
'E' | 'e' if radix == 10 => 10u as $T,
'P' | 'p' if radix == 16 => 2u as $T,
_ => return None,
};
// Parse the exponent as decimal integer
let src = src[offset..];
let (is_positive, exp) = match src.slice_shift_char() {
(Some('-'), src) => (false, from_str::<uint>(src)),
(Some('+'), src) => (true, from_str::<uint>(src)),
(Some(_), _) => (true, from_str::<uint>(src)),
(None, _) => return None,
};
match (is_positive, exp) {
(true, Some(exp)) => base.powi(exp as i32),
(false, Some(exp)) => 1.0 / base.powi(exp as i32),
(_, None) => return None,
}
},
None => 1.0, // no exponent
};
Some(sig * exp)
}
}
}
}
from_str_radix_float_impl!(f32)
from_str_radix_float_impl!(f64)
macro_rules! from_str_radix_int_impl {
($T:ty) => {
#[experimental = "might need to return Result"]
impl FromStr for $T {
#[inline]
fn from_str(src: &str) -> Option<$T> {
from_str_radix(src, 10)
}
}
#[experimental = "might need to return Result"]
impl FromStrRadix for $T {
fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
assert!(radix >= 2 && radix <= 36,
"from_str_radix_int: must lie in the range `[2, 36]` - found {}",
radix);
let is_signed_ty = (0 as $T) > Int::min_value();
match src.slice_shift_char() {
(Some('-'), src) if is_signed_ty => {
// The number is negative
let mut result = 0;
for c in src.chars() {
let x = match c.to_digit(radix) {
Some(x) => x,
None => return None,
};
result = match result.checked_mul(radix as $T) {
Some(result) => result,
None => return None,
};
result = match result.checked_sub(x as $T) {
Some(result) => result,
None => return None,
};
}
Some(result)
},
(Some(_), _) => {
// The number is signed
let mut result = 0;
for c in src.chars() {
let x = match c.to_digit(radix) {
Some(x) => x,
None => return None,
};
result = match result.checked_mul(radix as $T) {
Some(result) => result,
None => return None,
};
result = match result.checked_add(x as $T) {
Some(result) => result,
None => return None,
};
}
Some(result)
},
(None, _) => None,
}
}
}
}
}
from_str_radix_int_impl!(int)
from_str_radix_int_impl!(i8)
from_str_radix_int_impl!(i16)
from_str_radix_int_impl!(i32)
from_str_radix_int_impl!(i64)
from_str_radix_int_impl!(uint)
from_str_radix_int_impl!(u8)
from_str_radix_int_impl!(u16)
from_str_radix_int_impl!(u32)
from_str_radix_int_impl!(u64)
// DEPRECATED
macro_rules! trait_impl {
......
......@@ -41,6 +41,7 @@
// Reexported functions
pub use iter::{range, repeat};
pub use mem::drop;
pub use str::from_str;
// Reexported types and traits
......
......@@ -31,6 +31,42 @@
use slice::{mod, SlicePrelude};
use uint;
/// A trait to abstract the idea of creating a new instance of a type from a
/// string.
#[experimental = "might need to return Result"]
pub trait FromStr {
/// Parses a string `s` to return an optional value of this type. If the
/// string is ill-formatted, the None is returned.
fn from_str(s: &str) -> Option<Self>;
}
/// A utility function that just calls FromStr::from_str
pub fn from_str<A: FromStr>(s: &str) -> Option<A> {
FromStr::from_str(s)
}
impl FromStr for bool {
/// Parse a `bool` from a string.
///
/// Yields an `Option<bool>`, because `s` may or may not actually be parseable.
///
/// # Examples
///
/// ```rust
/// assert_eq!(from_str::<bool>("true"), Some(true));
/// assert_eq!(from_str::<bool>("false"), Some(false));
/// assert_eq!(from_str::<bool>("not even a boolean"), None);
/// ```
#[inline]
fn from_str(s: &str) -> Option<bool> {
match s {
"true" => Some(true),
"false" => Some(false),
_ => None,
}
}
}
/*
Section: Creating a string
*/
......
......@@ -15,7 +15,8 @@
mod tests {
use core::$T_i::*;
use core::int;
use core::num::{Int, SignedInt};
use core::num::{FromStrRadix, Int, SignedInt};
use core::str::from_str;
use num;
#[test]
......@@ -156,6 +157,49 @@ fn test_signed_checked_div() {
assert!(5i.checked_div(0) == None);
assert!(int::MIN.checked_div(-1) == None);
}
#[test]
fn test_from_str() {
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));
assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
assert_eq!(from_str::<$T>(""), None);
assert_eq!(from_str::<$T>(" "), None);
assert_eq!(from_str::<$T>("x"), None);
}
#[test]
fn test_from_str_radix() {
assert_eq!(FromStrRadix::from_str_radix("123", 10), Some(123 as $T));
assert_eq!(FromStrRadix::from_str_radix("1001", 2), Some(9 as $T));
assert_eq!(FromStrRadix::from_str_radix("123", 8), Some(83 as $T));
assert_eq!(FromStrRadix::from_str_radix("123", 16), Some(291 as i32));
assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Some(65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("FFFF", 16), Some(65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("z", 36), Some(35 as $T));
assert_eq!(FromStrRadix::from_str_radix("Z", 36), Some(35 as $T));
assert_eq!(FromStrRadix::from_str_radix("-123", 10), Some(-123 as $T));
assert_eq!(FromStrRadix::from_str_radix("-1001", 2), Some(-9 as $T));
assert_eq!(FromStrRadix::from_str_radix("-123", 8), Some(-83 as $T));
assert_eq!(FromStrRadix::from_str_radix("-123", 16), Some(-291 as i32));
assert_eq!(FromStrRadix::from_str_radix("-ffff", 16), Some(-65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("-FFFF", 16), Some(-65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("-z", 36), Some(-35 as $T));
assert_eq!(FromStrRadix::from_str_radix("-Z", 36), Some(-35 as $T));
assert_eq!(FromStrRadix::from_str_radix("Z", 35), None::<$T>);
assert_eq!(FromStrRadix::from_str_radix("-9", 2), None::<$T>);
}
}
))
......@@ -45,3 +45,73 @@ pub fn test_num<T>(ten: T, two: T) where
assert_eq!(ten.div(&two), ten / two);
assert_eq!(ten.rem(&two), ten % two);
}
#[cfg(test)]
mod test {
use core::option::{Option, Some, None};
use core::num::Float;
use core::num::from_str_radix;
#[test]
fn from_str_issue7588() {
let u : Option<u8> = from_str_radix("1000", 10);
assert_eq!(u, None);
let s : Option<i16> = from_str_radix("80000", 10);
assert_eq!(s, None);
let f : Option<f32> = from_str_radix("10000000000000000000000000000000000000000", 10);
assert_eq!(f, Some(Float::infinity()))
let fe : Option<f32> = from_str_radix("1e40", 10);
assert_eq!(fe, Some(Float::infinity()))
}
#[test]
fn test_from_str_radix_float() {
let x1 : Option<f64> = from_str_radix("-123.456", 10);
assert_eq!(x1, Some(-123.456));
let x2 : Option<f32> = from_str_radix("123.456", 10);
assert_eq!(x2, Some(123.456));
let x3 : Option<f32> = from_str_radix("-0.0", 10);
assert_eq!(x3, Some(-0.0));
let x4 : Option<f32> = from_str_radix("0.0", 10);
assert_eq!(x4, Some(0.0));
let x4 : Option<f32> = from_str_radix("1.0", 10);
assert_eq!(x4, Some(1.0));
let x5 : Option<f32> = from_str_radix("-1.0", 10);
assert_eq!(x5, Some(-1.0));
}
#[test]
fn test_int_from_str_overflow() {
let mut i8_val: i8 = 127_i8;
assert_eq!(from_str::<i8>("127"), Some(i8_val));
assert_eq!(from_str::<i8>("128"), None);
i8_val += 1 as i8;
assert_eq!(from_str::<i8>("-128"), Some(i8_val));
assert_eq!(from_str::<i8>("-129"), None);
let mut i16_val: i16 = 32_767_i16;
assert_eq!(from_str::<i16>("32767"), Some(i16_val));
assert_eq!(from_str::<i16>("32768"), None);
i16_val += 1 as i16;
assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
assert_eq!(from_str::<i16>("-32769"), None);
let mut i32_val: i32 = 2_147_483_647_i32;
assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
assert_eq!(from_str::<i32>("2147483648"), None);
i32_val += 1 as i32;
assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
assert_eq!(from_str::<i32>("-2147483649"), None);
let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
assert_eq!(from_str::<i64>("9223372036854775808"), None);
i64_val += 1 as i64;
assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
assert_eq!(from_str::<i64>("-9223372036854775809"), None);
}
}
......@@ -8,6 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[test]
fn test_bool_from_str() {
assert_eq!(from_str::<bool>("true"), Some(true));
assert_eq!(from_str::<bool>("false"), Some(false));
assert_eq!(from_str::<bool>("not even a boolean"), None);
}
fn check_contains_all_substrings(s: &str) {
assert!(s.contains(""));
for i in range(0, s.len()) {
......
......@@ -10,7 +10,6 @@
use std::collections::HashMap;
use std::fmt;
use std::from_str::from_str;
use std::str::{MaybeOwned, Owned, Slice};
use compile::Program;
......
......@@ -334,8 +334,7 @@ fn parse_opt_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
}
fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
use std::from_str::FromStr;
match v.and_then(FromStr::from_str) {
match v.and_then(from_str) {
Some(i) => { *slot = i; true },
None => false
}
......
......@@ -31,8 +31,8 @@
use graphviz as dot;
use std::io::{mod, MemReader};
use std::from_str::FromStr;
use std::option;
use std::str::FromStr;
use arena::TypedArena;
#[deriving(PartialEq, Show)]
......
......@@ -200,7 +200,7 @@ fn main() {
use std::io::MemWriter;
use std::mem::{swap, transmute};
use std::num::{Float, FPNaN, FPInfinite, Int};
use std::str::ScalarValue;
use std::str::{FromStr, ScalarValue};
use std::string;
use std::vec::Vec;
use std::ops;
......@@ -1988,7 +1988,7 @@ fn $name(&mut self) -> DecodeResult<$ty> {
String(s) => {
// re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
// is going to have a string here, as per JSON spec.
match std::from_str::from_str(s.as_slice()) {
match std::str::from_str(s.as_slice()) {
Some(f) => Ok(f),
None => Err(ExpectedError("Number".to_string(), s)),
}
......@@ -2027,7 +2027,7 @@ fn read_f64(&mut self) -> DecodeResult<f64> {
String(s) => {
// re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
// is going to have a string here, as per JSON spec.
match std::from_str::from_str(s.as_slice()) {
match std::str::from_str(s.as_slice()) {
Some(f) => Ok(f),
None => Err(ExpectedError("Number".to_string(), s)),
}
......@@ -2399,7 +2399,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl std::from_str::FromStr for Json {
impl FromStr for Json {
fn from_str(s: &str) -> Option<Json> {
from_str(s).ok()
}
......@@ -2484,7 +2484,7 @@ fn mk_object(items: &[(string::String, Json)]) -> Json {
#[test]
fn test_from_str_trait() {
let s = "null";
assert!(::std::from_str::from_str::<Json>(s).unwrap() == from_str(s).unwrap());
assert!(::std::str::from_str::<Json>(s).unwrap() == from_str(s).unwrap());
}
#[test]
......
......@@ -21,8 +21,7 @@
use option::{Option, Some, None};
use slice::{SlicePrelude, AsSlice};
use str::{Str, StrPrelude};
use string::{mod, String};
use to_string::IntoStr;
use string::{mod, String, IntoString};
use vec::Vec;
/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
......@@ -326,7 +325,7 @@ fn eq_ignore_case(&self, other: &[Ascii]) -> bool {
}
}
impl IntoStr for Vec<Ascii> {
impl IntoString for Vec<Ascii> {
#[inline]
fn into_string(self) -> String {
unsafe {
......
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The `FromStr` trait for types that can be created from strings
#![experimental]
use option::{Option, Some, None};
use string::String;
/// A trait to abstract the idea of creating a new instance of a type from a
/// string.
#[experimental = "might need to return Result"]
pub trait FromStr {
/// Parses a string `s` to return an optional value of this type. If the
/// string is ill-formatted, the None is returned.
fn from_str(s: &str) -> Option<Self>;
}
/// A utility function that just calls FromStr::from_str
pub fn from_str<A: FromStr>(s: &str) -> Option<A> {
FromStr::from_str(s)
}
impl FromStr for bool {
/// Parse a `bool` from a string.
///
/// Yields an `Option<bool>`, because `s` may or may not actually be parseable.
///
/// # Examples
///
/// ```rust
/// assert_eq!(from_str::<bool>("true"), Some(true));
/// assert_eq!(from_str::<bool>("false"), Some(false));
/// assert_eq!(from_str::<bool>("not even a boolean"), None);
/// ```
#[inline]
fn from_str(s: &str) -> Option<bool> {
match s {
"true" => Some(true),
"false" => Some(false),
_ => None,
}
}
}
impl FromStr for String {
#[inline]
fn from_str(s: &str) -> Option<String> {
Some(String::from_str(s))
}
}
#[cfg(test)]
mod test {
use prelude::*;
#[test]
fn test_bool_from_str() {
assert_eq!(from_str::<bool>("true"), Some(true));
assert_eq!(from_str::<bool>("false"), Some(false));
assert_eq!(from_str::<bool>("not even a boolean"), None);
}
}
......@@ -16,13 +16,12 @@
#![allow(missing_docs)]
use fmt;
use from_str::FromStr;
use io::{mod, IoResult, IoError};
use io::net;
use iter::Iterator;
use option::{Option, None, Some};
use result::{Ok, Err};
use str::StrPrelude;
use str::{FromStr, StrPrelude};
use slice::{CloneSlicePrelude, SlicePrelude};
use vec::Vec;
......@@ -540,7 +539,7 @@ fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
mod test {
use prelude::*;
use super::*;
use from_str::FromStr;
use str::FromStr;
#[test]
fn test_from_str_ipv4() {
......
......@@ -54,7 +54,7 @@
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](from_str/index.html) trait.
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
......@@ -219,9 +219,7 @@
/* Common traits */
pub mod error;
pub mod from_str;
pub mod num;
pub mod to_string;
/* Common data structures */
......
......@@ -17,12 +17,10 @@
use prelude::*;
use from_str::FromStr;
use intrinsics;
use libc::c_int;
use num::{Float, FloatMath};
use num::strconv;
use num;
pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
......@@ -339,68 +337,6 @@ pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String {
r
}
#[inline]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f32> {
strconv::from_str_radix_float(src, 16)
}
impl FromStr for f32 {
/// Convert a string in base 10 to a float.
/// Accepts an optional decimal exponent.
///
/// This function accepts strings such as
///
/// * '3.14'
/// * '+3.14', equivalent to '3.14'
/// * '-3.14'
/// * '2.5E10', or equivalently, '2.5e10'
/// * '2.5E-10'
/// * '.' (understood as 0)
/// * '5.'
/// * '.5', or, equivalently, '0.5'
/// * '+inf', 'inf', '-inf', 'NaN'
///
/// Leading and trailing whitespace represent an error.
///
/// # Arguments
///
/// * src - A string
///
/// # Return value
///
/// `None` if the string did not represent a valid number. Otherwise,
/// `Some(n)` where `n` is the floating-point number represented by `src`.
#[inline]
fn from_str(src: &str) -> Option<f32> {
strconv::from_str_radix_float(src, 10u)
}
}
impl num::FromStrRadix for f32 {
/// Convert a string in a given base to a float.
///
/// Due to possible conflicts, this function does **not** accept
/// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
/// does it recognize exponents of any kind.
///
/// Leading and trailing whitespace represent an error.
///
/// # Arguments
///
/// * src - A string
/// * radix - The base to use. Must lie in the range [2 .. 36]
///
/// # Return value
///
/// `None` if the string did not represent a valid number. Otherwise,
/// `Some(n)` where `n` is the floating-point number represented by `src`.
#[inline]
fn from_str_radix(src: &str, radix: uint) -> Option<f32> {
strconv::from_str_radix_float(src, radix)
}
}
#[cfg(test)]
mod tests {
use f32::*;
......
......@@ -16,12 +16,10 @@
use prelude::*;
use from_str::FromStr;
use intrinsics;
use libc::c_int;
use num::{Float, FloatMath};
use num::strconv;
use num;
pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
......@@ -347,63 +345,6 @@ pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String {
r
}
#[inline]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f64> {
strconv::from_str_radix_float(src, 16)
}
impl FromStr for f64 {
/// Convert a string in base 10 to a float.
/// Accepts an optional decimal exponent.
///
/// This function accepts strings such as:
///
/// * '3.14'
/// * '-3.14'
/// * '2.5E10', or equivalently, '2.5e10'
/// * '2.5E-10'
/// * '.' (understood as 0)
/// * '5.'
/// * '.5', or, equivalently, '0.5'
/// * inf', '-inf', 'NaN'
///
/// Leading and trailing whitespace represent an error.
///
/// # Arguments
///
/// * src - A string
///
/// # Return value
///
/// `none` if the string did not represent a valid number. Otherwise,
/// `Some(n)` where `n` is the floating-point number represented by `src`.
#[inline]
fn from_str(src: &str) -> Option<f64> {
strconv::from_str_radix_float(src, 10u)
}
}
impl num::FromStrRadix for f64 {
/// Convert a string in a given base to a float.
///
/// Leading and trailing whitespace represent an error.
///
/// # Arguments
///
/// * src - A string
/// * radix - The base to use. Must lie in the range [2 .. 36]
///
/// # Return value
///
/// `None` if the string did not represent a valid number. Otherwise,
/// `Some(n)` where `n` is the floating-point number represented by `src`.
#[inline]
fn from_str_radix(src: &str, radix: uint) -> Option<f64> {
strconv::from_str_radix_float(src, radix)
}
}
#[cfg(test)]
mod tests {
use f64::*;
......
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "i16")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::i16::{BITS, BYTES, MIN, MAX};
int_module!(i16)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "i32")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::i32::{BITS, BYTES, MIN, MAX};
int_module!(i32)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "i64")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::i64::{BITS, BYTES, MIN, MAX};
int_module!(i64)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "i8")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::i8::{BITS, BYTES, MIN, MAX};
int_module!(i8)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "int")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::int::{BITS, BYTES, MIN, MAX};
int_module!(int)
......@@ -14,131 +14,4 @@
macro_rules! int_module (($T:ty) => (
#[experimental = "might need to return Result"]
impl FromStr for $T {
#[inline]
fn from_str(s: &str) -> Option<$T> {
strconv::from_str_radix_int(s, 10)
}
}
#[experimental = "might need to return Result"]
impl FromStrRadix for $T {
#[inline]
fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
strconv::from_str_radix_int(s, radix)
}
}
#[cfg(test)]
mod tests {
use prelude::*;
use num::FromStrRadix;
#[test]
fn test_from_str() {
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));
assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
assert_eq!(from_str::<$T>(""), None);
assert_eq!(from_str::<$T>(" "), None);
assert_eq!(from_str::<$T>("x"), None);
}
#[test]
fn test_from_str_radix() {
assert_eq!(FromStrRadix::from_str_radix("123", 10), Some(123 as $T));
assert_eq!(FromStrRadix::from_str_radix("1001", 2), Some(9 as $T));
assert_eq!(FromStrRadix::from_str_radix("123", 8), Some(83 as $T));
assert_eq!(FromStrRadix::from_str_radix("123", 16), Some(291 as i32));
assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Some(65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("FFFF", 16), Some(65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("z", 36), Some(35 as $T));
assert_eq!(FromStrRadix::from_str_radix("Z", 36), Some(35 as $T));
assert_eq!(FromStrRadix::from_str_radix("-123", 10), Some(-123 as $T));
assert_eq!(FromStrRadix::from_str_radix("-1001", 2), Some(-9 as $T));
assert_eq!(FromStrRadix::from_str_radix("-123", 8), Some(-83 as $T));
assert_eq!(FromStrRadix::from_str_radix("-123", 16), Some(-291 as i32));
assert_eq!(FromStrRadix::from_str_radix("-ffff", 16), Some(-65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("-FFFF", 16), Some(-65535 as i32));
assert_eq!(FromStrRadix::from_str_radix("-z", 36), Some(-35 as $T));
assert_eq!(FromStrRadix::from_str_radix("-Z", 36), Some(-35 as $T));
assert_eq!(FromStrRadix::from_str_radix("Z", 35), None::<$T>);
assert_eq!(FromStrRadix::from_str_radix("-9", 2), None::<$T>);
}
#[test]
fn test_int_to_str_overflow() {
let mut i8_val: i8 = 127_i8;
assert_eq!(i8_val.to_string(), "127".to_string());
i8_val += 1 as i8;
assert_eq!(i8_val.to_string(), "-128".to_string());
let mut i16_val: i16 = 32_767_i16;
assert_eq!(i16_val.to_string(), "32767".to_string());
i16_val += 1 as i16;
assert_eq!(i16_val.to_string(), "-32768".to_string());
let mut i32_val: i32 = 2_147_483_647_i32;
assert_eq!(i32_val.to_string(), "2147483647".to_string());
i32_val += 1 as i32;
assert_eq!(i32_val.to_string(), "-2147483648".to_string());
let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
i64_val += 1 as i64;
assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
}
#[test]
fn test_int_from_str_overflow() {
let mut i8_val: i8 = 127_i8;
assert_eq!(from_str::<i8>("127"), Some(i8_val));
assert_eq!(from_str::<i8>("128"), None);
i8_val += 1 as i8;
assert_eq!(from_str::<i8>("-128"), Some(i8_val));
assert_eq!(from_str::<i8>("-129"), None);
let mut i16_val: i16 = 32_767_i16;
assert_eq!(from_str::<i16>("32767"), Some(i16_val));
assert_eq!(from_str::<i16>("32768"), None);
i16_val += 1 as i16;
assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
assert_eq!(from_str::<i16>("-32769"), None);
let mut i32_val: i32 = 2_147_483_647_i32;
assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
assert_eq!(from_str::<i32>("2147483648"), None);
i32_val += 1 as i32;
assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
assert_eq!(from_str::<i32>("-2147483649"), None);
let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
assert_eq!(from_str::<i64>("9223372036854775808"), None);
i64_val += 1 as i64;
assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
assert_eq!(from_str::<i64>("-9223372036854775809"), None);
}
}
))
......@@ -16,8 +16,6 @@
#![experimental]
#![allow(missing_docs)]
use option::Option;
#[cfg(test)] use cmp::PartialEq;
#[cfg(test)] use fmt::Show;
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
......@@ -31,6 +29,7 @@
pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
pub use core::num::{from_f32, from_f64};
pub use core::num::{FromStrRadix, from_str_radix};
pub use core::num::{FPCategory, FPNaN, FPInfinite, FPZero, FPSubnormal};
pub use core::num::{FPNormal, Float};
......@@ -115,18 +114,6 @@ pub trait FloatMath: Float {
fn atanh(self) -> Self;
}
/// A generic trait for converting a string with a radix (base) to a value
#[experimental = "might need to return Result"]
pub trait FromStrRadix {
fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
}
/// A utility function that just calls FromStrRadix::from_str_radix.
#[experimental = "might need to return Result"]
pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
FromStrRadix::from_str_radix(str, radix)
}
// DEPRECATED
#[deprecated = "Use `FloatMath::abs_sub`"]
......@@ -764,8 +751,9 @@ fn test_from_primitive() {
#[test]
fn test_pow() {
fn naive_pow<T: One + Mul<T, T>>(base: T, exp: uint) -> T {
range(0, exp).fold(one::<T>(), |acc, _| acc * base)
fn naive_pow<T: Int>(base: T, exp: uint) -> T {
let one: T = Int::one();
range(0, exp).fold(one, |acc, _| acc * base)
}
macro_rules! assert_pow(
(($num:expr, $exp:expr) => $expected:expr) => {{
......
......@@ -13,12 +13,8 @@
#![allow(missing_docs)]
use char;
use char::Char;
use from_str::from_str;
use iter::Iterator;
use num;
use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
use option::{None, Option, Some};
use slice::{SlicePrelude, CloneSliceAllocPrelude};
use str::StrPrelude;
use string::String;
......@@ -425,242 +421,35 @@ pub fn float_to_str_common<T: Float>(
static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
pub fn from_str_radix_float<T: Float>(src: &str, radix: uint) -> Option<T> {
assert!(radix >= 2 && radix <= 36,
"from_str_radix_float: must lie in the range `[2, 36]` - found {}",
radix);
let _0: T = Float::zero();
let _1: T = Float::one();
let radix_t: T = num::cast(radix as int).unwrap();
// Special values
match src {
"inf" => return Some(Float::infinity()),
"-inf" => return Some(Float::neg_infinity()),
"NaN" => return Some(Float::nan()),
_ => {},
}
let (is_positive, src) = match src.slice_shift_char() {
(None, _) => return None,
(Some('-'), "") => return None,
(Some('-'), src) => (false, src),
(Some(_), _) => (true, src),
};
// The significand to accumulate
let mut sig = if is_positive { _0 } else { -_0 };
// Necessary to detect overflow
let mut prev_sig = sig;
let mut cs = src.chars().enumerate();
// Exponent prefix and exponent index offset
let mut exp_info = None::<(char, uint)>;
// Parse the integer part of the significand
for (i, c) in cs {
match c.to_digit(radix) {
Some(digit) => {
// shift significand one digit left
sig = sig * radix_t;
// add/subtract current digit depending on sign
if is_positive {
sig = sig + num::cast(digit as int).unwrap();
} else {
sig = sig - num::cast(digit as int).unwrap();
}
// Detect overflow by comparing to last value, except
// if we've not seen any non-zero digits.
if prev_sig != _0 {
if is_positive && sig <= prev_sig
{ return Some(Float::infinity()); }
if !is_positive && sig >= prev_sig
{ return Some(Float::neg_infinity()); }
// Detect overflow by reversing the shift-and-add process
let digit: T = num::cast(digit as int).unwrap();
if is_positive && (prev_sig != ((sig - digit) / radix_t))
{ return Some(Float::infinity()); }
if !is_positive && (prev_sig != ((sig + digit) / radix_t))
{ return Some(Float::neg_infinity()); }
}
prev_sig = sig;
},
None => match c {
'e' | 'E' | 'p' | 'P' => {
exp_info = Some((c, i + 1));
break; // start of exponent
},
'.' => {
break; // start of fractional part
},
_ => {
return None;
},
},
}
}
// If we are not yet at the exponent parse the fractional
// part of the significand
if exp_info.is_none() {
let mut power = _1;
for (i, c) in cs {
match c.to_digit(radix) {
Some(digit) => {
let digit: T = num::cast(digit).unwrap();
// Decrease power one order of magnitude
power = power / radix_t;
// add/subtract current digit depending on sign
sig = if is_positive {
sig + digit * power
} else {
sig - digit * power
};
// Detect overflow by comparing to last value
if is_positive && sig < prev_sig
{ return Some(Float::infinity()); }
if !is_positive && sig > prev_sig
{ return Some(Float::neg_infinity()); }
prev_sig = sig;
},
None => match c {
'e' | 'E' | 'p' | 'P' => {
exp_info = Some((c, i + 1));
break; // start of exponent
},
_ => {
return None; // invalid number
},
},
}
}
}
// Parse and calculate the exponent
let exp = match exp_info {
Some((c, offset)) => {
let base: T = match c {
'E' | 'e' if radix == 10 => num::cast(10u).unwrap(),
'P' | 'p' if radix == 16 => num::cast(2u).unwrap(),
_ => return None,
};
// Parse the exponent as decimal integer
let src = src[offset..];
let (is_positive, exp) = match src.slice_shift_char() {
(Some('-'), src) => (false, from_str::<uint>(src)),
(Some('+'), src) => (true, from_str::<uint>(src)),
(Some(_), _) => (true, from_str::<uint>(src)),
(None, _) => return None,
};
match (is_positive, exp) {
(true, Some(exp)) => base.powi(exp as i32),
(false, Some(exp)) => _1 / base.powi(exp as i32),
(_, None) => return None,
}
},
None => _1, // no exponent
};
#[cfg(test)]
mod tests {
use string::ToString;
Some(sig * exp)
}
#[test]
fn test_int_to_str_overflow() {
let mut i8_val: i8 = 127_i8;
assert_eq!(i8_val.to_string(), "127".to_string());
pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
assert!(radix >= 2 && radix <= 36,
"from_str_radix_int: must lie in the range `[2, 36]` - found {}",
radix);
i8_val += 1 as i8;
assert_eq!(i8_val.to_string(), "-128".to_string());
fn cast<T: Int>(x: uint) -> T {
num::cast(x).unwrap()
}
let mut i16_val: i16 = 32_767_i16;
assert_eq!(i16_val.to_string(), "32767".to_string());
let _0: T = Int::zero();
let _1: T = Int::one();
let is_signed = _0 > Int::min_value();
i16_val += 1 as i16;
assert_eq!(i16_val.to_string(), "-32768".to_string());
let (is_positive, src) = match src.slice_shift_char() {
(Some('-'), src) if is_signed => (false, src),
(Some(_), _) => (true, src),
(None, _) => return None,
};
let mut i32_val: i32 = 2_147_483_647_i32;
assert_eq!(i32_val.to_string(), "2147483647".to_string());
let mut xs = src.chars().map(|c| {
c.to_digit(radix).map(cast)
});
let radix = cast(radix);
let mut result = _0;
if is_positive {
for x in xs {
let x = match x {
Some(x) => x,
None => return None,
};
result = match result.checked_mul(radix) {
Some(result) => result,
None => return None,
};
result = match result.checked_add(x) {
Some(result) => result,
None => return None,
};
}
} else {
for x in xs {
let x = match x {
Some(x) => x,
None => return None,
};
result = match result.checked_mul(radix) {
Some(result) => result,
None => return None,
};
result = match result.checked_sub(x) {
Some(result) => result,
None => return None,
};
}
}
i32_val += 1 as i32;
assert_eq!(i32_val.to_string(), "-2147483648".to_string());
Some(result)
}
let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
#[cfg(test)]
mod test {
use super::*;
use option::*;
use num::Float;
#[test]
fn from_str_issue7588() {
let u : Option<u8> = from_str_radix_int("1000", 10);
assert_eq!(u, None);
let s : Option<i16> = from_str_radix_int("80000", 10);
assert_eq!(s, None);
let f : Option<f32> = from_str_radix_float("10000000000000000000000000000000000000000", 10);
assert_eq!(f, Some(Float::infinity()))
let fe : Option<f32> = from_str_radix_float("1e40", 10);
assert_eq!(fe, Some(Float::infinity()))
}
#[test]
fn test_from_str_radix_float() {
let x1 : Option<f64> = from_str_radix_float("-123.456", 10);
assert_eq!(x1, Some(-123.456));
let x2 : Option<f32> = from_str_radix_float("123.456", 10);
assert_eq!(x2, Some(123.456));
let x3 : Option<f32> = from_str_radix_float("-0.0", 10);
assert_eq!(x3, Some(-0.0));
let x4 : Option<f32> = from_str_radix_float("0.0", 10);
assert_eq!(x4, Some(0.0));
let x4 : Option<f32> = from_str_radix_float("1.0", 10);
assert_eq!(x4, Some(1.0));
let x5 : Option<f32> = from_str_radix_float("-1.0", 10);
assert_eq!(x5, Some(-1.0));
i64_val += 1 as i64;
assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
}
}
......
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "u16")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::u16::{BITS, BYTES, MIN, MAX};
uint_module!(u16)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "u32")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::u32::{BITS, BYTES, MIN, MAX};
uint_module!(u32)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "u64")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::u64::{BITS, BYTES, MIN, MAX};
uint_module!(u64)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "u8")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::u8::{BITS, BYTES, MIN, MAX};
uint_module!(u8)
......@@ -13,11 +13,6 @@
#![unstable]
#![doc(primitive = "uint")]
use from_str::FromStr;
use num::FromStrRadix;
use num::strconv;
use option::Option;
pub use core::uint::{BITS, BYTES, MIN, MAX};
uint_module!(uint)
......@@ -15,22 +15,6 @@
macro_rules! uint_module (($T:ty) => (
#[experimental = "might need to return Result"]
impl FromStr for $T {
#[inline]
fn from_str(s: &str) -> Option<$T> {
strconv::from_str_radix_int(s, 10)
}
}
#[experimental = "might need to return Result"]
impl FromStrRadix for $T {
#[inline]
fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
strconv::from_str_radix_int(s, radix)
}
}
// String conversion functions and impl num -> str
/// Convert to a string as a byte slice in a given base.
......
......@@ -51,8 +51,7 @@
use slice::{AsSlice, SlicePrelude, PartialEqSlicePrelude};
use slice::CloneSliceAllocPrelude;
use str::{Str, StrPrelude, StrAllocating};
use string::String;
use to_string::ToString;
use string::{String, ToString};
use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
use vec::Vec;
......
......@@ -13,12 +13,11 @@
use c_str::{CString, ToCStr};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use from_str::FromStr;
use hash;
use io::Writer;
use iter::{DoubleEndedIterator, AdditiveIterator, Extend, Iterator, Map};
use option::{Option, None, Some};
use str::Str;
use str::{FromStr, Str};
use str;
use slice::{CloneSliceAllocPrelude, Splits, AsSlice, VectorVector,
PartialEqSlicePrelude, SlicePrelude};
......
......@@ -16,14 +16,13 @@
use c_str::{CString, ToCStr};
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use from_str::FromStr;
use hash;
use io::Writer;
use iter::{AdditiveIterator, DoubleEndedIterator, Extend, Iterator, Map};
use mem;
use option::{Option, Some, None};
use slice::{AsSlice, SlicePrelude};
use str::{CharSplits, Str, StrAllocating, StrVector, StrPrelude};
use str::{CharSplits, FromStr, Str, StrAllocating, StrVector, StrPrelude};
use string::String;
use unicode::char::UnicodeChar;
use vec::Vec;
......
......@@ -50,9 +50,9 @@
#[doc(no_inline)] pub use ops::{Fn, FnMut, FnOnce};
// Reexported functions
#[doc(no_inline)] pub use from_str::from_str;
#[doc(no_inline)] pub use iter::{range, repeat};
#[doc(no_inline)] pub use mem::drop;
#[doc(no_inline)] pub use str::from_str;
// Reexported types and traits
......@@ -76,14 +76,13 @@
#[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude};
#[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude};
#[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating, UnicodeStrPrelude};
#[doc(no_inline)] pub use to_string::{ToString, IntoStr};
#[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
#[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
#[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
#[doc(no_inline)] pub use slice::{SlicePrelude, AsSlice, CloneSlicePrelude};
#[doc(no_inline)] pub use slice::{VectorVector, PartialEqSlicePrelude, OrdSlicePrelude};
#[doc(no_inline)] pub use slice::{CloneSliceAllocPrelude, OrdSliceAllocPrelude, SliceAllocPrelude};
#[doc(no_inline)] pub use string::String;
#[doc(no_inline)] pub use string::{IntoString, String, ToString};
#[doc(no_inline)] pub use vec::Vec;
// Reexported runtime types
......
......@@ -12,13 +12,12 @@
#![allow(non_camel_case_types)]
use from_str::from_str;
use io::{IoResult, Writer};
use iter::Iterator;
use option::{Some, None};
use os;
use result::{Ok, Err};
use str::StrPrelude;
use str::{StrPrelude, from_str};
use sync::atomic;
use unicode::char::UnicodeChar;
......
......@@ -8,12 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use from_str::FromStr;
use from_str::from_str;
use libc::uintptr_t;
use option::{Some, None, Option};
use os;
use str::Str;
use str::{FromStr, from_str, Str};
use sync::atomic;
/// Dynamically inquire about whether we're running under V.
......
......@@ -105,9 +105,8 @@
use rt::task;
use rt::task::Task;
use str::{Str, SendStr, IntoMaybeOwned};
use string::String;
use string::{String, ToString};
use sync::Future;
use to_string::ToString;
/// A means of spawning a task
pub trait Spawner {
......
......@@ -388,7 +388,7 @@ mod tests {
use super::{Duration, MIN, MAX};
use {i32, i64};
use option::{Some, None};
use to_string::ToString;
use string::ToString;
#[test]
fn test_duration() {
......
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
The `ToString` trait for converting to strings
*/
#![experimental]
use fmt;
use string::String;
/// A generic trait for converting a value to a string
pub trait ToString {
/// Converts the value of `self` to an owned string
fn to_string(&self) -> String;
}
/// Trait for converting a type to a string, consuming it in the process.
pub trait IntoStr {
/// Consume and convert to a string.
fn into_string(self) -> String;
}
impl<T: fmt::Show> ToString for T {
fn to_string(&self) -> String {
format!("{}", *self)
}
}
#[cfg(test)]
mod tests {
use prelude::*;
use super::*;
#[test]
fn test_simple_types() {
assert_eq!(1i.to_string(), "1".to_string());
assert_eq!((-1i).to_string(), "-1".to_string());
assert_eq!(200u.to_string(), "200".to_string());
assert_eq!(2u8.to_string(), "2".to_string());
assert_eq!(true.to_string(), "true".to_string());
assert_eq!(false.to_string(), "false".to_string());
assert_eq!(().to_string(), "()".to_string());
assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
}
#[test]
fn test_vectors() {
let x: Vec<int> = vec![];
assert_eq!(x.to_string(), "[]".to_string());
assert_eq!((vec![1i]).to_string(), "[1]".to_string());
assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
"[[], [1], [1, 1]]".to_string());
}
}
......@@ -53,13 +53,13 @@
use std::f64;
use std::fmt::Show;
use std::fmt;
use std::from_str::FromStr;
use std::io::fs::PathExtensions;
use std::io::stdio::StdWriter;
use std::io::{File, ChanReader, ChanWriter};
use std::io;
use std::num::{Float, FloatMath, Int};
use std::os;
use std::str::FromStr;
use std::string::String;
use std::task::TaskBuilder;
use std::time::Duration;
......
......@@ -11,7 +11,7 @@
// aux-build:cci_class_cast.rs
extern crate cci_class_cast;
use std::to_string::ToString;
use std::string::ToString;
use cci_class_cast::kitty::cat;
fn print_out(thing: Box<ToString>, expected: String) {
......
......@@ -11,7 +11,7 @@
extern crate collections;
use std::str::{SendStr, Owned, Slice};
use std::to_string::ToString;
use std::string::ToString;
use self::collections::TreeMap;
use std::option::Some;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册