auto merge of #18978 : jakub-/rust/roll-up, r=cmr
This commit is contained in:
commit
0c7a3d6c16
74 changed files with 1015 additions and 937 deletions
|
@ -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 @@ extern crate regex;
|
|||
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::Config;
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ code should need to run is a stack.
|
|||
`match` being exhaustive has some useful properties. First, if every
|
||||
possibility is covered by the `match`, adding further variants to the `enum`
|
||||
in the future will prompt a compilation failure, rather than runtime panic.
|
||||
Second, it makes cost explicit. In general, only safe way to have a
|
||||
Second, it makes cost explicit. In general, the only safe way to have a
|
||||
non-exhaustive match would be to panic the task if nothing is matched, though
|
||||
it could fall through if the type of the `match` expression is `()`. This sort
|
||||
of hidden cost and special casing is against the language's philosophy. It's
|
||||
|
|
|
@ -133,11 +133,11 @@ pass-by-reference. Basically, languages can make two choices (this is made
|
|||
up syntax, it's not Rust):
|
||||
|
||||
```{notrust,ignore}
|
||||
fn foo(x) {
|
||||
func foo(x) {
|
||||
x = 5
|
||||
}
|
||||
|
||||
fn main() {
|
||||
func main() {
|
||||
i = 1
|
||||
foo(i)
|
||||
// what is the value of i here?
|
||||
|
@ -153,11 +153,11 @@ So what do pointers have to do with this? Well, since pointers point to a
|
|||
location in memory...
|
||||
|
||||
```{notrust,ignore}
|
||||
fn foo(&int x) {
|
||||
func foo(&int x) {
|
||||
*x = 5
|
||||
}
|
||||
|
||||
fn main() {
|
||||
func main() {
|
||||
i = 1
|
||||
foo(&i)
|
||||
// what is the value of i here?
|
||||
|
@ -192,13 +192,13 @@ When you combine pointers and functions, it's easy to accidentally invalidate
|
|||
the memory the pointer is pointing to. For example:
|
||||
|
||||
```{notrust,ignore}
|
||||
fn make_pointer(): &int {
|
||||
func make_pointer(): &int {
|
||||
x = 5;
|
||||
|
||||
return &x;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
func main() {
|
||||
&int i = make_pointer();
|
||||
*i = 5; // uh oh!
|
||||
}
|
||||
|
@ -214,11 +214,11 @@ issue. Two pointers are said to alias when they point at the same location
|
|||
in memory. Like this:
|
||||
|
||||
```{notrust,ignore}
|
||||
fn mutate(&int i, int j) {
|
||||
func mutate(&int i, int j) {
|
||||
*i = j;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
func main() {
|
||||
x = 5;
|
||||
y = &x;
|
||||
z = &x; //y and z are aliased
|
||||
|
|
|
@ -155,7 +155,7 @@ println!("{}", s[0]);
|
|||
This does not compile. This is on purpose. In the world of UTF-8, direct
|
||||
indexing is basically never what you want to do. The reason is that each
|
||||
character can be a variable number of bytes. This means that you have to iterate
|
||||
through the characters anyway, which is a O(n) operation.
|
||||
through the characters anyway, which is an O(n) operation.
|
||||
|
||||
There's 3 basic levels of unicode (and its encodings):
|
||||
|
||||
|
|
|
@ -2526,7 +2526,7 @@ The currently implemented features of the reference compiler are:
|
|||
|
||||
* `plugin_registrar` - Indicates that a crate has [compiler plugins][plugin] that it
|
||||
wants to load. As with `phase`, the implementation is
|
||||
in need of a overhaul, and it is not clear that plugins
|
||||
in need of an overhaul, and it is not clear that plugins
|
||||
defined using this will continue to work.
|
||||
|
||||
* `quote` - Allows use of the `quote_*!` family of macros, which are
|
||||
|
@ -2583,7 +2583,7 @@ there isn't a parser error first). The directive in this case is no longer
|
|||
necessary, and it's likely that existing code will break if the feature isn't
|
||||
removed.
|
||||
|
||||
If a unknown feature is found in a directive, it results in a compiler error.
|
||||
If an unknown feature is found in a directive, it results in a compiler error.
|
||||
An unknown feature is one which has never been recognized by the compiler.
|
||||
|
||||
# Statements and expressions
|
||||
|
@ -2685,7 +2685,7 @@ When an lvalue is evaluated in an _lvalue context_, it denotes a memory
|
|||
location; when evaluated in an _rvalue context_, it denotes the value held _in_
|
||||
that memory location.
|
||||
|
||||
When an rvalue is used in lvalue context, a temporary un-named lvalue is
|
||||
When an rvalue is used in an lvalue context, a temporary un-named lvalue is
|
||||
created and used instead. A temporary's lifetime equals the largest lifetime
|
||||
of any reference that points to it.
|
||||
|
||||
|
@ -2833,7 +2833,7 @@ foo().x;
|
|||
```
|
||||
|
||||
A field access is an [lvalue](#lvalues,-rvalues-and-temporaries) referring to
|
||||
the value of that field. When the type providing the field inherits mutabilty,
|
||||
the value of that field. When the type providing the field inherits mutability,
|
||||
it can be [assigned](#assignment-expressions) to.
|
||||
|
||||
Also, if the type of the expression to the left of the dot is a pointer, it is
|
||||
|
@ -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
|
||||
|
@ -3321,7 +3320,7 @@ between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
|
|||
exactly one argument, while the pattern `C(..)` is type-correct for any enum
|
||||
variant `C`, regardless of how many arguments `C` has.
|
||||
|
||||
Used inside a array pattern, `..` stands for any number of elements, when the
|
||||
Used inside an array pattern, `..` stands for any number of elements, when the
|
||||
`advanced_slice_patterns` feature gate is turned on. This wildcard can be used
|
||||
at most once for a given array, which implies that it cannot be used to
|
||||
specifically match elements that are at an unknown distance from both ends of a
|
||||
|
@ -3584,7 +3583,7 @@ is not a surrogate), represented as a 32-bit unsigned word in the 0x0000 to
|
|||
0xD7FF or 0xE000 to 0x10FFFF range. A `[char]` array is effectively an UCS-4 /
|
||||
UTF-32 string.
|
||||
|
||||
A value of type `str` is a Unicode string, represented as a array of 8-bit
|
||||
A value of type `str` is a Unicode string, represented as an array of 8-bit
|
||||
unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of
|
||||
unknown size, it is not a _first class_ type, but can only be instantiated
|
||||
through a pointer type, such as `&str` or `String`.
|
||||
|
|
|
@ -75,7 +75,11 @@ def full_snapshot_name(date, rev, platform, hsh):
|
|||
|
||||
|
||||
def get_kernel(triple):
|
||||
os_name = triple.split('-')[2]
|
||||
t = triple.split('-')
|
||||
if len(t) == 2:
|
||||
os_name = t[1]
|
||||
else:
|
||||
os_name = t[2]
|
||||
if os_name == "windows":
|
||||
return "winnt"
|
||||
if os_name == "darwin":
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -179,9 +179,9 @@ pub struct Rc<T> {
|
|||
_noshare: marker::NoSync
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl<T> Rc<T> {
|
||||
/// Constructs a new reference-counted pointer.
|
||||
#[stable]
|
||||
pub fn new(value: T) -> Rc<T> {
|
||||
unsafe {
|
||||
Rc {
|
||||
|
@ -200,9 +200,7 @@ impl<T> Rc<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Rc<T> {
|
||||
/// Downgrades the reference-counted pointer to a weak reference.
|
||||
#[experimental = "Weak pointers may not belong in this module"]
|
||||
pub fn downgrade(&self) -> Weak<T> {
|
||||
|
|
|
@ -73,6 +73,7 @@ pub use core::str::{CharSplitsN, AnyLines, MatchIndices, StrSplits};
|
|||
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 core::raw::Slice as RawSlice;
|
|||
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 @@ mod tests {
|
|||
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(|| {
|
||||
|
|
|
@ -504,9 +504,9 @@ impl<T: Ord> TreeSet<T> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::collections::TreeSet;
|
||||
///
|
||||
/// let mut set = BTreeSet::new();
|
||||
/// let mut set = TreeSet::new();
|
||||
///
|
||||
/// assert_eq!(set.insert(2i), true);
|
||||
/// assert_eq!(set.insert(2i), false);
|
||||
|
@ -522,9 +522,9 @@ impl<T: Ord> TreeSet<T> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::collections::TreeSet;
|
||||
///
|
||||
/// let mut set = BTreeSet::new();
|
||||
/// let mut set = TreeSet::new();
|
||||
///
|
||||
/// set.insert(2i);
|
||||
/// assert_eq!(set.remove(&2), true);
|
||||
|
|
|
@ -645,7 +645,6 @@ impl<T> Vec<T> {
|
|||
/// assert!(vec.capacity() >= 3);
|
||||
/// ```
|
||||
#[stable]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn shrink_to_fit(&mut self) {
|
||||
if mem::size_of::<T>() == 0 { return }
|
||||
|
||||
|
@ -1653,6 +1652,13 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -88,6 +88,7 @@ use intrinsics::TypeId;
|
|||
#[stable]
|
||||
pub trait Any: 'static {
|
||||
/// Get the `TypeId` of `self`
|
||||
#[stable]
|
||||
fn get_type_id(&self) -> TypeId;
|
||||
}
|
||||
|
||||
|
@ -117,7 +118,6 @@ pub trait AnyRefExt<'a> {
|
|||
#[stable]
|
||||
impl<'a> AnyRefExt<'a> for &'a Any {
|
||||
#[inline]
|
||||
#[stable]
|
||||
fn is<T: 'static>(self) -> bool {
|
||||
// Get TypeId of the type this function is instantiated with
|
||||
let t = TypeId::of::<T>();
|
||||
|
@ -130,7 +130,6 @@ impl<'a> AnyRefExt<'a> for &'a Any {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[unstable = "naming conventions around acquiring references may change"]
|
||||
fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
|
@ -159,7 +158,6 @@ pub trait AnyMutRefExt<'a> {
|
|||
#[stable]
|
||||
impl<'a> AnyMutRefExt<'a> for &'a mut Any {
|
||||
#[inline]
|
||||
#[unstable = "naming conventions around acquiring references may change"]
|
||||
fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
|
|
|
@ -58,20 +58,25 @@ pub struct AtomicPtr<T> {
|
|||
#[stable]
|
||||
pub enum Ordering {
|
||||
/// No ordering constraints, only atomic operations
|
||||
#[stable]
|
||||
Relaxed,
|
||||
/// When coupled with a store, all previous writes become visible
|
||||
/// to another thread that performs a load with `Acquire` ordering
|
||||
/// on the same value
|
||||
#[stable]
|
||||
Release,
|
||||
/// When coupled with a load, all subsequent loads will see data
|
||||
/// written before a store with `Release` ordering on the same value
|
||||
/// in another thread
|
||||
#[stable]
|
||||
Acquire,
|
||||
/// When coupled with a load, uses `Acquire` ordering, and with a store
|
||||
/// `Release` ordering
|
||||
#[stable]
|
||||
AcqRel,
|
||||
/// Like `AcqRel` with the additional guarantee that all threads see all
|
||||
/// sequentially consistent operations in the same order.
|
||||
#[stable]
|
||||
SeqCst
|
||||
}
|
||||
|
||||
|
@ -91,10 +96,10 @@ pub const INIT_ATOMIC_UINT: AtomicUint =
|
|||
// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
|
||||
const UINT_TRUE: uint = -1;
|
||||
|
||||
#[stable]
|
||||
impl AtomicBool {
|
||||
/// Create a new `AtomicBool`
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn new(v: bool) -> AtomicBool {
|
||||
let val = if v { UINT_TRUE } else { 0 };
|
||||
AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
|
||||
|
@ -106,6 +111,7 @@ impl AtomicBool {
|
|||
///
|
||||
/// Panics if `order` is `Release` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> bool {
|
||||
unsafe { atomic_load(self.v.get() as *const uint, order) > 0 }
|
||||
}
|
||||
|
@ -116,6 +122,7 @@ impl AtomicBool {
|
|||
///
|
||||
/// Panics if `order` is `Acquire` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn store(&self, val: bool, order: Ordering) {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
|
@ -124,6 +131,7 @@ impl AtomicBool {
|
|||
|
||||
/// Store a value, returning the old value
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
|
@ -174,6 +182,7 @@ impl AtomicBool {
|
|||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn compare_and_swap(&self, old: bool, new: bool, order: Ordering) -> bool {
|
||||
let old = if old { UINT_TRUE } else { 0 };
|
||||
let new = if new { UINT_TRUE } else { 0 };
|
||||
|
@ -205,6 +214,7 @@ impl AtomicBool {
|
|||
/// assert_eq!(false, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
|
@ -236,6 +246,7 @@ impl AtomicBool {
|
|||
/// assert_eq!(true, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
|
@ -266,6 +277,7 @@ impl AtomicBool {
|
|||
/// assert_eq!(false, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
|
@ -296,6 +308,7 @@ impl AtomicBool {
|
|||
/// assert_eq!(false, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
|
@ -303,10 +316,10 @@ impl AtomicBool {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl AtomicInt {
|
||||
/// Create a new `AtomicInt`
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn new(v: int) -> AtomicInt {
|
||||
AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
|
||||
}
|
||||
|
@ -317,6 +330,7 @@ impl AtomicInt {
|
|||
///
|
||||
/// Panics if `order` is `Release` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> int {
|
||||
unsafe { atomic_load(self.v.get() as *const int, order) }
|
||||
}
|
||||
|
@ -327,12 +341,14 @@ impl AtomicInt {
|
|||
///
|
||||
/// Panics if `order` is `Acquire` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn store(&self, val: int, order: Ordering) {
|
||||
unsafe { atomic_store(self.v.get(), val, order); }
|
||||
}
|
||||
|
||||
/// Store a value, returning the old value
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn swap(&self, val: int, order: Ordering) -> int {
|
||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -343,6 +359,7 @@ impl AtomicInt {
|
|||
/// replace the current value with `new`. Return the previous value.
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
|
||||
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
|
||||
}
|
||||
|
@ -359,6 +376,7 @@ impl AtomicInt {
|
|||
/// assert_eq!(10, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_add(&self, val: int, order: Ordering) -> int {
|
||||
unsafe { atomic_add(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -375,6 +393,7 @@ impl AtomicInt {
|
|||
/// assert_eq!(-10, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
|
||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -390,6 +409,7 @@ impl AtomicInt {
|
|||
/// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
|
||||
/// assert_eq!(0b100001, foo.load(SeqCst));
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_and(&self, val: int, order: Ordering) -> int {
|
||||
unsafe { atomic_and(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -405,6 +425,7 @@ impl AtomicInt {
|
|||
/// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
|
||||
/// assert_eq!(0b111111, foo.load(SeqCst));
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_or(&self, val: int, order: Ordering) -> int {
|
||||
unsafe { atomic_or(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -420,15 +441,16 @@ impl AtomicInt {
|
|||
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
|
||||
/// assert_eq!(0b011110, foo.load(SeqCst));
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
|
||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl AtomicUint {
|
||||
/// Create a new `AtomicUint`
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn new(v: uint) -> AtomicUint {
|
||||
AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
|
||||
}
|
||||
|
@ -439,6 +461,7 @@ impl AtomicUint {
|
|||
///
|
||||
/// Panics if `order` is `Release` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> uint {
|
||||
unsafe { atomic_load(self.v.get() as *const uint, order) }
|
||||
}
|
||||
|
@ -449,12 +472,14 @@ impl AtomicUint {
|
|||
///
|
||||
/// Panics if `order` is `Acquire` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn store(&self, val: uint, order: Ordering) {
|
||||
unsafe { atomic_store(self.v.get(), val, order); }
|
||||
}
|
||||
|
||||
/// Store a value, returning the old value
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn swap(&self, val: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -465,6 +490,7 @@ impl AtomicUint {
|
|||
/// replace the current value with `new`. Return the previous value.
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
|
||||
}
|
||||
|
@ -481,6 +507,7 @@ impl AtomicUint {
|
|||
/// assert_eq!(10, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_add(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -497,6 +524,7 @@ impl AtomicUint {
|
|||
/// assert_eq!(0, foo.load(SeqCst));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -512,6 +540,7 @@ impl AtomicUint {
|
|||
/// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
|
||||
/// assert_eq!(0b100001, foo.load(SeqCst));
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_and(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -527,6 +556,7 @@ impl AtomicUint {
|
|||
/// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
|
||||
/// assert_eq!(0b111111, foo.load(SeqCst));
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_or(self.v.get(), val, order) }
|
||||
}
|
||||
|
@ -542,15 +572,16 @@ impl AtomicUint {
|
|||
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
|
||||
/// assert_eq!(0b011110, foo.load(SeqCst));
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
|
||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl<T> AtomicPtr<T> {
|
||||
/// Create a new `AtomicPtr`
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn new(p: *mut T) -> AtomicPtr<T> {
|
||||
AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
|
||||
}
|
||||
|
@ -561,6 +592,7 @@ impl<T> AtomicPtr<T> {
|
|||
///
|
||||
/// Panics if `order` is `Release` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn load(&self, order: Ordering) -> *mut T {
|
||||
unsafe {
|
||||
atomic_load(self.p.get() as *const *mut T, order) as *mut T
|
||||
|
@ -573,12 +605,14 @@ impl<T> AtomicPtr<T> {
|
|||
///
|
||||
/// Panics if `order` is `Acquire` or `AcqRel`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn store(&self, ptr: *mut T, order: Ordering) {
|
||||
unsafe { atomic_store(self.p.get(), ptr as uint, order); }
|
||||
}
|
||||
|
||||
/// Store a value, returning the old value
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
|
||||
unsafe { atomic_swap(self.p.get(), ptr as uint, order) as *mut T }
|
||||
}
|
||||
|
@ -589,6 +623,7 @@ impl<T> AtomicPtr<T> {
|
|||
/// replace the current value with `new`. Return the previous value.
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
|
||||
unsafe {
|
||||
atomic_compare_and_swap(self.p.get(), old as uint,
|
||||
|
@ -609,6 +644,7 @@ unsafe fn atomic_store<T>(dst: *mut T, val: T, order:Ordering) {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_load_acq(dst),
|
||||
|
@ -620,6 +656,7 @@ unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xchg_acq(dst, val),
|
||||
|
@ -632,6 +669,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// Returns the old value (like __sync_fetch_and_add).
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xadd_acq(dst, val),
|
||||
|
@ -644,6 +682,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
/// Returns the old value (like __sync_fetch_and_sub).
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xsub_acq(dst, val),
|
||||
|
@ -655,6 +694,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_compare_and_swap<T>(dst: *mut T, old:T, new:T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_cxchg_acq(dst, old, new),
|
||||
|
@ -666,6 +706,7 @@ unsafe fn atomic_compare_and_swap<T>(dst: *mut T, old:T, new:T, order: Ordering)
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_and_acq(dst, val),
|
||||
|
@ -677,6 +718,7 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_nand_acq(dst, val),
|
||||
|
@ -689,6 +731,7 @@ unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_or_acq(dst, val),
|
||||
|
@ -701,6 +744,7 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
|
||||
|
||||
#[inline]
|
||||
#[stable]
|
||||
unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_xor_acq(dst, val),
|
||||
|
|
|
@ -157,6 +157,7 @@
|
|||
|
||||
use clone::Clone;
|
||||
use cmp::PartialEq;
|
||||
use default::Default;
|
||||
use kinds::{marker, Copy};
|
||||
use ops::{Deref, DerefMut, Drop};
|
||||
use option::{None, Option, Some};
|
||||
|
@ -168,9 +169,9 @@ pub struct Cell<T> {
|
|||
noshare: marker::NoSync,
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl<T:Copy> Cell<T> {
|
||||
/// Creates a new `Cell` containing the given value.
|
||||
#[stable]
|
||||
pub fn new(value: T) -> Cell<T> {
|
||||
Cell {
|
||||
value: UnsafeCell::new(value),
|
||||
|
@ -180,12 +181,14 @@ impl<T:Copy> Cell<T> {
|
|||
|
||||
/// Returns a copy of the contained value.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn get(&self) -> T {
|
||||
unsafe{ *self.value.get() }
|
||||
}
|
||||
|
||||
/// Sets the contained value.
|
||||
#[inline]
|
||||
#[stable]
|
||||
pub fn set(&self, value: T) {
|
||||
unsafe {
|
||||
*self.value.get() = value;
|
||||
|
@ -211,6 +214,13 @@ impl<T:Copy> Clone for Cell<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable]
|
||||
impl<T:Default + Copy> Default for Cell<T> {
|
||||
fn default() -> Cell<T> {
|
||||
Cell::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable = "waiting for `PartialEq` trait to become stable"]
|
||||
impl<T:PartialEq + Copy> PartialEq for Cell<T> {
|
||||
fn eq(&self, other: &Cell<T>) -> bool {
|
||||
|
@ -337,6 +347,13 @@ impl<T: Clone> Clone for RefCell<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable]
|
||||
impl<T:Default> Default for RefCell<T> {
|
||||
fn default() -> RefCell<T> {
|
||||
RefCell::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable = "waiting for `PartialEq` to become stable"]
|
||||
impl<T: PartialEq> PartialEq for RefCell<T> {
|
||||
fn eq(&self, other: &RefCell<T>) -> bool {
|
||||
|
|
|
@ -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 @@ impl Float for 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 @@ impl Float for 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 {
|
||||
|
|
|
@ -716,7 +716,6 @@ impl<T: Default> Option<T> {
|
|||
impl<T> AsSlice<T> for Option<T> {
|
||||
/// Convert from `Option<T>` to `&[T]` (without copying)
|
||||
#[inline]
|
||||
#[stable]
|
||||
fn as_slice<'a>(&'a self) -> &'a [T] {
|
||||
match *self {
|
||||
Some(ref x) => slice::ref_slice(x),
|
||||
|
@ -728,6 +727,7 @@ impl<T> AsSlice<T> for Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl<T> Default for Option<T> {
|
||||
#[inline]
|
||||
fn default() -> Option<T> { None }
|
||||
|
@ -772,9 +772,10 @@ impl<A> DoubleEndedIterator<A> for Item<A> {
|
|||
impl<A> ExactSize<A> for Item<A> {}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Free functions
|
||||
// FromIterator
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[stable]
|
||||
impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
|
||||
/// Takes each element in the `Iterator`: if it is `None`, no further
|
||||
/// elements are taken, and the `None` is returned. Should no `None` occur, a
|
||||
|
|
|
@ -41,6 +41,7 @@ pub use ops::{Fn, FnMut, FnOnce};
|
|||
// Reexported functions
|
||||
pub use iter::{range, repeat};
|
||||
pub use mem::drop;
|
||||
pub use str::from_str;
|
||||
|
||||
// Reexported types and traits
|
||||
|
||||
|
|
|
@ -878,9 +878,10 @@ impl<A> DoubleEndedIterator<A> for Item<A> {
|
|||
impl<A> ExactSize<A> for Item<A> {}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Free functions
|
||||
// FromIterator
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[stable]
|
||||
impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
|
||||
/// Takes each element in the `Iterator`: if it is an `Err`, no further
|
||||
/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
|
||||
|
@ -933,6 +934,10 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// FromIterator
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Perform a fold operation over the result values from an iterator.
|
||||
///
|
||||
/// If an `Err` is encountered, it is immediately returned.
|
||||
|
|
|
@ -31,6 +31,42 @@ use raw::Repr;
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use core::cell::*;
|
||||
use core::default::Default;
|
||||
use std::mem::drop;
|
||||
|
||||
#[test]
|
||||
|
@ -146,3 +147,15 @@ fn as_unsafe_cell() {
|
|||
unsafe { *r2.as_unsafe_cell().get() = 1u; }
|
||||
assert_eq!(1u, *r2.borrow());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cell_default() {
|
||||
let cell: Cell<u32> = Default::default();
|
||||
assert_eq!(0, cell.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refcell_default() {
|
||||
let cell: RefCell<u64> = Default::default();
|
||||
assert_eq!(0, *cell.borrow());
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@ macro_rules! int_module (($T:ty, $T_i:ident) => (
|
|||
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 @@ mod tests {
|
|||
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;
|
||||
|
|
|
@ -268,8 +268,21 @@ macro_rules! cgoptions(
|
|||
|
||||
pub type CodegenSetter = fn(&mut CodegenOptions, v: Option<&str>) -> bool;
|
||||
pub const CG_OPTIONS: &'static [(&'static str, CodegenSetter,
|
||||
&'static str)] =
|
||||
&[ $( (stringify!($opt), cgsetters::$opt, $desc) ),* ];
|
||||
Option<&'static str>, &'static str)] =
|
||||
&[ $( (stringify!($opt), cgsetters::$opt, cg_type_descs::$parse, $desc) ),* ];
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
mod cg_type_descs {
|
||||
pub const parse_bool: Option<&'static str> = None;
|
||||
pub const parse_opt_bool: Option<&'static str> = None;
|
||||
pub const parse_string: Option<&'static str> = Some("a string");
|
||||
pub const parse_opt_string: Option<&'static str> = Some("a string");
|
||||
pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
|
||||
pub const parse_opt_list: Option<&'static str> = Some("a space-separated list of strings");
|
||||
pub const parse_uint: Option<&'static str> = Some("a number");
|
||||
pub const parse_passes: Option<&'static str> =
|
||||
Some("a space-separated list of passes, or `all`");
|
||||
}
|
||||
|
||||
mod cgsetters {
|
||||
use super::{CodegenOptions, Passes, SomePasses, AllPasses};
|
||||
|
@ -334,8 +347,7 @@ macro_rules! cgoptions(
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -421,19 +433,25 @@ pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
|
|||
let value = iter.next();
|
||||
let option_to_lookup = key.replace("-", "_");
|
||||
let mut found = false;
|
||||
for &(candidate, setter, _) in CG_OPTIONS.iter() {
|
||||
for &(candidate, setter, opt_type_desc, _) in CG_OPTIONS.iter() {
|
||||
if option_to_lookup.as_slice() != candidate { continue }
|
||||
if !setter(&mut cg, value) {
|
||||
match value {
|
||||
Some(..) => {
|
||||
match (value, opt_type_desc) {
|
||||
(Some(..), None) => {
|
||||
early_error(format!("codegen option `{}` takes no \
|
||||
value", key).as_slice())
|
||||
}
|
||||
None => {
|
||||
(None, Some(type_desc)) => {
|
||||
early_error(format!("codegen option `{0}` requires \
|
||||
a value (-C {0}=<value>)",
|
||||
key).as_slice())
|
||||
{1} (-C {0}=<value>)",
|
||||
key, type_desc).as_slice())
|
||||
}
|
||||
(Some(value), Some(type_desc)) => {
|
||||
early_error(format!("incorrect value `{}` for codegen \
|
||||
option `{}` - {} was expected",
|
||||
value, key, type_desc).as_slice())
|
||||
}
|
||||
(None, None) => unreachable!()
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
|
|
|
@ -299,14 +299,10 @@ fn describe_debug_flags() {
|
|||
|
||||
fn describe_codegen_flags() {
|
||||
println!("\nAvailable codegen options:\n");
|
||||
let mut cg = config::basic_codegen_options();
|
||||
for &(name, parser, desc) in config::CG_OPTIONS.iter() {
|
||||
// we invoke the parser function on `None` to see if this option needs
|
||||
// an argument or not.
|
||||
let (width, extra) = if parser(&mut cg, None) {
|
||||
(25, "")
|
||||
} else {
|
||||
(21, "=val")
|
||||
for &(name, _, opt_type_desc, desc) in config::CG_OPTIONS.iter() {
|
||||
let (width, extra) = match opt_type_desc {
|
||||
Some(..) => (21, "=val"),
|
||||
None => (25, "")
|
||||
};
|
||||
println!(" -C {:>width$s}{} -- {}", name.replace("_", "-"),
|
||||
extra, desc, width=width);
|
||||
|
|
|
@ -31,8 +31,8 @@ use syntax::print::{pp, pprust};
|
|||
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)]
|
||||
|
|
|
@ -455,7 +455,12 @@ pub fn llvm_type_name(cx: &CrateContext,
|
|||
|
||||
let base = ty::item_path_str(cx.tcx(), did);
|
||||
let strings: Vec<String> = tps.iter().map(|t| t.repr(cx.tcx())).collect();
|
||||
let tstr = format!("{}<{}>", base, strings);
|
||||
let tstr = if strings.is_empty() {
|
||||
base
|
||||
} else {
|
||||
format!("{}<{}>", base, strings)
|
||||
};
|
||||
|
||||
if did.krate == 0 {
|
||||
format!("{}.{}", name, tstr)
|
||||
} else {
|
||||
|
|
|
@ -584,3 +584,9 @@ pre.rust { position: relative; }
|
|||
height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
nav.sub, .content .out-of-band, .collapse-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use std::num::Zero;
|
|||
use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
|
||||
use syntax::ast::Public;
|
||||
|
||||
use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
|
||||
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
|
||||
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
|
||||
use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
|
||||
|
||||
|
@ -146,13 +146,12 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
|
|||
// considered to have no children.
|
||||
match item.inner {
|
||||
// Require explicit `pub` to be visible
|
||||
StructItem(Struct { fields: ref subitems, .. }) |
|
||||
ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
|
||||
let subcounts = subitems.iter().filter(|i| visible(*i))
|
||||
.map(summarize_item)
|
||||
.map(|s| s.val0())
|
||||
.fold(Counts::zero(), |acc, x| acc + x);
|
||||
(item_counts + subcounts, None)
|
||||
(subcounts, None)
|
||||
}
|
||||
// `pub` automatically
|
||||
EnumItem(Enum { variants: ref subitems, .. }) => {
|
||||
|
|
|
@ -200,7 +200,7 @@ use std::{char, f64, fmt, io, num, str};
|
|||
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 @@ macro_rules! read_primitive {
|
|||
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 @@ impl ::Decoder<DecoderError> for Decoder {
|
|||
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)),
|
||||
}
|
||||
|
@ -2315,6 +2315,10 @@ impl ToJson for bool {
|
|||
fn to_json(&self) -> Json { Boolean(*self) }
|
||||
}
|
||||
|
||||
impl ToJson for str {
|
||||
fn to_json(&self) -> Json { String(self.into_string()) }
|
||||
}
|
||||
|
||||
impl ToJson for string::String {
|
||||
fn to_json(&self) -> Json { String((*self).clone()) }
|
||||
}
|
||||
|
@ -2395,7 +2399,7 @@ impl fmt::Show for Json {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::from_str::FromStr for Json {
|
||||
impl FromStr for Json {
|
||||
fn from_str(s: &str) -> Option<Json> {
|
||||
from_str(s).ok()
|
||||
}
|
||||
|
@ -2480,7 +2484,7 @@ mod tests {
|
|||
#[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]
|
||||
|
@ -3714,7 +3718,8 @@ mod tests {
|
|||
assert_eq!(f64::NAN.to_json(), Null);
|
||||
assert_eq!(true.to_json(), Boolean(true));
|
||||
assert_eq!(false.to_json(), Boolean(false));
|
||||
assert_eq!("abc".to_string().to_json(), String("abc".to_string()));
|
||||
assert_eq!("abc".to_json(), String("abc".into_string()));
|
||||
assert_eq!("abc".into_string().to_json(), String("abc".into_string()));
|
||||
assert_eq!((1u, 2u).to_json(), list2);
|
||||
assert_eq!((1u, 2u, 3u).to_json(), list3);
|
||||
assert_eq!([1u, 2].to_json(), list2);
|
||||
|
|
|
@ -21,8 +21,7 @@ use mem;
|
|||
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 @@ impl AsciiStr for [Ascii] {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoStr for Vec<Ascii> {
|
||||
impl IntoString for Vec<Ascii> {
|
||||
#[inline]
|
||||
fn into_string(self) -> String {
|
||||
unsafe {
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
// 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 @@ impl<'a> ToSocketAddr for &'a str {
|
|||
mod test {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use from_str::FromStr;
|
||||
use str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_from_str_ipv4() {
|
||||
|
|
|
@ -661,14 +661,15 @@ mod test {
|
|||
let addr = next_test_ip4();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
drop(TcpStream::connect(addr));
|
||||
tx.send(());
|
||||
});
|
||||
|
||||
let mut stream = acceptor.accept();
|
||||
rx.recv();
|
||||
let buf = [0];
|
||||
loop {
|
||||
match stream.write(buf) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
|
@ -676,8 +677,6 @@ mod test {
|
|||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -687,14 +686,15 @@ mod test {
|
|||
let addr = next_test_ip6();
|
||||
let mut acceptor = TcpListener::bind(addr).listen();
|
||||
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
let _stream = TcpStream::connect(addr);
|
||||
// Close
|
||||
drop(TcpStream::connect(addr));
|
||||
tx.send(());
|
||||
});
|
||||
|
||||
let mut stream = acceptor.accept();
|
||||
rx.recv();
|
||||
let buf = [0];
|
||||
loop {
|
||||
match stream.write(buf) {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
|
@ -702,8 +702,6 @@ mod test {
|
|||
e.kind == BrokenPipe ||
|
||||
e.kind == ConnectionAborted,
|
||||
"unknown error: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1190,7 +1190,7 @@ mod tests {
|
|||
Path::new("/dev/null")
|
||||
};
|
||||
|
||||
let mut fdes = match fs::open(&path, Truncate, Write) {
|
||||
let fdes = match fs::open(&path, Truncate, Write) {
|
||||
Ok(f) => f,
|
||||
Err(_) => panic!("failed to open file descriptor"),
|
||||
};
|
||||
|
|
|
@ -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 @@ pub mod time;
|
|||
/* 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::{checked_next_power_of_two};
|
|||
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 @@ mod tests {
|
|||
|
||||
#[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
|
||||
};
|
||||
|
||||
Some(sig * exp)
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
fn cast<T: Int>(x: uint) -> T {
|
||||
num::cast(x).unwrap()
|
||||
}
|
||||
|
||||
let _0: T = Int::zero();
|
||||
let _1: T = Int::one();
|
||||
let is_signed = _0 > Int::min_value();
|
||||
|
||||
let (is_positive, src) = match src.slice_shift_char() {
|
||||
(Some('-'), src) if is_signed => (false, src),
|
||||
(Some(_), _) => (true, src),
|
||||
(None, _) => return None,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Some(result)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use option::*;
|
||||
use num::Float;
|
||||
mod tests {
|
||||
use string::ToString;
|
||||
|
||||
#[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()))
|
||||
}
|
||||
fn test_int_to_str_overflow() {
|
||||
let mut i8_val: i8 = 127_i8;
|
||||
assert_eq!(i8_val.to_string(), "127".to_string());
|
||||
|
||||
#[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));
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 result::{Err, Ok, Result};
|
|||
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 ascii::AsciiCast;
|
|||
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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -12,91 +12,195 @@
|
|||
|
||||
use core::prelude::*;
|
||||
|
||||
use task;
|
||||
use task::spawn;
|
||||
use vec::Vec;
|
||||
use comm::{channel, Sender};
|
||||
use comm::{channel, Sender, Receiver};
|
||||
use sync::{Arc, Mutex};
|
||||
|
||||
enum Msg<T> {
|
||||
Execute(proc(&T):Send),
|
||||
Quit
|
||||
struct Sentinel<'a> {
|
||||
jobs: &'a Arc<Mutex<Receiver<proc(): Send>>>,
|
||||
active: bool
|
||||
}
|
||||
|
||||
/// A task pool used to execute functions in parallel.
|
||||
pub struct TaskPool<T> {
|
||||
channels: Vec<Sender<Msg<T>>>,
|
||||
next_index: uint,
|
||||
impl<'a> Sentinel<'a> {
|
||||
fn new(jobs: &Arc<Mutex<Receiver<proc(): Send>>>) -> Sentinel {
|
||||
Sentinel {
|
||||
jobs: jobs,
|
||||
active: true
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel and destroy this sentinel.
|
||||
fn cancel(mut self) {
|
||||
self.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<T> Drop for TaskPool<T> {
|
||||
impl<'a> Drop for Sentinel<'a> {
|
||||
fn drop(&mut self) {
|
||||
for channel in self.channels.iter_mut() {
|
||||
channel.send(Quit);
|
||||
if self.active {
|
||||
spawn_in_pool(self.jobs.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TaskPool<T> {
|
||||
/// Spawns a new task pool with `n_tasks` tasks. The provided
|
||||
/// `init_fn_factory` returns a function which, given the index of the
|
||||
/// task, should return local data to be kept around in that task.
|
||||
/// A task pool used to execute functions in parallel.
|
||||
///
|
||||
/// Spawns `n` worker tasks and replenishes the pool if any worker tasks
|
||||
/// panic.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::sync::TaskPool;
|
||||
/// # use std::iter::AdditiveIterator;
|
||||
///
|
||||
/// let pool = TaskPool::new(4u);
|
||||
///
|
||||
/// let (tx, rx) = channel();
|
||||
/// for _ in range(0, 8u) {
|
||||
/// let tx = tx.clone();
|
||||
/// pool.execute(proc() {
|
||||
/// tx.send(1u);
|
||||
/// });
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(rx.iter().take(8u).sum(), 8u);
|
||||
/// ```
|
||||
pub struct TaskPool {
|
||||
// How the taskpool communicates with subtasks.
|
||||
//
|
||||
// This is the only such Sender, so when it is dropped all subtasks will
|
||||
// quit.
|
||||
jobs: Sender<proc(): Send>
|
||||
}
|
||||
|
||||
impl TaskPool {
|
||||
/// Spawns a new task pool with `tasks` tasks.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if `n_tasks` is less than 1.
|
||||
pub fn new(n_tasks: uint,
|
||||
init_fn_factory: || -> proc(uint):Send -> T)
|
||||
-> TaskPool<T> {
|
||||
assert!(n_tasks >= 1);
|
||||
/// This function will panic if `tasks` is 0.
|
||||
pub fn new(tasks: uint) -> TaskPool {
|
||||
assert!(tasks >= 1);
|
||||
|
||||
let channels = Vec::from_fn(n_tasks, |i| {
|
||||
let (tx, rx) = channel::<Msg<T>>();
|
||||
let init_fn = init_fn_factory();
|
||||
let (tx, rx) = channel::<proc(): Send>();
|
||||
let rx = Arc::new(Mutex::new(rx));
|
||||
|
||||
// Taskpool tasks.
|
||||
for _ in range(0, tasks) {
|
||||
spawn_in_pool(rx.clone());
|
||||
}
|
||||
|
||||
TaskPool { jobs: tx }
|
||||
}
|
||||
|
||||
/// Executes the function `job` on a task in the pool.
|
||||
pub fn execute(&self, job: proc():Send) {
|
||||
self.jobs.send(job);
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_in_pool(jobs: Arc<Mutex<Receiver<proc(): Send>>>) {
|
||||
spawn(proc() {
|
||||
// Will spawn a new task on panic unless it is cancelled.
|
||||
let sentinel = Sentinel::new(&jobs);
|
||||
|
||||
let task_body = proc() {
|
||||
let local_data = init_fn(i);
|
||||
loop {
|
||||
match rx.recv() {
|
||||
Execute(f) => f(&local_data),
|
||||
Quit => break
|
||||
}
|
||||
}
|
||||
let message = {
|
||||
// Only lock jobs for the time it takes
|
||||
// to get a job, not run it.
|
||||
let lock = jobs.lock();
|
||||
lock.recv_opt()
|
||||
};
|
||||
|
||||
// Run on this scheduler.
|
||||
task::spawn(task_body);
|
||||
match message {
|
||||
Ok(job) => job(),
|
||||
|
||||
tx
|
||||
});
|
||||
|
||||
return TaskPool {
|
||||
channels: channels,
|
||||
next_index: 0,
|
||||
};
|
||||
}
|
||||
|
||||
/// Executes the function `f` on a task in the pool. The function
|
||||
/// receives a reference to the local data returned by the `init_fn`.
|
||||
pub fn execute(&mut self, f: proc(&T):Send) {
|
||||
self.channels[self.next_index].send(Execute(f));
|
||||
self.next_index += 1;
|
||||
if self.next_index == self.channels.len() { self.next_index = 0; }
|
||||
// The Taskpool was dropped.
|
||||
Err(..) => break
|
||||
}
|
||||
}
|
||||
|
||||
sentinel.cancel();
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::prelude::*;
|
||||
use super::*;
|
||||
use comm::channel;
|
||||
use iter::range;
|
||||
|
||||
const TEST_TASKS: uint = 4u;
|
||||
|
||||
#[test]
|
||||
fn test_task_pool() {
|
||||
let f: || -> proc(uint):Send -> uint = || { proc(i) i };
|
||||
let mut pool = TaskPool::new(4, f);
|
||||
for _ in range(0u, 8) {
|
||||
pool.execute(proc(i) println!("Hello from thread {}!", *i));
|
||||
fn test_works() {
|
||||
use iter::AdditiveIterator;
|
||||
|
||||
let pool = TaskPool::new(TEST_TASKS);
|
||||
|
||||
let (tx, rx) = channel();
|
||||
for _ in range(0, TEST_TASKS) {
|
||||
let tx = tx.clone();
|
||||
pool.execute(proc() {
|
||||
tx.send(1u);
|
||||
});
|
||||
}
|
||||
|
||||
assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_zero_tasks_panic() {
|
||||
let f: || -> proc(uint):Send -> uint = || { proc(i) i };
|
||||
TaskPool::new(0, f);
|
||||
TaskPool::new(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recovery_from_subtask_panic() {
|
||||
use iter::AdditiveIterator;
|
||||
|
||||
let pool = TaskPool::new(TEST_TASKS);
|
||||
|
||||
// Panic all the existing tasks.
|
||||
for _ in range(0, TEST_TASKS) {
|
||||
pool.execute(proc() { panic!() });
|
||||
}
|
||||
|
||||
// Ensure new tasks were spawned to compensate.
|
||||
let (tx, rx) = channel();
|
||||
for _ in range(0, TEST_TASKS) {
|
||||
let tx = tx.clone();
|
||||
pool.execute(proc() {
|
||||
tx.send(1u);
|
||||
});
|
||||
}
|
||||
|
||||
assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
|
||||
use sync::{Arc, Barrier};
|
||||
|
||||
let pool = TaskPool::new(TEST_TASKS);
|
||||
let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));
|
||||
|
||||
// Panic all the existing tasks in a bit.
|
||||
for _ in range(0, TEST_TASKS) {
|
||||
let waiter = waiter.clone();
|
||||
pool.execute(proc() {
|
||||
waiter.wait();
|
||||
panic!();
|
||||
});
|
||||
}
|
||||
|
||||
drop(pool);
|
||||
|
||||
// Kick off the failure.
|
||||
waiter.wait();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,9 +105,8 @@ use rt::local::Local;
|
|||
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() {
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
// 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());
|
||||
}
|
||||
}
|
|
@ -22,19 +22,23 @@
|
|||
//! would generate two implementations like:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! impl<S:serialize::Encoder> Encodable<S> for Node {
|
||||
//! fn encode(&self, s: &S) {
|
||||
//! s.emit_struct("Node", 1, || {
|
||||
//! s.emit_field("id", 0, || s.emit_uint(self.id))
|
||||
//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
|
||||
//! fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
//! s.emit_struct("Node", 1, |this| {
|
||||
//! this.emit_struct_field("id", 0, |this| {
|
||||
//! Encodable::encode(&self.id, this)
|
||||
//! /* this.emit_uint(self.id) can also be used */
|
||||
//! })
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<D:Decoder> Decodable for node_id {
|
||||
//! fn decode(d: &D) -> Node {
|
||||
//! d.read_struct("Node", 1, || {
|
||||
//! Node {
|
||||
//! id: d.read_field("x".to_string(), 0, || decode(d))
|
||||
//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
|
||||
//! fn decode(d: &mut D) -> Result<Node, E> {
|
||||
//! d.read_struct("Node", 1, |this| {
|
||||
//! match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
|
||||
//! Ok(id) => Ok(Node { id: id }),
|
||||
//! Err(e) => Err(e),
|
||||
//! }
|
||||
//! })
|
||||
//! }
|
||||
|
@ -46,34 +50,39 @@
|
|||
//!
|
||||
//! ```ignore
|
||||
//! #[deriving(Encodable, Decodable)]
|
||||
//! struct spanned<T> { node: T, span: Span }
|
||||
//! struct Spanned<T> { node: T, span: Span }
|
||||
//! ```
|
||||
//!
|
||||
//! would yield functions like:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! impl<
|
||||
//! S: Encoder,
|
||||
//! T: Encodable<S>
|
||||
//! > spanned<T>: Encodable<S> {
|
||||
//! fn encode<S:Encoder>(s: &S) {
|
||||
//! s.emit_rec(|| {
|
||||
//! s.emit_field("node", 0, || self.node.encode(s));
|
||||
//! s.emit_field("span", 1, || self.span.encode(s));
|
||||
//! S: Encoder<E>,
|
||||
//! E,
|
||||
//! T: Encodable<S, E>
|
||||
//! > Encodable<S, E> for Spanned<T> {
|
||||
//! fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
//! s.emit_struct("Spanned", 2, |this| {
|
||||
//! this.emit_struct_field("node", 0, |this| self.node.encode(this))
|
||||
//! .ok().unwrap();
|
||||
//! this.emit_struct_field("span", 1, |this| self.span.encode(this))
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<
|
||||
//! D: Decoder,
|
||||
//! T: Decodable<D>
|
||||
//! > spanned<T>: Decodable<D> {
|
||||
//! fn decode(d: &D) -> spanned<T> {
|
||||
//! d.read_rec(|| {
|
||||
//! {
|
||||
//! node: d.read_field("node".to_string(), 0, || decode(d)),
|
||||
//! span: d.read_field("span".to_string(), 1, || decode(d)),
|
||||
//! }
|
||||
//! D: Decoder<E>,
|
||||
//! E,
|
||||
//! T: Decodable<D, E>
|
||||
//! > Decodable<D, E> for Spanned<T> {
|
||||
//! fn decode(d: &mut D) -> Result<Spanned<T>, E> {
|
||||
//! d.read_struct("Spanned", 2, |this| {
|
||||
//! Ok(Spanned {
|
||||
//! node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
|
||||
//! .ok().unwrap(),
|
||||
//! span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
|
||||
//! .ok().unwrap(),
|
||||
//! })
|
||||
//! })
|
||||
//! }
|
||||
//! }
|
||||
|
|
|
@ -53,13 +53,13 @@ use std::cmp;
|
|||
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;
|
||||
|
|
24
src/test/run-make/codegen-options-parsing/Makefile
Normal file
24
src/test/run-make/codegen-options-parsing/Makefile
Normal file
|
@ -0,0 +1,24 @@
|
|||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
#Option taking a number
|
||||
$(RUSTC) -C codegen-units dummy.rs 2>&1 | \
|
||||
grep 'codegen option `codegen-units` requires a number'
|
||||
$(RUSTC) -C codegen-units= dummy.rs 2>&1 | \
|
||||
grep 'incorrect value `` for codegen option `codegen-units` - a number was expected'
|
||||
$(RUSTC) -C codegen-units=foo dummy.rs 2>&1 | \
|
||||
grep 'incorrect value `foo` for codegen option `codegen-units` - a number was expected'
|
||||
$(RUSTC) -C codegen-units=1 dummy.rs
|
||||
#Option taking a string
|
||||
$(RUSTC) -C extra-filename dummy.rs 2>&1 | \
|
||||
grep 'codegen option `extra-filename` requires a string'
|
||||
$(RUSTC) -C extra-filename= dummy.rs 2>&1
|
||||
$(RUSTC) -C extra-filename=foo dummy.rs 2>&1
|
||||
#Option taking no argument
|
||||
$(RUSTC) -C lto= dummy.rs 2>&1 | \
|
||||
grep 'codegen option `lto` takes no value'
|
||||
$(RUSTC) -C lto=1 dummy.rs 2>&1 | \
|
||||
grep 'codegen option `lto` takes no value'
|
||||
$(RUSTC) -C lto=foo dummy.rs 2>&1 | \
|
||||
grep 'codegen option `lto` takes no value'
|
||||
$(RUSTC) -C lto dummy.rs
|
11
src/test/run-make/codegen-options-parsing/dummy.rs
Normal file
11
src/test/run-make/codegen-options-parsing/dummy.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
fn main() {}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue