Auto merge of #24433 - alexcrichton:rollup, r=alexcrichton
This commit is contained in:
commit
16e1fcead1
|
@ -12,16 +12,16 @@
|
|||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(old_io)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(std_misc)]
|
||||
#![feature(test)]
|
||||
#![feature(path_ext)]
|
||||
#![feature(str_char)]
|
||||
#![feature(libc)]
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
extern crate libc;
|
||||
extern crate test;
|
||||
extern crate getopts;
|
||||
|
||||
|
@ -42,6 +42,7 @@ pub mod header;
|
|||
pub mod runtest;
|
||||
pub mod common;
|
||||
pub mod errors;
|
||||
mod raise_fd_limit;
|
||||
|
||||
pub fn main() {
|
||||
let config = parse_config(env::args().collect());
|
||||
|
@ -245,11 +246,7 @@ pub fn run_tests(config: &Config) {
|
|||
// sadly osx needs some file descriptor limits raised for running tests in
|
||||
// parallel (especially when we have lots and lots of child processes).
|
||||
// For context, see #8904
|
||||
#[allow(deprecated)]
|
||||
fn raise_fd_limit() {
|
||||
std::old_io::test::raise_fd_limit();
|
||||
}
|
||||
raise_fd_limit();
|
||||
unsafe { raise_fd_limit::raise_fd_limit(); }
|
||||
// Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
|
||||
// If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
|
||||
env::set_var("__COMPAT_LAYER", "RunAsInvoker");
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
/// darwin_fd_limit exists to work around an issue where launchctl on Mac OS X
|
||||
/// defaults the rlimit maxfiles to 256/unlimited. The default soft limit of 256
|
||||
/// ends up being far too low for our multithreaded scheduler testing, depending
|
||||
/// on the number of cores available.
|
||||
///
|
||||
/// This fixes issue #7772.
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub unsafe fn raise_fd_limit() {
|
||||
use libc;
|
||||
use std::cmp;
|
||||
use std::io;
|
||||
use std::mem::size_of_val;
|
||||
use std::ptr::null_mut;
|
||||
|
||||
type rlim_t = libc::uint64_t;
|
||||
|
||||
#[repr(C)]
|
||||
struct rlimit {
|
||||
rlim_cur: rlim_t,
|
||||
rlim_max: rlim_t
|
||||
}
|
||||
extern {
|
||||
// name probably doesn't need to be mut, but the C function doesn't
|
||||
// specify const
|
||||
fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
|
||||
oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
|
||||
newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
|
||||
fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
|
||||
fn setrlimit(resource: libc::c_int, rlp: *const rlimit) -> libc::c_int;
|
||||
}
|
||||
static CTL_KERN: libc::c_int = 1;
|
||||
static KERN_MAXFILESPERPROC: libc::c_int = 29;
|
||||
static RLIMIT_NOFILE: libc::c_int = 8;
|
||||
|
||||
// The strategy here is to fetch the current resource limits, read the
|
||||
// kern.maxfilesperproc sysctl value, and bump the soft resource limit for
|
||||
// maxfiles up to the sysctl value.
|
||||
|
||||
// Fetch the kern.maxfilesperproc value
|
||||
let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
|
||||
let mut maxfiles: libc::c_int = 0;
|
||||
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
|
||||
if sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size,
|
||||
null_mut(), 0) != 0 {
|
||||
let err = io::Error::last_os_error();
|
||||
panic!("raise_fd_limit: error calling sysctl: {}", err);
|
||||
}
|
||||
|
||||
// Fetch the current resource limits
|
||||
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
|
||||
if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
|
||||
let err = io::Error::last_os_error();
|
||||
panic!("raise_fd_limit: error calling getrlimit: {}", err);
|
||||
}
|
||||
|
||||
// Bump the soft limit to the smaller of kern.maxfilesperproc and the hard
|
||||
// limit
|
||||
rlim.rlim_cur = cmp::min(maxfiles as rlim_t, rlim.rlim_max);
|
||||
|
||||
// Set our newly-increased resource limit
|
||||
if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
|
||||
let err = io::Error::last_os_error();
|
||||
panic!("raise_fd_limit: error calling setrlimit: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
|
||||
pub unsafe fn raise_fd_limit() {}
|
|
@ -29,7 +29,6 @@ use std::net::TcpStream;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Output, ExitStatus};
|
||||
use std::str;
|
||||
use std::time::Duration;
|
||||
use test::MetricMap;
|
||||
|
||||
pub fn run(config: Config, testfile: &Path) {
|
||||
|
@ -452,11 +451,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||
.expect(&format!("failed to exec `{:?}`", config.adb_path));
|
||||
loop {
|
||||
//waiting 1 second for gdbserver start
|
||||
#[allow(deprecated)]
|
||||
fn sleep() {
|
||||
::std::old_io::timer::sleep(Duration::milliseconds(1000));
|
||||
}
|
||||
sleep();
|
||||
::std::thread::sleep_ms(1000);
|
||||
if TcpStream::connect("127.0.0.1:5039").is_ok() {
|
||||
break
|
||||
}
|
||||
|
|
|
@ -15,6 +15,12 @@ Rust, its syntax, and its concepts. Upon completing the book, you'll be an
|
|||
intermediate Rust developer, and will have a good grasp of the fundamental
|
||||
ideas behind Rust.
|
||||
|
||||
[Rust By Example][rbe] was originally a community resource, but was then
|
||||
donated to the Rust project. As the name implies, it teaches you Rust through a
|
||||
series of small examples.
|
||||
|
||||
[rbe]: rustbyexample.com
|
||||
|
||||
# Community & Getting Help
|
||||
|
||||
If you need help with something, or just want to talk about Rust with others,
|
||||
|
@ -76,17 +82,3 @@ We have [API documentation for the entire standard
|
|||
library](std/index.html). There's a list of crates on the left with more
|
||||
specific sections, or you can use the search bar at the top to search for
|
||||
something if you know its name.
|
||||
|
||||
# External documentation
|
||||
|
||||
*Note: While these are great resources for learning Rust, they may track a
|
||||
particular version of Rust that is likely not exactly the same as that for
|
||||
which this documentation was generated.*
|
||||
|
||||
* [Rust by Example] - Short examples of common tasks in Rust (tracks the master
|
||||
branch).
|
||||
* [Rust for Rubyists] - The first community tutorial for Rust. Tracks the last
|
||||
stable release. Not just for Ruby programmers.
|
||||
|
||||
[Rust by Example]: http://rustbyexample.com/
|
||||
[Rust for Rubyists]: http://www.rustforrubyists.com/
|
||||
|
|
|
@ -389,6 +389,7 @@ safe concurrent programs.
|
|||
Here's an example of a concurrent Rust program:
|
||||
|
||||
```{rust}
|
||||
# #![feature(scoped)]
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
|
@ -421,6 +422,7 @@ problem.
|
|||
Let's see an example. This Rust code will not compile:
|
||||
|
||||
```{rust,ignore}
|
||||
# #![feature(scoped)]
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
|
@ -467,6 +469,7 @@ that our mutation doesn't cause a data race.
|
|||
Here's what using a Mutex looks like:
|
||||
|
||||
```{rust}
|
||||
# #![feature(scoped)]
|
||||
use std::thread;
|
||||
use std::sync::Mutex;
|
||||
|
||||
|
@ -527,6 +530,7 @@ As an example, Rust's ownership system is _entirely_ at compile time. The
|
|||
safety check that makes this an error about moved values:
|
||||
|
||||
```{rust,ignore}
|
||||
# #![feature(scoped)]
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,47 +1,45 @@
|
|||
% Comments
|
||||
|
||||
Now that we have some functions, it's a good idea to learn about comments.
|
||||
Now that we have some functions, it’s a good idea to learn about comments.
|
||||
Comments are notes that you leave to other programmers to help explain things
|
||||
about your code. The compiler mostly ignores them.
|
||||
|
||||
Rust has two kinds of comments that you should care about: *line comments*
|
||||
and *doc comments*.
|
||||
|
||||
```{rust}
|
||||
// Line comments are anything after '//' and extend to the end of the line.
|
||||
```rust
|
||||
// Line comments are anything after ‘//’ and extend to the end of the line.
|
||||
|
||||
let x = 5; // this is also a line comment.
|
||||
|
||||
// If you have a long explanation for something, you can put line comments next
|
||||
// to each other. Put a space between the // and your comment so that it's
|
||||
// to each other. Put a space between the // and your comment so that it’s
|
||||
// more readable.
|
||||
```
|
||||
|
||||
The other kind of comment is a doc comment. Doc comments use `///` instead of
|
||||
`//`, and support Markdown notation inside:
|
||||
|
||||
```{rust}
|
||||
/// `hello` is a function that prints a greeting that is personalized based on
|
||||
/// the name given.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name` - The name of the person you'd like to greet.
|
||||
```rust
|
||||
/// Adds one to the number given.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// let name = "Steve";
|
||||
/// hello(name); // prints "Hello, Steve!"
|
||||
/// ```
|
||||
fn hello(name: &str) {
|
||||
println!("Hello, {}!", name);
|
||||
/// let five = 5;
|
||||
///
|
||||
/// assert_eq!(6, add_one(5));
|
||||
/// ```
|
||||
fn add_one(x: i32) -> i32 {
|
||||
x + 1
|
||||
}
|
||||
```
|
||||
|
||||
When writing doc comments, adding sections for any arguments, return values,
|
||||
and providing some examples of usage is very, very helpful. Don't worry about
|
||||
the `&str`, we'll get to it soon.
|
||||
When writing doc comments, providing some examples of usage is very, very
|
||||
helpful. You’ll notice we’ve used a new macro here: `assert_eq!`. This compares
|
||||
two values, and `panic!`s if they’re not equal to each other. It’s very helpful
|
||||
in documentation. There’s another macro, `assert!`, which `panic!`s if the
|
||||
value passed to it is `false`.
|
||||
|
||||
You can use the [`rustdoc`](documentation.html) tool to generate HTML documentation
|
||||
from these doc comments.
|
||||
from these doc comments, and also to run the code examples as tests!
|
||||
|
|
|
@ -56,67 +56,34 @@ place!
|
|||
|
||||
## Threads
|
||||
|
||||
Rust's standard library provides a library for 'threads', which allow you to
|
||||
Rust's standard library provides a library for threads, which allow you to
|
||||
run Rust code in parallel. Here's a basic example of using `std::thread`:
|
||||
|
||||
```
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
thread::scoped(|| {
|
||||
println!("Hello from a thread!");
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
The `thread::scoped()` method accepts a closure, which is executed in a new
|
||||
thread. It's called `scoped` because this thread returns a join guard:
|
||||
|
||||
```
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
let guard = thread::scoped(|| {
|
||||
println!("Hello from a thread!");
|
||||
});
|
||||
|
||||
// guard goes out of scope here
|
||||
}
|
||||
```
|
||||
|
||||
When `guard` goes out of scope, it will block execution until the thread is
|
||||
finished. If we didn't want this behaviour, we could use `thread::spawn()`:
|
||||
|
||||
```
|
||||
use std::thread;
|
||||
|
||||
fn main() {
|
||||
thread::spawn(|| {
|
||||
println!("Hello from a thread!");
|
||||
});
|
||||
|
||||
thread::sleep_ms(50);
|
||||
}
|
||||
```
|
||||
|
||||
We need to `sleep` here because when `main()` ends, it kills all of the
|
||||
running threads.
|
||||
The `thread::spawn()` method accepts a closure, which is executed in a
|
||||
new thread. It returns a handle to the thread, that can be used to
|
||||
wait for the child thread to finish and extract its result:
|
||||
|
||||
[`scoped`](std/thread/struct.Builder.html#method.scoped) has an interesting
|
||||
type signature:
|
||||
|
||||
```text
|
||||
fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T>
|
||||
where T: Send + 'a,
|
||||
F: FnOnce() -> T,
|
||||
F: Send + 'a
|
||||
```
|
||||
use std::thread;
|
||||
|
||||
Specifically, `F`, the closure that we pass to execute in the new thread. It
|
||||
has two restrictions: It must be a `FnOnce` from `()` to `T`. Using `FnOnce`
|
||||
allows the closure to take ownership of any data it mentions from the parent
|
||||
thread. The other restriction is that `F` must be `Send`. We aren't allowed to
|
||||
transfer this ownership unless the type thinks that's okay.
|
||||
fn main() {
|
||||
let handle = thread::spawn(|| {
|
||||
"Hello from a thread!"
|
||||
});
|
||||
|
||||
println!("{}", handle.join().unwrap());
|
||||
}
|
||||
```
|
||||
|
||||
Many languages have the ability to execute threads, but it's wildly unsafe.
|
||||
There are entire books about how to prevent errors that occur from shared
|
||||
|
|
|
@ -143,7 +143,5 @@ matching, a tool that will let us deconstruct sum types (the type theory term
|
|||
for enums) like `Ordering` in a very elegant way that avoids all these messy
|
||||
and brittle `if`/`else`s.
|
||||
|
||||
|
||||
[arity]: ./glossary.html#arity
|
||||
[match]: ./match.html
|
||||
[generics]: ./generics.html
|
||||
|
|
|
@ -297,5 +297,5 @@ It's worth noting that you can only use `try!` from a function that returns a
|
|||
`Result`, which means that you cannot use `try!` inside of `main()`, because
|
||||
`main()` doesn't return anything.
|
||||
|
||||
`try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine
|
||||
`try!` makes use of [`From<Error>`](../std/convert/trait.From.hml) to determine
|
||||
what to return in the error case.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
% Functions
|
||||
|
||||
You've already seen one function so far, the `main` function:
|
||||
Every Rust program has at least one function, the `main` function:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
|
@ -8,16 +8,16 @@ fn main() {
|
|||
```
|
||||
|
||||
This is the simplest possible function declaration. As we mentioned before,
|
||||
`fn` says "this is a function," followed by the name, some parentheses because
|
||||
`fn` says ‘this is a function’, followed by the name, some parentheses because
|
||||
this function takes no arguments, and then some curly braces to indicate the
|
||||
body. Here's a function named `foo`:
|
||||
body. Here’s a function named `foo`:
|
||||
|
||||
```rust
|
||||
fn foo() {
|
||||
}
|
||||
```
|
||||
|
||||
So, what about taking arguments? Here's a function that prints a number:
|
||||
So, what about taking arguments? Here’s a function that prints a number:
|
||||
|
||||
```rust
|
||||
fn print_number(x: i32) {
|
||||
|
@ -25,7 +25,7 @@ fn print_number(x: i32) {
|
|||
}
|
||||
```
|
||||
|
||||
Here's a complete program that uses `print_number`:
|
||||
Here’s a complete program that uses `print_number`:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
|
@ -40,7 +40,7 @@ fn print_number(x: i32) {
|
|||
As you can see, function arguments work very similar to `let` declarations:
|
||||
you add a type to the argument name, after a colon.
|
||||
|
||||
Here's a complete program that adds two numbers together and prints them:
|
||||
Here’s a complete program that adds two numbers together and prints them:
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
|
@ -58,7 +58,7 @@ as when you declare it.
|
|||
Unlike `let`, you _must_ declare the types of function arguments. This does
|
||||
not work:
|
||||
|
||||
```{rust,ignore}
|
||||
```rust,ignore
|
||||
fn print_sum(x, y) {
|
||||
println!("sum is: {}", x + y);
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ fn print_sum(x, y) {
|
|||
You get this error:
|
||||
|
||||
```text
|
||||
hello.rs:5:18: 5:19 expected one of `!`, `:`, or `@`, found `)`
|
||||
hello.rs:5 fn print_number(x, y) {
|
||||
expected one of `!`, `:`, or `@`, found `)`
|
||||
fn print_number(x, y) {
|
||||
```
|
||||
|
||||
This is a deliberate design decision. While full-program inference is possible,
|
||||
|
@ -77,7 +77,7 @@ types explicitly is a best-practice. We agree that forcing functions to declare
|
|||
types while allowing for inference inside of function bodies is a wonderful
|
||||
sweet spot between full inference and no inference.
|
||||
|
||||
What about returning a value? Here's a function that adds one to an integer:
|
||||
What about returning a value? Here’s a function that adds one to an integer:
|
||||
|
||||
```rust
|
||||
fn add_one(x: i32) -> i32 {
|
||||
|
@ -86,11 +86,11 @@ fn add_one(x: i32) -> i32 {
|
|||
```
|
||||
|
||||
Rust functions return exactly one value, and you declare the type after an
|
||||
"arrow," which is a dash (`-`) followed by a greater-than sign (`>`).
|
||||
‘arrow’, which is a dash (`-`) followed by a greater-than sign (`>`). The last
|
||||
line of a function determines what it returns. You’ll note the lack of a
|
||||
semicolon here. If we added it in:
|
||||
|
||||
You'll note the lack of a semicolon here. If we added it in:
|
||||
|
||||
```{rust,ignore}
|
||||
```rust,ignore
|
||||
fn add_one(x: i32) -> i32 {
|
||||
x + 1;
|
||||
}
|
||||
|
@ -109,24 +109,79 @@ help: consider removing this semicolon:
|
|||
^
|
||||
```
|
||||
|
||||
Remember our earlier discussions about semicolons and `()`? Our function claims
|
||||
to return an `i32`, but with a semicolon, it would return `()` instead. Rust
|
||||
realizes this probably isn't what we want, and suggests removing the semicolon.
|
||||
This reveals two interesting things about Rust: it is an expression-based
|
||||
language, and semicolons are different from semicolons in other ‘curly brace
|
||||
and semicolon’-based languages. These two things are related.
|
||||
|
||||
This is very much like our `if` statement before: the result of the block
|
||||
(`{}`) is the value of the expression. Other expression-oriented languages,
|
||||
such as Ruby, work like this, but it's a bit unusual in the systems programming
|
||||
world. When people first learn about this, they usually assume that it
|
||||
introduces bugs. But because Rust's type system is so strong, and because unit
|
||||
is its own unique type, we have never seen an issue where adding or removing a
|
||||
semicolon in a return position would cause a bug.
|
||||
## Expressions vs. Statements
|
||||
|
||||
Rust is primarily an expression-based language. There are only two kinds of
|
||||
statements, and everything else is an expression.
|
||||
|
||||
So what's the difference? Expressions return a value, and statements do not.
|
||||
That’s why we end up with ‘not all control paths return a value’ here: the
|
||||
statement `x + 1;` doesn’t return a value. There are two kinds of statements in
|
||||
Rust: ‘declaration statements’ and ‘expression statements’. Everything else is
|
||||
an expression. Let’s talk about declaration statements first.
|
||||
|
||||
In some languages, variable bindings can be written as expressions, not just
|
||||
statements. Like Ruby:
|
||||
|
||||
```ruby
|
||||
x = y = 5
|
||||
```
|
||||
|
||||
In Rust, however, using `let` to introduce a binding is _not_ an expression. The
|
||||
following will produce a compile-time error:
|
||||
|
||||
```ignore
|
||||
let x = (let y = 5); // expected identifier, found keyword `let`
|
||||
```
|
||||
|
||||
The compiler is telling us here that it was expecting to see the beginning of
|
||||
an expression, and a `let` can only begin a statement, not an expression.
|
||||
|
||||
Note that assigning to an already-bound variable (e.g. `y = 5`) is still an
|
||||
expression, although its value is not particularly useful. Unlike other
|
||||
languages where an assignment evaluates to the assigned value (e.g. `5` in the
|
||||
previous example), in Rust the value of an assignment is an empty tuple `()`:
|
||||
|
||||
```
|
||||
let mut y = 5;
|
||||
|
||||
let x = (y = 6); // x has the value `()`, not `6`
|
||||
```
|
||||
|
||||
The second kind of statement in Rust is the *expression statement*. Its
|
||||
purpose is to turn any expression into a statement. In practical terms, Rust's
|
||||
grammar expects statements to follow other statements. This means that you use
|
||||
semicolons to separate expressions from each other. This means that Rust
|
||||
looks a lot like most other languages that require you to use semicolons
|
||||
at the end of every line, and you will see semicolons at the end of almost
|
||||
every line of Rust code you see.
|
||||
|
||||
What is this exception that makes us say "almost"? You saw it already, in this
|
||||
code:
|
||||
|
||||
```rust
|
||||
fn add_one(x: i32) -> i32 {
|
||||
x + 1
|
||||
}
|
||||
```
|
||||
|
||||
Our function claims to return an `i32`, but with a semicolon, it would return
|
||||
`()` instead. Rust realizes this probably isn’t what we want, and suggests
|
||||
removing the semicolon in the error we saw before.
|
||||
|
||||
## Early returns
|
||||
|
||||
But what about early returns? Rust does have a keyword for that, `return`:
|
||||
|
||||
```rust
|
||||
fn foo(x: i32) -> i32 {
|
||||
if x < 5 { return x; }
|
||||
return x;
|
||||
|
||||
// we never run this code!
|
||||
x + 1
|
||||
}
|
||||
```
|
||||
|
@ -136,33 +191,17 @@ style:
|
|||
|
||||
```rust
|
||||
fn foo(x: i32) -> i32 {
|
||||
if x < 5 { return x; }
|
||||
|
||||
return x + 1;
|
||||
}
|
||||
```
|
||||
|
||||
The previous definition without `return` may look a bit strange if you haven't
|
||||
The previous definition without `return` may look a bit strange if you haven’t
|
||||
worked in an expression-based language before, but it becomes intuitive over
|
||||
time. If this were production code, we wouldn't write it in that way anyway,
|
||||
we'd write this:
|
||||
|
||||
```rust
|
||||
fn foo(x: i32) -> i32 {
|
||||
if x < 5 {
|
||||
x
|
||||
} else {
|
||||
x + 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Because `if` is an expression, and it's the only expression in this function,
|
||||
the value will be the result of the `if`.
|
||||
time.
|
||||
|
||||
## Diverging functions
|
||||
|
||||
Rust has some special syntax for 'diverging functions', which are functions that
|
||||
Rust has some special syntax for ‘diverging functions’, which are functions that
|
||||
do not return:
|
||||
|
||||
```
|
||||
|
@ -171,23 +210,18 @@ fn diverges() -> ! {
|
|||
}
|
||||
```
|
||||
|
||||
`panic!` is a macro, similar to `println!()` that we've already seen. Unlike
|
||||
`panic!` is a macro, similar to `println!()` that we’ve already seen. Unlike
|
||||
`println!()`, `panic!()` causes the current thread of execution to crash with
|
||||
the given message.
|
||||
|
||||
Because this function will cause a crash, it will never return, and so it has
|
||||
the type '`!`', which is read "diverges." A diverging function can be used
|
||||
the type ‘`!`’, which is read ‘diverges’. A diverging function can be used
|
||||
as any type:
|
||||
|
||||
```should_panic
|
||||
# fn diverges() -> ! {
|
||||
# panic!("This function never returns!");
|
||||
# }
|
||||
|
||||
let x: i32 = diverges();
|
||||
let x: String = diverges();
|
||||
```
|
||||
|
||||
We don't have a good use for diverging functions yet, because they're used in
|
||||
conjunction with other Rust features. But when you see `-> !` later, you'll
|
||||
know what it's called.
|
||||
|
|
|
@ -18,7 +18,7 @@ use a two-step version of the installation and examine our installation script:
|
|||
|
||||
```bash
|
||||
$ curl -f -L https://static.rust-lang.org/rustup.sh -O
|
||||
$ sudo sh rustup.sh
|
||||
$ sudo sh rustup.sh --channel=nightly
|
||||
```
|
||||
|
||||
[insecurity]: http://curlpipesh.tumblr.com
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
% Structs
|
||||
|
||||
A struct is another form of a *record type*, just like a tuple. There's a
|
||||
difference: structs give each element that they contain a name, called a
|
||||
*field* or a *member*. Check it out:
|
||||
Structs are a way of creating more complex datatypes. For example, if we were
|
||||
doing calculations involving coordinates in 2D space, we would need both an `x`
|
||||
and a `y` value:
|
||||
|
||||
```rust
|
||||
let origin_x = 0;
|
||||
let origin_y = 0;
|
||||
```
|
||||
|
||||
A struct lets us combine these two into a single, unified datatype:
|
||||
|
||||
```rust
|
||||
struct Point {
|
||||
|
@ -17,7 +24,7 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
There's a lot going on here, so let's break it down. We declare a struct with
|
||||
There’s a lot going on here, so let’s break it down. We declare a struct with
|
||||
the `struct` keyword, and then with a name. By convention, structs begin with a
|
||||
capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
|
||||
|
||||
|
@ -31,7 +38,7 @@ notation: `origin.x`.
|
|||
The values in structs are immutable by default, like other bindings in Rust.
|
||||
Use `mut` to make them mutable:
|
||||
|
||||
```{rust}
|
||||
```rust
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
|
@ -47,3 +54,36 @@ fn main() {
|
|||
```
|
||||
|
||||
This will print `The point is at (5, 0)`.
|
||||
|
||||
Rust does not support field mutability at the language level, so you cannot
|
||||
write something like this:
|
||||
|
||||
```rust,ignore
|
||||
struct Point {
|
||||
mut x: i32,
|
||||
y: i32,
|
||||
}
|
||||
```
|
||||
|
||||
Mutability is a property of the binding, not of the structure itself. If you’re
|
||||
used to field-level mutability, this may seem strange at first, but it
|
||||
significantly simplifies things. It even lets you make things mutable for a short
|
||||
time only:
|
||||
|
||||
|
||||
```rust,ignore
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut point = Point { x: 0, y: 0 };
|
||||
|
||||
point.x = 5;
|
||||
|
||||
let point = point; // this new binding can’t change now
|
||||
|
||||
point.y = 6; // this causes an error
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
% Vectors
|
||||
|
||||
A *vector* is a dynamic or "growable" array, implemented as the standard
|
||||
library type [`Vec<T>`](../std/vec/) (we'll talk about what the `<T>` means
|
||||
later). Vectors always allocate their data on the heap. Vectors are to slices
|
||||
library type [`Vec<T>`](../std/vec/) (Where `<T>` is a [Generic](./generics.md) statement). Vectors always allocate their data on the heap. Vectors are to slices
|
||||
what `String` is to `&str`. You can create them with the `vec!` macro:
|
||||
|
||||
```{rust}
|
||||
|
|
|
@ -923,7 +923,7 @@ impl BitVec {
|
|||
self.set(insert_pos, elem);
|
||||
}
|
||||
|
||||
/// Return the total number of bits in this vector
|
||||
/// Returns the total number of bits in this vector
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn len(&self) -> usize { self.nbits }
|
||||
|
@ -1695,7 +1695,7 @@ impl BitSet {
|
|||
self.other_op(other, |w1, w2| w1 ^ w2);
|
||||
}
|
||||
|
||||
/// Return the number of set bits in this set.
|
||||
/// Returns the number of set bits in this set.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn len(&self) -> usize {
|
||||
|
|
|
@ -1339,7 +1339,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||
Values { inner: self.iter().map(second) }
|
||||
}
|
||||
|
||||
/// Return the number of elements in the map.
|
||||
/// Returns the number of elements in the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -1354,7 +1354,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn len(&self) -> usize { self.length }
|
||||
|
||||
/// Return true if the map contains no elements.
|
||||
/// Returns true if the map contains no elements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -284,7 +284,7 @@ impl<T: Ord> BTreeSet<T> {
|
|||
Union{a: self.iter().peekable(), b: other.iter().peekable()}
|
||||
}
|
||||
|
||||
/// Return the number of elements in the set
|
||||
/// Returns the number of elements in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -299,7 +299,7 @@ impl<T: Ord> BTreeSet<T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn len(&self) -> usize { self.map.len() }
|
||||
|
||||
/// Returns true if the set contains no elements
|
||||
/// Returns true if the set contains no elements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#![feature(str_char)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(debug_builders)]
|
||||
#![feature(utf8_error)]
|
||||
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
|
||||
#![cfg_attr(test, allow(deprecated))] // rand
|
||||
|
||||
|
|
|
@ -943,7 +943,7 @@ mod test {
|
|||
use std::clone::Clone;
|
||||
use std::iter::Iterator;
|
||||
use std::option::Option::{Some, None, self};
|
||||
use std::rand;
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
use std::thread;
|
||||
use std::vec::Vec;
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ mod test {
|
|||
let mut v = vec![];
|
||||
for i in 0..sz {
|
||||
check_links(&m);
|
||||
let r: u8 = rand::random();
|
||||
let r: u8 = thread_rng().next_u32() as u8;
|
||||
match r % 6 {
|
||||
0 => {
|
||||
m.pop_back();
|
||||
|
|
|
@ -549,7 +549,7 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::binary_search_by(self, f)
|
||||
}
|
||||
|
||||
/// Return the number of elements in the slice
|
||||
/// Returns the number of elements in the slice.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -757,7 +757,7 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::get_unchecked_mut(self, index)
|
||||
}
|
||||
|
||||
/// Return an unsafe mutable pointer to the slice's buffer.
|
||||
/// Returns an unsafe mutable pointer to the slice's buffer.
|
||||
///
|
||||
/// The caller must ensure that the slice outlives the pointer this
|
||||
/// function returns, or else it will end up pointing to garbage.
|
||||
|
@ -984,7 +984,7 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::ends_with(self, needle)
|
||||
}
|
||||
|
||||
/// Convert `self` into a vector without clones or allocation.
|
||||
/// Converts `self` into a vector without clones or allocation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn into_vec(self: Box<Self>) -> Vec<T> {
|
||||
|
|
|
@ -1248,7 +1248,7 @@ impl str {
|
|||
core_str::StrExt::trim_right_matches(&self[..], pat)
|
||||
}
|
||||
|
||||
/// Check that `index`-th byte lies at the start and/or end of a
|
||||
/// Checks that `index`-th byte lies at the start and/or end of a
|
||||
/// UTF-8 code point sequence.
|
||||
///
|
||||
/// The start and end of the string (when `index == self.len()`) are
|
||||
|
@ -1435,7 +1435,7 @@ impl str {
|
|||
core_str::StrExt::char_at_reverse(&self[..], i)
|
||||
}
|
||||
|
||||
/// Convert `self` to a byte slice.
|
||||
/// Converts `self` to a byte slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -1591,7 +1591,7 @@ impl str {
|
|||
core_str::StrExt::subslice_offset(&self[..], inner)
|
||||
}
|
||||
|
||||
/// Return an unsafe pointer to the `&str`'s buffer.
|
||||
/// Returns an unsafe pointer to the `&str`'s buffer.
|
||||
///
|
||||
/// The caller must ensure that the string outlives this pointer, and
|
||||
/// that it is not
|
||||
|
@ -1609,7 +1609,7 @@ impl str {
|
|||
core_str::StrExt::as_ptr(&self[..])
|
||||
}
|
||||
|
||||
/// Return an iterator of `u16` over the string encoded as UTF-16.
|
||||
/// Returns an iterator of `u16` over the string encoded as UTF-16.
|
||||
#[unstable(feature = "collections",
|
||||
reason = "this functionality may only be provided by libunicode")]
|
||||
pub fn utf16_units(&self) -> Utf16Units {
|
||||
|
|
|
@ -132,7 +132,7 @@ impl String {
|
|||
///
|
||||
/// let invalid_vec = vec![240, 144, 128];
|
||||
/// let s = String::from_utf8(invalid_vec).err().unwrap();
|
||||
/// assert_eq!(s.utf8_error(), Utf8Error::TooShort);
|
||||
/// let err = s.utf8_error();
|
||||
/// assert_eq!(s.into_bytes(), [240, 144, 128]);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -156,14 +156,10 @@ impl String {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
|
||||
let mut i = 0;
|
||||
let mut i;
|
||||
match str::from_utf8(v) {
|
||||
Ok(s) => return Cow::Borrowed(s),
|
||||
Err(e) => {
|
||||
if let Utf8Error::InvalidByte(firstbad) = e {
|
||||
i = firstbad;
|
||||
}
|
||||
}
|
||||
Err(e) => i = e.valid_up_to(),
|
||||
}
|
||||
|
||||
const TAG_CONT_U8: u8 = 128;
|
||||
|
@ -188,9 +184,9 @@ impl String {
|
|||
};
|
||||
}
|
||||
|
||||
// subseqidx is the index of the first byte of the subsequence we're looking at.
|
||||
// It's used to copy a bunch of contiguous good codepoints at once instead of copying
|
||||
// them one by one.
|
||||
// subseqidx is the index of the first byte of the subsequence we're
|
||||
// looking at. It's used to copy a bunch of contiguous good codepoints
|
||||
// at once instead of copying them one by one.
|
||||
let mut subseqidx = i;
|
||||
|
||||
while i < total {
|
||||
|
@ -347,7 +343,7 @@ impl String {
|
|||
String { vec: bytes }
|
||||
}
|
||||
|
||||
/// Return the underlying byte buffer, encoded as UTF-8.
|
||||
/// Returns the underlying byte buffer, encoded as UTF-8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -363,7 +359,7 @@ impl String {
|
|||
self.vec
|
||||
}
|
||||
|
||||
/// Extract a string slice containing the entire string.
|
||||
/// Extracts a string slice containing the entire string.
|
||||
#[inline]
|
||||
#[unstable(feature = "convert",
|
||||
reason = "waiting on RFC revision")]
|
||||
|
@ -607,7 +603,7 @@ impl String {
|
|||
ch
|
||||
}
|
||||
|
||||
/// Insert a character into the string buffer at byte position `idx`.
|
||||
/// Inserts a character into the string buffer at byte position `idx`.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
|
@ -662,7 +658,7 @@ impl String {
|
|||
&mut self.vec
|
||||
}
|
||||
|
||||
/// Return the number of bytes in this string.
|
||||
/// Returns the number of bytes in this string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -705,12 +701,12 @@ impl String {
|
|||
}
|
||||
|
||||
impl FromUtf8Error {
|
||||
/// Consume this error, returning the bytes that were attempted to make a
|
||||
/// Consumes this error, returning the bytes that were attempted to make a
|
||||
/// `String` with.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn into_bytes(self) -> Vec<u8> { self.bytes }
|
||||
|
||||
/// Access the underlying UTF8-error that was the cause of this error.
|
||||
/// Accesss the underlying UTF8-error that was the cause of this error.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn utf8_error(&self) -> Utf8Error { self.error }
|
||||
}
|
||||
|
@ -959,7 +955,7 @@ impl<'a> Deref for DerefString<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert a string slice to a wrapper type providing a `&String` reference.
|
||||
/// Converts a string slice to a wrapper type providing a `&String` reference.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -393,7 +393,7 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert the vector into Box<[T]>.
|
||||
/// Converts the vector into Box<[T]>.
|
||||
///
|
||||
/// Note that this will drop any excess capacity. Calling this and
|
||||
/// converting back to a vector with `into_vec()` is equivalent to calling
|
||||
|
@ -434,7 +434,7 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Extract a slice containing the entire vector.
|
||||
/// Extracts a slice containing the entire vector.
|
||||
#[inline]
|
||||
#[unstable(feature = "convert",
|
||||
reason = "waiting on RFC revision")]
|
||||
|
@ -1936,7 +1936,7 @@ impl<'a, T> Drop for DerefVec<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert a slice to a wrapper type providing a `&Vec<T>` reference.
|
||||
/// Converts a slice to a wrapper type providing a `&Vec<T>` reference.
|
||||
#[unstable(feature = "collections")]
|
||||
pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
|
||||
unsafe {
|
||||
|
|
|
@ -481,7 +481,7 @@ impl<T> VecDeque<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Shorten a ringbuf, dropping excess elements from the back.
|
||||
/// Shortens a ringbuf, dropping excess elements from the back.
|
||||
///
|
||||
/// If `len` is greater than the ringbuf's current length, this has no
|
||||
/// effect.
|
||||
|
|
|
@ -452,7 +452,7 @@ impl<V> VecMap<V> {
|
|||
Drain { iter: self.v.drain().enumerate().filter_map(filter) }
|
||||
}
|
||||
|
||||
/// Return the number of elements in the map.
|
||||
/// Returns the number of elements in the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -470,7 +470,7 @@ impl<V> VecMap<V> {
|
|||
self.v.iter().filter(|elt| elt.is_some()).count()
|
||||
}
|
||||
|
||||
/// Return true if the map contains no elements.
|
||||
/// Returns true if the map contains no elements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -12,14 +12,13 @@ macro_rules! map_insert_rand_bench {
|
|||
($name: ident, $n: expr, $map: ident) => (
|
||||
#[bench]
|
||||
pub fn $name(b: &mut ::test::Bencher) {
|
||||
use std::rand;
|
||||
use std::rand::Rng;
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
use test::black_box;
|
||||
|
||||
let n: usize = $n;
|
||||
let mut map = $map::new();
|
||||
// setup
|
||||
let mut rng = rand::weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
|
||||
for _ in 0..n {
|
||||
let i = rng.gen::<usize>() % n;
|
||||
|
@ -67,8 +66,7 @@ macro_rules! map_find_rand_bench {
|
|||
#[bench]
|
||||
pub fn $name(b: &mut ::test::Bencher) {
|
||||
use std::iter::Iterator;
|
||||
use std::rand::Rng;
|
||||
use std::rand;
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
use std::vec::Vec;
|
||||
use test::black_box;
|
||||
|
||||
|
@ -76,7 +74,7 @@ macro_rules! map_find_rand_bench {
|
|||
let n: usize = $n;
|
||||
|
||||
// setup
|
||||
let mut rng = rand::weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
|
||||
|
||||
for &k in &keys {
|
||||
|
|
|
@ -389,16 +389,15 @@ fn test_bit_vec_clone() {
|
|||
|
||||
mod bench {
|
||||
use std::collections::{BitSet, BitVec};
|
||||
use std::rand::{Rng, self};
|
||||
use std::__rand::{Rng, thread_rng, ThreadRng};
|
||||
use std::u32;
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
const BENCH_BITS : usize = 1 << 14;
|
||||
|
||||
fn rng() -> rand::IsaacRng {
|
||||
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
|
||||
rand::SeedableRng::from_seed(seed)
|
||||
fn rng() -> ThreadRng {
|
||||
thread_rng()
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
|
@ -633,15 +633,14 @@ fn test_bit_vec_extend() {
|
|||
mod bench {
|
||||
use std::collections::BitVec;
|
||||
use std::u32;
|
||||
use std::rand::{Rng, self};
|
||||
use std::__rand::{Rng, thread_rng, ThreadRng};
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
const BENCH_BITS : usize = 1 << 14;
|
||||
|
||||
fn rng() -> rand::IsaacRng {
|
||||
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
|
||||
rand::SeedableRng::from_seed(seed)
|
||||
fn rng() -> ThreadRng {
|
||||
thread_rng()
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
|
@ -251,7 +251,7 @@ fn test_entry(){
|
|||
|
||||
mod bench {
|
||||
use std::collections::BTreeMap;
|
||||
use std::rand::{Rng, weak_rng};
|
||||
use std::__rand::{Rng, thread_rng};
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
|
@ -269,7 +269,7 @@ mod bench {
|
|||
|
||||
fn bench_iter(b: &mut Bencher, size: i32) {
|
||||
let mut map = BTreeMap::<i32, i32>::new();
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
|
||||
for _ in 0..size {
|
||||
map.insert(rng.gen(), rng.gen());
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::cmp::Ordering::{Equal, Greater, Less};
|
|||
use std::default::Default;
|
||||
use std::iter::RandomAccessIterator;
|
||||
use std::mem;
|
||||
use std::rand::{Rng, thread_rng};
|
||||
use std::__rand::{Rng, thread_rng};
|
||||
use std::rc::Rc;
|
||||
use std::slice::ElementSwaps;
|
||||
|
||||
|
@ -1296,7 +1296,7 @@ fn test_to_vec() {
|
|||
mod bench {
|
||||
use std::iter::repeat;
|
||||
use std::{mem, ptr};
|
||||
use std::rand::{Rng, weak_rng};
|
||||
use std::__rand::{Rng, thread_rng};
|
||||
|
||||
use test::{Bencher, black_box};
|
||||
|
||||
|
@ -1465,7 +1465,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn random_inserts(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v: Vec<_> = repeat((0, 0)).take(30).collect();
|
||||
for _ in 0..100 {
|
||||
|
@ -1477,7 +1477,7 @@ mod bench {
|
|||
}
|
||||
#[bench]
|
||||
fn random_removes(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v: Vec<_> = repeat((0, 0)).take(130).collect();
|
||||
for _ in 0..100 {
|
||||
|
@ -1489,7 +1489,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn sort_random_small(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect();
|
||||
v.sort();
|
||||
|
@ -1499,7 +1499,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn sort_random_medium(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect();
|
||||
v.sort();
|
||||
|
@ -1509,7 +1509,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn sort_random_large(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect();
|
||||
v.sort();
|
||||
|
@ -1530,7 +1530,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn sort_big_random_small(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v = rng.gen_iter::<BigSortable>().take(5)
|
||||
.collect::<Vec<BigSortable>>();
|
||||
|
@ -1541,7 +1541,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn sort_big_random_medium(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v = rng.gen_iter::<BigSortable>().take(100)
|
||||
.collect::<Vec<BigSortable>>();
|
||||
|
@ -1552,7 +1552,7 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn sort_big_random_large(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| {
|
||||
let mut v = rng.gen_iter::<BigSortable>().take(10000)
|
||||
.collect::<Vec<BigSortable>>();
|
||||
|
|
|
@ -1502,7 +1502,7 @@ fn test_str_from_utf8() {
|
|||
assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
|
||||
|
||||
let xs = b"hello\xFF";
|
||||
assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort));
|
||||
assert!(from_utf8(xs).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -45,7 +45,6 @@ fn test_from_utf8() {
|
|||
|
||||
let xs = b"hello\xFF".to_vec();
|
||||
let err = String::from_utf8(xs).err().unwrap();
|
||||
assert_eq!(err.utf8_error(), Utf8Error::TooShort);
|
||||
assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ use marker::{Reflect, Sized};
|
|||
/// [mod]: index.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Any: Reflect + 'static {
|
||||
/// Get the `TypeId` of `self`
|
||||
/// Gets the `TypeId` of `self`.
|
||||
#[unstable(feature = "core",
|
||||
reason = "this method will likely be replaced by an associated static")]
|
||||
fn get_type_id(&self) -> TypeId;
|
||||
|
|
|
@ -78,12 +78,20 @@ use intrinsics;
|
|||
use cell::UnsafeCell;
|
||||
use marker::PhantomData;
|
||||
|
||||
use default::Default;
|
||||
|
||||
/// A boolean type which can be safely shared between threads.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct AtomicBool {
|
||||
v: UnsafeCell<usize>,
|
||||
}
|
||||
|
||||
impl Default for AtomicBool {
|
||||
fn default() -> AtomicBool {
|
||||
ATOMIC_BOOL_INIT
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for AtomicBool {}
|
||||
|
||||
/// A signed integer type which can be safely shared between threads.
|
||||
|
@ -92,6 +100,12 @@ pub struct AtomicIsize {
|
|||
v: UnsafeCell<isize>,
|
||||
}
|
||||
|
||||
impl Default for AtomicIsize {
|
||||
fn default() -> AtomicIsize {
|
||||
ATOMIC_ISIZE_INIT
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for AtomicIsize {}
|
||||
|
||||
/// An unsigned integer type which can be safely shared between threads.
|
||||
|
@ -100,6 +114,12 @@ pub struct AtomicUsize {
|
|||
v: UnsafeCell<usize>,
|
||||
}
|
||||
|
||||
impl Default for AtomicUsize {
|
||||
fn default() -> AtomicUsize {
|
||||
ATOMIC_USIZE_INIT
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for AtomicUsize {}
|
||||
|
||||
/// A raw pointer type which can be safely shared between threads.
|
||||
|
|
|
@ -211,7 +211,7 @@ impl<T:Copy> Cell<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the underlying `UnsafeCell`.
|
||||
/// Gets a reference to the underlying `UnsafeCell`.
|
||||
///
|
||||
/// # Unsafety
|
||||
///
|
||||
|
@ -436,7 +436,7 @@ impl<T> RefCell<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the underlying `UnsafeCell`.
|
||||
/// Gets a reference to the underlying `UnsafeCell`.
|
||||
///
|
||||
/// This can be used to circumvent `RefCell`'s safety checks.
|
||||
///
|
||||
|
@ -537,7 +537,7 @@ impl<'b, T> Deref for Ref<'b, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Copy a `Ref`.
|
||||
/// Copies a `Ref`.
|
||||
///
|
||||
/// The `RefCell` is already immutably borrowed, so this cannot fail.
|
||||
///
|
||||
|
@ -647,7 +647,7 @@ pub struct UnsafeCell<T> {
|
|||
impl<T> !Sync for UnsafeCell<T> {}
|
||||
|
||||
impl<T> UnsafeCell<T> {
|
||||
/// Construct a new instance of `UnsafeCell` which will wrap the specified
|
||||
/// Constructs a new instance of `UnsafeCell` which will wrap the specified
|
||||
/// value.
|
||||
///
|
||||
/// All access to the inner value through methods is `unsafe`, and it is highly discouraged to
|
||||
|
@ -685,7 +685,7 @@ impl<T> UnsafeCell<T> {
|
|||
&self.value as *const T as *mut T
|
||||
}
|
||||
|
||||
/// Unwraps the value
|
||||
/// Unwraps the value.
|
||||
///
|
||||
/// # Unsafety
|
||||
///
|
||||
|
|
|
@ -38,7 +38,7 @@ pub trait Clone : Sized {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn clone(&self) -> Self;
|
||||
|
||||
/// Perform copy-assignment from `source`.
|
||||
/// Performs copy-assignment from `source`.
|
||||
///
|
||||
/// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
|
||||
/// but can be overridden to reuse the resources of `a` to avoid unnecessary
|
||||
|
@ -52,7 +52,7 @@ pub trait Clone : Sized {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T: ?Sized> Clone for &'a T {
|
||||
/// Return a shallow copy of the reference.
|
||||
/// Returns a shallow copy of the reference.
|
||||
#[inline]
|
||||
fn clone(&self) -> &'a T { *self }
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ macro_rules! clone_impl {
|
|||
($t:ty) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Clone for $t {
|
||||
/// Return a deep copy of the value.
|
||||
/// Returns a deep copy of the value.
|
||||
#[inline]
|
||||
fn clone(&self) -> $t { *self }
|
||||
}
|
||||
|
@ -92,28 +92,28 @@ macro_rules! extern_fn_clone {
|
|||
#[unstable(feature = "core",
|
||||
reason = "this may not be sufficient for fns with region parameters")]
|
||||
impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
|
||||
/// Return a copy of a function pointer
|
||||
/// Returns a copy of a function pointer.
|
||||
#[inline]
|
||||
fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
|
||||
}
|
||||
|
||||
#[unstable(feature = "core", reason = "brand new")]
|
||||
impl<$($A,)* ReturnType> Clone for extern "C" fn($($A),*) -> ReturnType {
|
||||
/// Return a copy of a function pointer
|
||||
/// Returns a copy of a function pointer.
|
||||
#[inline]
|
||||
fn clone(&self) -> extern "C" fn($($A),*) -> ReturnType { *self }
|
||||
}
|
||||
|
||||
#[unstable(feature = "core", reason = "brand new")]
|
||||
impl<$($A,)* ReturnType> Clone for unsafe extern "Rust" fn($($A),*) -> ReturnType {
|
||||
/// Return a copy of a function pointer
|
||||
/// Returns a copy of a function pointer.
|
||||
#[inline]
|
||||
fn clone(&self) -> unsafe extern "Rust" fn($($A),*) -> ReturnType { *self }
|
||||
}
|
||||
|
||||
#[unstable(feature = "core", reason = "brand new")]
|
||||
impl<$($A,)* ReturnType> Clone for unsafe extern "C" fn($($A),*) -> ReturnType {
|
||||
/// Return a copy of a function pointer
|
||||
/// Returns a copy of a function pointer.
|
||||
#[inline]
|
||||
fn clone(&self) -> unsafe extern "C" fn($($A),*) -> ReturnType { *self }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -8,14 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
pub use self::ExponentFormat::*;
|
||||
pub use self::SignificantDigits::*;
|
||||
pub use self::SignFormat::*;
|
||||
|
||||
use char;
|
||||
use char::CharExt;
|
||||
use char::{self, CharExt};
|
||||
use fmt;
|
||||
use iter::Iterator;
|
||||
use num::{cast, Float, ToPrimitive};
|
||||
|
@ -46,50 +42,29 @@ pub enum SignificantDigits {
|
|||
DigExact(usize)
|
||||
}
|
||||
|
||||
/// How to emit the sign of a number.
|
||||
pub enum SignFormat {
|
||||
/// `-` will be printed for negative values, but no sign will be emitted
|
||||
/// for positive numbers.
|
||||
SignNeg
|
||||
}
|
||||
|
||||
const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
|
||||
|
||||
/// Converts a number to its string representation as a byte vector.
|
||||
/// This is meant to be a common base implementation for all numeric string
|
||||
/// conversion functions like `to_string()` or `to_str_radix()`.
|
||||
/// Converts a float number to its string representation.
|
||||
/// This is meant to be a common base implementation for various formatting styles.
|
||||
/// The number is assumed to be non-negative, callers use `Formatter::pad_integral`
|
||||
/// to add the right sign, if any.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `num` - The number to convert. Accepts any number that
|
||||
/// - `num` - The number to convert (non-negative). Accepts any number that
|
||||
/// implements the numeric traits.
|
||||
/// - `radix` - Base to use. Accepts only the values 2-36. If the exponential notation
|
||||
/// is used, then this base is only used for the significand. The exponent
|
||||
/// itself always printed using a base of 10.
|
||||
/// - `negative_zero` - Whether to treat the special value `-0` as
|
||||
/// `-0` or as `+0`.
|
||||
/// - `sign` - How to emit the sign. See `SignFormat`.
|
||||
/// - `digits` - The amount of digits to use for emitting the fractional
|
||||
/// part, if any. See `SignificantDigits`.
|
||||
/// - `exp_format` - Whether or not to use the exponential (scientific) notation.
|
||||
/// See `ExponentFormat`.
|
||||
/// - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if
|
||||
/// exponential notation is desired.
|
||||
/// - `f` - A closure to invoke with the bytes representing the
|
||||
/// - `f` - A closure to invoke with the string representing the
|
||||
/// float.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - Panics if `radix` < 2 or `radix` > 36.
|
||||
/// - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict
|
||||
/// between digit and exponent sign `'e'`.
|
||||
/// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
|
||||
/// between digit and exponent sign `'p'`.
|
||||
/// - Panics if `num` is negative.
|
||||
pub fn float_to_str_bytes_common<T: Float, U, F>(
|
||||
num: T,
|
||||
radix: u32,
|
||||
negative_zero: bool,
|
||||
sign: SignFormat,
|
||||
digits: SignificantDigits,
|
||||
exp_format: ExponentFormat,
|
||||
exp_upper: bool,
|
||||
|
@ -97,16 +72,12 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
) -> U where
|
||||
F: FnOnce(&str) -> U,
|
||||
{
|
||||
assert!(2 <= radix && radix <= 36);
|
||||
match exp_format {
|
||||
ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e'
|
||||
=> panic!("float_to_str_bytes_common: radix {} incompatible with \
|
||||
use of 'e' as decimal exponent", radix),
|
||||
_ => ()
|
||||
}
|
||||
|
||||
let _0: T = Float::zero();
|
||||
let _1: T = Float::one();
|
||||
let radix: u32 = 10;
|
||||
let radix_f: T = cast(radix).unwrap();
|
||||
|
||||
assert!(num.is_nan() || num >= _0, "float_to_str_bytes_common: number is negative");
|
||||
|
||||
match num.classify() {
|
||||
Fp::Nan => return f("NaN"),
|
||||
|
@ -119,41 +90,28 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity());
|
||||
// For an f64 the exponent is in the range of [-1022, 1023] for base 2, so
|
||||
// we may have up to that many digits. Give ourselves some extra wiggle room
|
||||
// otherwise as well.
|
||||
let mut buf = [0; 1536];
|
||||
// For an f64 the (decimal) exponent is roughly in the range of [-307, 308], so
|
||||
// we may have up to that many digits. We err on the side of caution and
|
||||
// add 50% extra wiggle room.
|
||||
let mut buf = [0; 462];
|
||||
let mut end = 0;
|
||||
let radix_gen: T = cast(radix as isize).unwrap();
|
||||
|
||||
let (num, exp) = match exp_format {
|
||||
ExpNone => (num, 0),
|
||||
ExpDec if num == _0 => (num, 0),
|
||||
ExpDec => {
|
||||
let (exp, exp_base) = match exp_format {
|
||||
ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
|
||||
ExpNone => panic!("unreachable"),
|
||||
};
|
||||
|
||||
(num / exp_base.powf(exp), cast::<T, i32>(exp).unwrap())
|
||||
ExpDec if num != _0 => {
|
||||
let exp = num.log10().floor();
|
||||
(num / radix_f.powf(exp), cast::<T, i32>(exp).unwrap())
|
||||
}
|
||||
_ => (num, 0)
|
||||
};
|
||||
|
||||
// First emit the non-fractional part, looping at least once to make
|
||||
// sure at least a `0` gets emitted.
|
||||
let mut deccum = num.trunc();
|
||||
loop {
|
||||
// Calculate the absolute value of each digit instead of only
|
||||
// doing it once for the whole number because a
|
||||
// representable negative number doesn't necessary have an
|
||||
// representable additive inverse of the same type
|
||||
// (See twos complement). But we assume that for the
|
||||
// numbers [-35 .. 0] we always have [0 .. 35].
|
||||
let current_digit = (deccum % radix_gen).abs();
|
||||
let current_digit = deccum % radix_f;
|
||||
|
||||
// Decrease the deccumulator one digit at a time
|
||||
deccum = deccum / radix_gen;
|
||||
deccum = deccum / radix_f;
|
||||
deccum = deccum.trunc();
|
||||
|
||||
let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
|
||||
|
@ -170,15 +128,6 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
DigExact(count) => (true, count + 1, true)
|
||||
};
|
||||
|
||||
// Decide what sign to put in front
|
||||
match sign {
|
||||
SignNeg if neg => {
|
||||
buf[end] = b'-';
|
||||
end += 1;
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
buf[..end].reverse();
|
||||
|
||||
// Remember start of the fractional digits.
|
||||
|
@ -205,14 +154,11 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
)
|
||||
) {
|
||||
// Shift first fractional digit into the integer part
|
||||
deccum = deccum * radix_gen;
|
||||
deccum = deccum * radix_f;
|
||||
|
||||
// Calculate the absolute value of each digit.
|
||||
// See note in first loop.
|
||||
let current_digit = deccum.trunc().abs();
|
||||
let current_digit = deccum.trunc();
|
||||
|
||||
let c = char::from_digit(current_digit.to_isize().unwrap() as u32,
|
||||
radix);
|
||||
let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
|
||||
buf[end] = c.unwrap() as u8;
|
||||
end += 1;
|
||||
|
||||
|
@ -301,12 +247,8 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
|
||||
match exp_format {
|
||||
ExpNone => {},
|
||||
_ => {
|
||||
buf[end] = match exp_format {
|
||||
ExpDec if exp_upper => 'E',
|
||||
ExpDec if !exp_upper => 'e',
|
||||
_ => panic!("unreachable"),
|
||||
} as u8;
|
||||
ExpDec => {
|
||||
buf[end] = if exp_upper { b'E' } else { b'e' };
|
||||
end += 1;
|
||||
|
||||
struct Filler<'a> {
|
||||
|
@ -324,13 +266,9 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
}
|
||||
|
||||
let mut filler = Filler { buf: &mut buf, end: &mut end };
|
||||
match sign {
|
||||
SignNeg => {
|
||||
let _ = fmt::write(&mut filler, format_args!("{:-}", exp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f(unsafe { str::from_utf8_unchecked(&buf[..end]) })
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -18,6 +18,7 @@ use clone::Clone;
|
|||
use iter::Iterator;
|
||||
use marker::{Copy, PhantomData, Sized};
|
||||
use mem;
|
||||
use num::Float;
|
||||
use option::Option;
|
||||
use option::Option::{Some, None};
|
||||
use result::Result::Ok;
|
||||
|
@ -910,33 +911,38 @@ impl<'a, T> Pointer for &'a mut T {
|
|||
}
|
||||
}
|
||||
|
||||
// Common code of floating point Debug and Display.
|
||||
fn float_to_str_common<T: Float, F>(num: &T, precision: Option<usize>, post: F) -> Result
|
||||
where F : FnOnce(&str) -> Result {
|
||||
let digits = match precision {
|
||||
Some(i) => float::DigExact(i),
|
||||
None => float::DigMax(6),
|
||||
};
|
||||
float::float_to_str_bytes_common(num.abs(),
|
||||
digits,
|
||||
float::ExpNone,
|
||||
false,
|
||||
post)
|
||||
}
|
||||
|
||||
macro_rules! floating { ($ty:ident) => {
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Debug for $ty {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
Display::fmt(self, fmt)
|
||||
float_to_str_common(self, fmt.precision, |absolute| {
|
||||
// is_positive() counts -0.0 as negative
|
||||
fmt.pad_integral(self.is_nan() || self.is_positive(), "", absolute)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Display for $ty {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
use num::Float;
|
||||
|
||||
let digits = match fmt.precision {
|
||||
Some(i) => float::DigExact(i),
|
||||
None => float::DigMax(6),
|
||||
};
|
||||
float::float_to_str_bytes_common(self.abs(),
|
||||
10,
|
||||
true,
|
||||
float::SignNeg,
|
||||
digits,
|
||||
float::ExpNone,
|
||||
false,
|
||||
|bytes| {
|
||||
fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
|
||||
float_to_str_common(self, fmt.precision, |absolute| {
|
||||
// simple comparison counts -0.0 as positive
|
||||
fmt.pad_integral(self.is_nan() || *self >= 0.0, "", absolute)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -951,9 +957,6 @@ macro_rules! floating { ($ty:ident) => {
|
|||
None => float::DigMax(6),
|
||||
};
|
||||
float::float_to_str_bytes_common(self.abs(),
|
||||
10,
|
||||
true,
|
||||
float::SignNeg,
|
||||
digits,
|
||||
float::ExpDec,
|
||||
false,
|
||||
|
@ -973,9 +976,6 @@ macro_rules! floating { ($ty:ident) => {
|
|||
None => float::DigMax(6),
|
||||
};
|
||||
float::float_to_str_bytes_common(self.abs(),
|
||||
10,
|
||||
true,
|
||||
float::SignNeg,
|
||||
digits,
|
||||
float::ExpDec,
|
||||
true,
|
||||
|
|
|
@ -139,16 +139,16 @@ extern "rust-intrinsic" {
|
|||
pub fn atomic_fence_rel();
|
||||
pub fn atomic_fence_acqrel();
|
||||
|
||||
/// Abort the execution of the process.
|
||||
/// Aborts the execution of the process.
|
||||
pub fn abort() -> !;
|
||||
|
||||
/// Tell LLVM that this point in the code is not reachable,
|
||||
/// Tells LLVM that this point in the code is not reachable,
|
||||
/// enabling further optimizations.
|
||||
///
|
||||
/// NB: This is very different from the `unreachable!()` macro!
|
||||
pub fn unreachable() -> !;
|
||||
|
||||
/// Inform the optimizer that a condition is always true.
|
||||
/// Informs the optimizer that a condition is always true.
|
||||
/// If the condition is false, the behavior is undefined.
|
||||
///
|
||||
/// No code is generated for this intrinsic, but the optimizer will try
|
||||
|
@ -158,7 +158,7 @@ extern "rust-intrinsic" {
|
|||
/// own, or if it does not enable any significant optimizations.
|
||||
pub fn assume(b: bool);
|
||||
|
||||
/// Execute a breakpoint trap, for inspection by a debugger.
|
||||
/// Executes a breakpoint trap, for inspection by a debugger.
|
||||
pub fn breakpoint();
|
||||
|
||||
/// The size of a type in bytes.
|
||||
|
@ -170,7 +170,7 @@ extern "rust-intrinsic" {
|
|||
/// elements.
|
||||
pub fn size_of<T>() -> usize;
|
||||
|
||||
/// Move a value to an uninitialized memory location.
|
||||
/// Moves a value to an uninitialized memory location.
|
||||
///
|
||||
/// Drop glue is not run on the destination.
|
||||
pub fn move_val_init<T>(dst: &mut T, src: T);
|
||||
|
@ -186,7 +186,7 @@ extern "rust-intrinsic" {
|
|||
/// crate it is invoked in.
|
||||
pub fn type_id<T: ?Sized + 'static>() -> u64;
|
||||
|
||||
/// Create a value initialized to so that its drop flag,
|
||||
/// Creates a value initialized to so that its drop flag,
|
||||
/// if any, says that it has been dropped.
|
||||
///
|
||||
/// `init_dropped` is unsafe because it returns a datum with all
|
||||
|
@ -199,7 +199,7 @@ extern "rust-intrinsic" {
|
|||
/// intrinsic).
|
||||
pub fn init_dropped<T>() -> T;
|
||||
|
||||
/// Create a value initialized to zero.
|
||||
/// Creates a value initialized to zero.
|
||||
///
|
||||
/// `init` is unsafe because it returns a zeroed-out datum,
|
||||
/// which is unsafe unless T is `Copy`. Also, even if T is
|
||||
|
@ -207,7 +207,7 @@ extern "rust-intrinsic" {
|
|||
/// state for the type in question.
|
||||
pub fn init<T>() -> T;
|
||||
|
||||
/// Create an uninitialized value.
|
||||
/// Creates an uninitialized value.
|
||||
///
|
||||
/// `uninit` is unsafe because there is no guarantee of what its
|
||||
/// contents are. In particular its drop-flag may be set to any
|
||||
|
@ -216,7 +216,7 @@ extern "rust-intrinsic" {
|
|||
/// initialize memory previous set to the result of `uninit`.
|
||||
pub fn uninit<T>() -> T;
|
||||
|
||||
/// Move a value out of scope without running drop glue.
|
||||
/// Moves a value out of scope without running drop glue.
|
||||
///
|
||||
/// `forget` is unsafe because the caller is responsible for
|
||||
/// ensuring the argument is deallocated already.
|
||||
|
|
|
@ -91,7 +91,7 @@ pub trait Iterator {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Item;
|
||||
|
||||
/// Advance the iterator and return the next value. Return `None` when the
|
||||
/// Advances the iterator and returns the next value. Returns `None` when the
|
||||
/// end is reached.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn next(&mut self) -> Option<Self::Item>;
|
||||
|
@ -670,7 +670,7 @@ pub trait Iterator {
|
|||
None
|
||||
}
|
||||
|
||||
/// Return the index of the first element satisfying the specified predicate
|
||||
/// Returns the index of the first element satisfying the specified predicate
|
||||
///
|
||||
/// Does not consume the iterator past the first found element.
|
||||
///
|
||||
|
@ -698,7 +698,7 @@ pub trait Iterator {
|
|||
None
|
||||
}
|
||||
|
||||
/// Return the index of the last element satisfying the specified predicate
|
||||
/// Returns the index of the last element satisfying the specified predicate
|
||||
///
|
||||
/// If no element matches, None is returned.
|
||||
///
|
||||
|
@ -853,7 +853,7 @@ pub trait Iterator {
|
|||
MinMax(min, max)
|
||||
}
|
||||
|
||||
/// Return the element that gives the maximum value from the
|
||||
/// Returns the element that gives the maximum value from the
|
||||
/// specified function.
|
||||
///
|
||||
/// Returns the rightmost element if the comparison determines two elements
|
||||
|
@ -882,7 +882,7 @@ pub trait Iterator {
|
|||
.map(|(_, x)| x)
|
||||
}
|
||||
|
||||
/// Return the element that gives the minimum value from the
|
||||
/// Returns the element that gives the minimum value from the
|
||||
/// specified function.
|
||||
///
|
||||
/// Returns the leftmost element if the comparison determines two elements
|
||||
|
@ -1099,7 +1099,7 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
|
|||
#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
|
||||
built from an iterator over elements of type `{A}`"]
|
||||
pub trait FromIterator<A> {
|
||||
/// Build a container with elements from something iterable.
|
||||
/// Builds a container with elements from something iterable.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -1158,7 +1158,7 @@ impl<I: Iterator> IntoIterator for I {
|
|||
/// A type growable from an `Iterator` implementation
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Extend<A> {
|
||||
/// Extend a container with the elements yielded by an arbitrary iterator
|
||||
/// Extends a container with the elements yielded by an arbitrary iterator
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
|
||||
}
|
||||
|
@ -1170,7 +1170,7 @@ pub trait Extend<A> {
|
|||
/// independently of each other.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait DoubleEndedIterator: Iterator {
|
||||
/// Yield an element from the end of the range, returning `None` if the
|
||||
/// Yields an element from the end of the range, returning `None` if the
|
||||
/// range is empty.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn next_back(&mut self) -> Option<Self::Item>;
|
||||
|
@ -1191,11 +1191,11 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
|
|||
reason = "not widely used, may be better decomposed into Index \
|
||||
and ExactSizeIterator")]
|
||||
pub trait RandomAccessIterator: Iterator {
|
||||
/// Return the number of indexable elements. At most `std::usize::MAX`
|
||||
/// Returns the number of indexable elements. At most `std::usize::MAX`
|
||||
/// elements are indexable, even if the iterator represents a longer range.
|
||||
fn indexable(&self) -> usize;
|
||||
|
||||
/// Return an element at an index, or `None` if the index is out of bounds
|
||||
/// Returns an element at an index, or `None` if the index is out of bounds
|
||||
fn idx(&mut self, index: usize) -> Option<Self::Item>;
|
||||
}
|
||||
|
||||
|
@ -1210,7 +1210,7 @@ pub trait RandomAccessIterator: Iterator {
|
|||
pub trait ExactSizeIterator: Iterator {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Return the exact length of the iterator.
|
||||
/// Returns the exact length of the iterator.
|
||||
fn len(&self) -> usize {
|
||||
let (lower, upper) = self.size_hint();
|
||||
// Note: This assertion is overly defensive, but it checks the invariant
|
||||
|
@ -1856,7 +1856,7 @@ impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I: Iterator> Peekable<I> {
|
||||
/// Return a reference to the next element of the iterator with out
|
||||
/// Returns a reference to the next element of the iterator with out
|
||||
/// advancing it, or None if the iterator is exhausted.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1870,7 +1870,7 @@ impl<I: Iterator> Peekable<I> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check whether peekable iterator is empty or not.
|
||||
/// Checks whether peekable iterator is empty or not.
|
||||
#[inline]
|
||||
pub fn is_empty(&mut self) -> bool {
|
||||
self.peek().is_none()
|
||||
|
@ -2401,12 +2401,12 @@ pub trait Step: PartialOrd {
|
|||
/// Steps `self` if possible.
|
||||
fn step(&self, by: &Self) -> Option<Self>;
|
||||
|
||||
/// The number of steps between two step objects.
|
||||
/// Returns the number of steps between two step objects.
|
||||
///
|
||||
/// `start` should always be less than `end`, so the result should never
|
||||
/// be negative.
|
||||
///
|
||||
/// Return `None` if it is not possible to calculate steps_between
|
||||
/// Returns `None` if it is not possible to calculate steps_between
|
||||
/// without overflow.
|
||||
fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
|
||||
}
|
||||
|
@ -2549,7 +2549,7 @@ pub struct RangeInclusive<A> {
|
|||
done: bool,
|
||||
}
|
||||
|
||||
/// Return an iterator over the range [start, stop]
|
||||
/// Returns an iterator over the range [start, stop].
|
||||
#[inline]
|
||||
#[unstable(feature = "core",
|
||||
reason = "likely to be replaced by range notation and adapters")]
|
||||
|
@ -2657,7 +2657,7 @@ pub struct RangeStepInclusive<A> {
|
|||
done: bool,
|
||||
}
|
||||
|
||||
/// Return an iterator over the range [start, stop] by `step`.
|
||||
/// Returns an iterator over the range [start, stop] by `step`.
|
||||
///
|
||||
/// It handles overflow by stopping.
|
||||
///
|
||||
|
@ -2827,7 +2827,7 @@ type IterateState<T, F> = (F, Option<T>, bool);
|
|||
#[unstable(feature = "core")]
|
||||
pub type Iterate<T, F> = Unfold<IterateState<T, F>, fn(&mut IterateState<T, F>) -> Option<T>>;
|
||||
|
||||
/// Create a new iterator that produces an infinite sequence of
|
||||
/// Creates a new iterator that produces an infinite sequence of
|
||||
/// repeated applications of the given function `f`.
|
||||
#[unstable(feature = "core")]
|
||||
pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
|
||||
|
@ -2853,7 +2853,7 @@ pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
|
|||
Unfold::new((f, Some(seed), true), next)
|
||||
}
|
||||
|
||||
/// Create a new iterator that endlessly repeats the element `elt`.
|
||||
/// Creates a new iterator that endlessly repeats the element `elt`.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
|
||||
|
@ -2940,7 +2940,7 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
|
||||
/// Compare `a` and `b` for nonequality (Using partial equality, `PartialEq`)
|
||||
/// Compares `a` and `b` for nonequality (Using partial equality, `PartialEq`)
|
||||
pub fn ne<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
|
||||
L::Item: PartialEq<R::Item>,
|
||||
{
|
||||
|
@ -2953,7 +2953,7 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return `a` < `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
/// Returns `a` < `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
pub fn lt<R: Iterator, L: Iterator>(mut a: L, mut b: R) -> bool where
|
||||
L::Item: PartialOrd<R::Item>,
|
||||
{
|
||||
|
@ -2967,7 +2967,7 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return `a` <= `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
/// Returns `a` <= `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
pub fn le<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
|
||||
L::Item: PartialOrd<R::Item>,
|
||||
{
|
||||
|
@ -2981,7 +2981,7 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return `a` > `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
/// Returns `a` > `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
pub fn gt<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
|
||||
L::Item: PartialOrd<R::Item>,
|
||||
{
|
||||
|
@ -2995,7 +2995,7 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return `a` >= `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
/// Returns `a` >= `b` lexicographically (Using partial order, `PartialOrd`)
|
||||
pub fn ge<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
|
||||
L::Item: PartialOrd<R::Item>,
|
||||
{
|
||||
|
|
|
@ -134,7 +134,7 @@ pub fn align_of_val<T>(_val: &T) -> usize {
|
|||
align_of::<T>()
|
||||
}
|
||||
|
||||
/// Create a value initialized to zero.
|
||||
/// Creates a value initialized to zero.
|
||||
///
|
||||
/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe
|
||||
/// operation).
|
||||
|
@ -158,7 +158,7 @@ pub unsafe fn zeroed<T>() -> T {
|
|||
intrinsics::init()
|
||||
}
|
||||
|
||||
/// Create a value initialized to an unspecified series of bytes.
|
||||
/// Creates a value initialized to an unspecified series of bytes.
|
||||
///
|
||||
/// The byte sequence usually indicates that the value at the memory
|
||||
/// in question has been dropped. Thus, *if* T carries a drop flag,
|
||||
|
@ -179,7 +179,7 @@ pub unsafe fn dropped<T>() -> T {
|
|||
dropped_impl()
|
||||
}
|
||||
|
||||
/// Create an uninitialized value.
|
||||
/// Creates an uninitialized value.
|
||||
///
|
||||
/// Care must be taken when using this function, if the type `T` has a destructor and the value
|
||||
/// falls out of scope (due to unwinding or returning) before being initialized, then the
|
||||
|
@ -234,7 +234,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Replace the value at a mutable location with a new one, returning the old value, without
|
||||
/// Replaces the value at a mutable location with a new one, returning the old value, without
|
||||
/// deinitialising or copying either one.
|
||||
///
|
||||
/// This is primarily used for transferring and swapping ownership of a value in a mutable
|
||||
|
|
|
@ -38,7 +38,7 @@ unsafe impl Zeroable for u64 {}
|
|||
pub struct NonZero<T: Zeroable>(T);
|
||||
|
||||
impl<T: Zeroable> NonZero<T> {
|
||||
/// Create an instance of NonZero with the provided value.
|
||||
/// Creates an instance of NonZero with the provided value.
|
||||
/// You must indeed ensure that the value is actually "non-zero".
|
||||
#[inline(always)]
|
||||
pub unsafe fn new(inner: T) -> NonZero<T> {
|
||||
|
|
|
@ -268,7 +268,7 @@ pub trait Int
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn swap_bytes(self) -> Self;
|
||||
|
||||
/// Convert an integer from big endian to the target's endianness.
|
||||
/// Converts an integer from big endian to the target's endianness.
|
||||
///
|
||||
/// On big endian this is a no-op. On little endian the bytes are swapped.
|
||||
///
|
||||
|
@ -291,7 +291,7 @@ pub trait Int
|
|||
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert an integer from little endian to the target's endianness.
|
||||
/// Converts an integer from little endian to the target's endianness.
|
||||
///
|
||||
/// On little endian this is a no-op. On big endian the bytes are swapped.
|
||||
///
|
||||
|
@ -314,7 +314,7 @@ pub trait Int
|
|||
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert `self` to big endian from the target's endianness.
|
||||
/// Converts `self` to big endian from the target's endianness.
|
||||
///
|
||||
/// On big endian this is a no-op. On little endian the bytes are swapped.
|
||||
///
|
||||
|
@ -337,7 +337,7 @@ pub trait Int
|
|||
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert `self` to little endian from the target's endianness.
|
||||
/// Converts `self` to little endian from the target's endianness.
|
||||
///
|
||||
/// On little endian this is a no-op. On big endian the bytes are swapped.
|
||||
///
|
||||
|
@ -845,7 +845,7 @@ macro_rules! int_impl {
|
|||
let min: $T = Int::min_value(); !min
|
||||
}
|
||||
|
||||
/// Convert a string slice in a given base to an integer.
|
||||
/// Converts a string slice in a given base to an integer.
|
||||
///
|
||||
/// Leading and trailing whitespace represent an error.
|
||||
///
|
||||
|
@ -995,7 +995,7 @@ macro_rules! int_impl {
|
|||
(self as $UnsignedT).swap_bytes() as $T
|
||||
}
|
||||
|
||||
/// Convert an integer from big endian to the target's endianness.
|
||||
/// Converts an integer from big endian to the target's endianness.
|
||||
///
|
||||
/// On big endian this is a no-op. On little endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1019,7 +1019,7 @@ macro_rules! int_impl {
|
|||
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert an integer from little endian to the target's endianness.
|
||||
/// Converts an integer from little endian to the target's endianness.
|
||||
///
|
||||
/// On little endian this is a no-op. On big endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1043,7 +1043,7 @@ macro_rules! int_impl {
|
|||
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert `self` to big endian from the target's endianness.
|
||||
/// Converts `self` to big endian from the target's endianness.
|
||||
///
|
||||
/// On big endian this is a no-op. On little endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1067,7 +1067,7 @@ macro_rules! int_impl {
|
|||
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert `self` to little endian from the target's endianness.
|
||||
/// Converts `self` to little endian from the target's endianness.
|
||||
///
|
||||
/// On little endian this is a no-op. On big endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1361,7 +1361,7 @@ macro_rules! uint_impl {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn max_value() -> $T { !0 }
|
||||
|
||||
/// Convert a string slice in a given base to an integer.
|
||||
/// Converts a string slice in a given base to an integer.
|
||||
///
|
||||
/// Leading and trailing whitespace represent an error.
|
||||
///
|
||||
|
@ -1517,7 +1517,7 @@ macro_rules! uint_impl {
|
|||
unsafe { $bswap(self as $ActualT) as $T }
|
||||
}
|
||||
|
||||
/// Convert an integer from big endian to the target's endianness.
|
||||
/// Converts an integer from big endian to the target's endianness.
|
||||
///
|
||||
/// On big endian this is a no-op. On little endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1541,7 +1541,7 @@ macro_rules! uint_impl {
|
|||
if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert an integer from little endian to the target's endianness.
|
||||
/// Converts an integer from little endian to the target's endianness.
|
||||
///
|
||||
/// On little endian this is a no-op. On big endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1565,7 +1565,7 @@ macro_rules! uint_impl {
|
|||
if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert `self` to big endian from the target's endianness.
|
||||
/// Converts `self` to big endian from the target's endianness.
|
||||
///
|
||||
/// On big endian this is a no-op. On little endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -1589,7 +1589,7 @@ macro_rules! uint_impl {
|
|||
if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
|
||||
}
|
||||
|
||||
/// Convert `self` to little endian from the target's endianness.
|
||||
/// Converts `self` to little endian from the target's endianness.
|
||||
///
|
||||
/// On little endian this is a no-op. On big endian the bytes are
|
||||
/// swapped.
|
||||
|
@ -2183,7 +2183,7 @@ impl_to_primitive_float! { f64 }
|
|||
/// A generic trait for converting a number to a value.
|
||||
#[unstable(feature = "core", reason = "trait is likely to be removed")]
|
||||
pub trait FromPrimitive : ::marker::Sized {
|
||||
/// Convert an `isize` to return an optional value of this type. If the
|
||||
/// Converts an `isize` to return an optional value of this type. If the
|
||||
/// value cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
|
@ -2192,39 +2192,39 @@ pub trait FromPrimitive : ::marker::Sized {
|
|||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// Convert an `isize` to return an optional value of this type. If the
|
||||
/// Converts an `isize` to return an optional value of this type. If the
|
||||
/// value cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_isize(n: isize) -> Option<Self> {
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// Convert an `i8` to return an optional value of this type. If the
|
||||
/// Converts an `i8` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// Convert an `i16` to return an optional value of this type. If the
|
||||
/// Converts an `i16` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// Convert an `i32` to return an optional value of this type. If the
|
||||
/// Converts an `i32` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// Convert an `i64` to return an optional value of this type. If the
|
||||
/// Converts an `i64` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
fn from_i64(n: i64) -> Option<Self>;
|
||||
|
||||
/// Convert an `usize` to return an optional value of this type. If the
|
||||
/// Converts an `usize` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
|
@ -2233,46 +2233,46 @@ pub trait FromPrimitive : ::marker::Sized {
|
|||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// Convert a `usize` to return an optional value of this type. If the
|
||||
/// Converts a `usize` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_usize(n: usize) -> Option<Self> {
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// Convert an `u8` to return an optional value of this type. If the
|
||||
/// Converts an `u8` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// Convert an `u16` to return an optional value of this type. If the
|
||||
/// Converts an `u16` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// Convert an `u32` to return an optional value of this type. If the
|
||||
/// Converts an `u32` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// Convert an `u64` to return an optional value of this type. If the
|
||||
/// Converts an `u64` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
fn from_u64(n: u64) -> Option<Self>;
|
||||
|
||||
/// Convert a `f32` to return an optional value of this type. If the
|
||||
/// Converts a `f32` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_f32(n: f32) -> Option<Self> {
|
||||
FromPrimitive::from_f64(n as f64)
|
||||
}
|
||||
|
||||
/// Convert a `f64` to return an optional value of this type. If the
|
||||
/// Converts a `f64` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_f64(n: f64) -> Option<Self> {
|
||||
|
@ -2401,7 +2401,7 @@ impl_from_primitive! { u64, to_u64 }
|
|||
impl_from_primitive! { f32, to_f32 }
|
||||
impl_from_primitive! { f64, to_f64 }
|
||||
|
||||
/// Cast from one machine scalar to another.
|
||||
/// Casts from one machine scalar to another.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -2583,16 +2583,16 @@ pub trait Float
|
|||
/// Returns the mantissa, exponent and sign as integers, respectively.
|
||||
fn integer_decode(self) -> (u64, i16, i8);
|
||||
|
||||
/// Return the largest integer less than or equal to a number.
|
||||
/// Returns the largest integer less than or equal to a number.
|
||||
fn floor(self) -> Self;
|
||||
/// Return the smallest integer greater than or equal to a number.
|
||||
/// Returns the smallest integer greater than or equal to a number.
|
||||
fn ceil(self) -> Self;
|
||||
/// Return the nearest integer to a number. Round half-way cases away from
|
||||
/// Returns the nearest integer to a number. Round half-way cases away from
|
||||
/// `0.0`.
|
||||
fn round(self) -> Self;
|
||||
/// Return the integer part of a number.
|
||||
/// Returns the integer part of a number.
|
||||
fn trunc(self) -> Self;
|
||||
/// Return the fractional part of a number.
|
||||
/// Returns the fractional part of a number.
|
||||
fn fract(self) -> Self;
|
||||
|
||||
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
|
||||
|
@ -2615,21 +2615,21 @@ pub trait Float
|
|||
/// error. This produces a more accurate result with better performance than
|
||||
/// a separate multiplication operation followed by an add.
|
||||
fn mul_add(self, a: Self, b: Self) -> Self;
|
||||
/// Take the reciprocal (inverse) of a number, `1/x`.
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
fn recip(self) -> Self;
|
||||
|
||||
/// Raise a number to an integer power.
|
||||
/// Raises a number to an integer power.
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
fn powi(self, n: i32) -> Self;
|
||||
/// Raise a number to a floating point power.
|
||||
/// Raises a number to a floating point power.
|
||||
fn powf(self, n: Self) -> Self;
|
||||
|
||||
/// Take the square root of a number.
|
||||
/// Takes the square root of a number.
|
||||
///
|
||||
/// Returns NaN if `self` is a negative number.
|
||||
fn sqrt(self) -> Self;
|
||||
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
/// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
fn rsqrt(self) -> Self;
|
||||
|
||||
/// Returns `e^(self)`, (the exponential function).
|
||||
|
@ -2645,9 +2645,9 @@ pub trait Float
|
|||
/// Returns the base 10 logarithm of the number.
|
||||
fn log10(self) -> Self;
|
||||
|
||||
/// Convert radians to degrees.
|
||||
/// Converts radians to degrees.
|
||||
fn to_degrees(self) -> Self;
|
||||
/// Convert degrees to radians.
|
||||
/// Converts degrees to radians.
|
||||
fn to_radians(self) -> Self;
|
||||
}
|
||||
|
||||
|
@ -2682,7 +2682,7 @@ macro_rules! from_str_radix_float_impl {
|
|||
impl FromStr for $T {
|
||||
type Err = ParseFloatError;
|
||||
|
||||
/// Convert a string in base 10 to a float.
|
||||
/// Converts a string in base 10 to a float.
|
||||
/// Accepts an optional decimal exponent.
|
||||
///
|
||||
/// This function accepts strings such as
|
||||
|
@ -2719,7 +2719,7 @@ macro_rules! from_str_radix_float_impl {
|
|||
impl FromStrRadix for $T {
|
||||
type Err = ParseFloatError;
|
||||
|
||||
/// Convert a string in a given base to a float.
|
||||
/// Converts 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**
|
||||
|
|
|
@ -223,7 +223,7 @@ impl<T> Option<T> {
|
|||
// Adapter for working with references
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Convert from `Option<T>` to `Option<&T>`
|
||||
/// Converts from `Option<T>` to `Option<&T>`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -248,7 +248,7 @@ impl<T> Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert from `Option<T>` to `Option<&mut T>`
|
||||
/// Converts from `Option<T>` to `Option<&mut T>`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -269,7 +269,7 @@ impl<T> Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert from `Option<T>` to `&mut [T]` (without copying)
|
||||
/// Converts from `Option<T>` to `&mut [T]` (without copying)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -704,7 +704,7 @@ impl<T> Option<T> {
|
|||
mem::replace(self, None)
|
||||
}
|
||||
|
||||
/// Convert from `Option<T>` to `&[T]` (without copying)
|
||||
/// Converts from `Option<T>` to `&[T]` (without copying)
|
||||
#[inline]
|
||||
#[unstable(feature = "as_slice", since = "unsure of the utility here")]
|
||||
pub fn as_slice<'a>(&'a self) -> &'a [T] {
|
||||
|
|
|
@ -544,19 +544,19 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
|
|||
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
|
||||
|
||||
impl<T: ?Sized> Unique<T> {
|
||||
/// Create a new `Unique`.
|
||||
/// Creates a new `Unique`.
|
||||
#[unstable(feature = "unique")]
|
||||
pub unsafe fn new(ptr: *mut T) -> Unique<T> {
|
||||
Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Dereference the content.
|
||||
/// Dereferences the content.
|
||||
#[unstable(feature = "unique")]
|
||||
pub unsafe fn get(&self) -> &T {
|
||||
&**self.pointer
|
||||
}
|
||||
|
||||
/// Mutably dereference the content.
|
||||
/// Mutably dereferences the content.
|
||||
#[unstable(feature = "unique")]
|
||||
pub unsafe fn get_mut(&mut self) -> &mut T {
|
||||
&mut ***self
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
//! let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11));
|
||||
//!
|
||||
//! // Use `or_else` to handle the error.
|
||||
//! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(11));
|
||||
//! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(i + 20));
|
||||
//!
|
||||
//! // Consume the result and return the contents with `unwrap`.
|
||||
//! let final_awesome_result = good_result.unwrap();
|
||||
|
@ -85,35 +85,32 @@
|
|||
//! functions that may encounter errors but don't otherwise return a
|
||||
//! useful value.
|
||||
//!
|
||||
//! Consider the `write_line` method defined for I/O types
|
||||
//! by the [`Writer`](../old_io/trait.Writer.html) trait:
|
||||
//! Consider the `write_all` method defined for I/O types
|
||||
//! by the [`Write`](../io/trait.Write.html) trait:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(old_io)]
|
||||
//! use std::old_io::IoError;
|
||||
//! use std::io;
|
||||
//!
|
||||
//! trait Writer {
|
||||
//! fn write_line(&mut self, s: &str) -> Result<(), IoError>;
|
||||
//! fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>;
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! *Note: The actual definition of `Writer` uses `IoResult`, which
|
||||
//! is just a synonym for `Result<T, IoError>`.*
|
||||
//! *Note: The actual definition of `Write` uses `io::Result`, which
|
||||
//! is just a synonym for `Result<T, io::Error>`.*
|
||||
//!
|
||||
//! This method doesn't produce a value, but the write may
|
||||
//! fail. It's crucial to handle the error case, and *not* write
|
||||
//! something like this:
|
||||
//!
|
||||
//! ```{.ignore}
|
||||
//! # #![feature(old_io)]
|
||||
//! use std::old_io::*;
|
||||
//! use std::old_path::Path;
|
||||
//! ```no_run
|
||||
//! use std::fs::File;
|
||||
//! use std::io::prelude::*;
|
||||
//!
|
||||
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
|
||||
//! // If `write_line` errors, then we'll never know, because the return
|
||||
//! let mut file = File::create("valuable_data.txt").unwrap();
|
||||
//! // If `write_all` errors, then we'll never know, because the return
|
||||
//! // value is ignored.
|
||||
//! file.write_line("important message");
|
||||
//! drop(file);
|
||||
//! file.write_all(b"important message");
|
||||
//! ```
|
||||
//!
|
||||
//! If you *do* write that in Rust, the compiler will give you a
|
||||
|
@ -125,37 +122,31 @@
|
|||
//! a marginally useful message indicating why:
|
||||
//!
|
||||
//! ```{.no_run}
|
||||
//! # #![feature(old_io, old_path)]
|
||||
//! use std::old_io::*;
|
||||
//! use std::old_path::Path;
|
||||
//! use std::fs::File;
|
||||
//! use std::io::prelude::*;
|
||||
//!
|
||||
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
|
||||
//! file.write_line("important message").ok().expect("failed to write message");
|
||||
//! drop(file);
|
||||
//! let mut file = File::create("valuable_data.txt").unwrap();
|
||||
//! file.write_all(b"important message").ok().expect("failed to write message");
|
||||
//! ```
|
||||
//!
|
||||
//! You might also simply assert success:
|
||||
//!
|
||||
//! ```{.no_run}
|
||||
//! # #![feature(old_io, old_path)]
|
||||
//! # use std::old_io::*;
|
||||
//! # use std::old_path::Path;
|
||||
//!
|
||||
//! # let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
|
||||
//! assert!(file.write_line("important message").is_ok());
|
||||
//! # drop(file);
|
||||
//! # use std::fs::File;
|
||||
//! # use std::io::prelude::*;
|
||||
//! # let mut file = File::create("valuable_data.txt").unwrap();
|
||||
//! assert!(file.write_all(b"important message").is_ok());
|
||||
//! ```
|
||||
//!
|
||||
//! Or propagate the error up the call stack with `try!`:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(old_io, old_path)]
|
||||
//! # use std::old_io::*;
|
||||
//! # use std::old_path::Path;
|
||||
//! fn write_message() -> Result<(), IoError> {
|
||||
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
|
||||
//! try!(file.write_line("important message"));
|
||||
//! drop(file);
|
||||
//! # use std::fs::File;
|
||||
//! # use std::io::prelude::*;
|
||||
//! # use std::io;
|
||||
//! fn write_message() -> io::Result<()> {
|
||||
//! let mut file = try!(File::create("valuable_data.txt"));
|
||||
//! try!(file.write_all(b"important message"));
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
|
@ -170,9 +161,9 @@
|
|||
//! It replaces this:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(old_io, old_path)]
|
||||
//! use std::old_io::*;
|
||||
//! use std::old_path::Path;
|
||||
//! use std::fs::File;
|
||||
//! use std::io::prelude::*;
|
||||
//! use std::io;
|
||||
//!
|
||||
//! struct Info {
|
||||
//! name: String,
|
||||
|
@ -180,25 +171,28 @@
|
|||
//! rating: i32,
|
||||
//! }
|
||||
//!
|
||||
//! fn write_info(info: &Info) -> Result<(), IoError> {
|
||||
//! let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
|
||||
//! fn write_info(info: &Info) -> io::Result<()> {
|
||||
//! let mut file = try!(File::create("my_best_friends.txt"));
|
||||
//! // Early return on error
|
||||
//! if let Err(e) = file.write_line(&format!("name: {}", info.name)) {
|
||||
//! if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) {
|
||||
//! return Err(e)
|
||||
//! }
|
||||
//! if let Err(e) = file.write_line(&format!("age: {}", info.age)) {
|
||||
//! if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) {
|
||||
//! return Err(e)
|
||||
//! }
|
||||
//! file.write_line(&format!("rating: {}", info.rating))
|
||||
//! if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) {
|
||||
//! return Err(e)
|
||||
//! }
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! With this:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(old_io, old_path)]
|
||||
//! use std::old_io::*;
|
||||
//! use std::old_path::Path;
|
||||
//! use std::fs::File;
|
||||
//! use std::io::prelude::*;
|
||||
//! use std::io;
|
||||
//!
|
||||
//! struct Info {
|
||||
//! name: String,
|
||||
|
@ -206,12 +200,12 @@
|
|||
//! rating: i32,
|
||||
//! }
|
||||
//!
|
||||
//! fn write_info(info: &Info) -> Result<(), IoError> {
|
||||
//! let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
|
||||
//! fn write_info(info: &Info) -> io::Result<()> {
|
||||
//! let mut file = try!(File::create("my_best_friends.txt"));
|
||||
//! // Early return on error
|
||||
//! try!(file.write_line(&format!("name: {}", info.name)));
|
||||
//! try!(file.write_line(&format!("age: {}", info.age)));
|
||||
//! try!(file.write_line(&format!("rating: {}", info.rating)));
|
||||
//! try!(file.write_all(format!("name: {}\n", info.name).as_bytes()));
|
||||
//! try!(file.write_all(format!("age: {}\n", info.age).as_bytes()));
|
||||
//! try!(file.write_all(format!("rating: {}\n", info.rating).as_bytes()));
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
|
@ -311,7 +305,7 @@ impl<T, E> Result<T, E> {
|
|||
// Adapter for each variant
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Convert from `Result<T, E>` to `Option<T>`
|
||||
/// Converts from `Result<T, E>` to `Option<T>`
|
||||
///
|
||||
/// Converts `self` into an `Option<T>`, consuming `self`,
|
||||
/// and discarding the error, if any.
|
||||
|
@ -334,7 +328,7 @@ impl<T, E> Result<T, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert from `Result<T, E>` to `Option<E>`
|
||||
/// Converts from `Result<T, E>` to `Option<E>`
|
||||
///
|
||||
/// Converts `self` into an `Option<E>`, consuming `self`,
|
||||
/// and discarding the success value, if any.
|
||||
|
@ -361,7 +355,7 @@ impl<T, E> Result<T, E> {
|
|||
// Adapter for working with references
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Convert from `Result<T, E>` to `Result<&T, &E>`
|
||||
/// Converts from `Result<T, E>` to `Result<&T, &E>`
|
||||
///
|
||||
/// Produces a new `Result`, containing a reference
|
||||
/// into the original, leaving the original in place.
|
||||
|
@ -382,7 +376,7 @@ impl<T, E> Result<T, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
|
||||
/// Converts from `Result<T, E>` to `Result<&mut T, &mut E>`
|
||||
///
|
||||
/// ```
|
||||
/// fn mutate(r: &mut Result<i32, i32>) {
|
||||
|
@ -409,7 +403,7 @@ impl<T, E> Result<T, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert from `Result<T, E>` to `&[T]` (without copying)
|
||||
/// Converts from `Result<T, E>` to `&[T]` (without copying)
|
||||
#[inline]
|
||||
#[unstable(feature = "as_slice", since = "unsure of the utility here")]
|
||||
pub fn as_slice(&self) -> &[T] {
|
||||
|
@ -423,7 +417,7 @@ impl<T, E> Result<T, E> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert from `Result<T, E>` to `&mut [T]` (without copying)
|
||||
/// Converts from `Result<T, E>` to `&mut [T]` (without copying)
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(core)]
|
||||
|
@ -464,29 +458,17 @@ impl<T, E> Result<T, E> {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Sum the lines of a buffer by mapping strings to numbers,
|
||||
/// ignoring I/O and parse errors:
|
||||
/// Print the numbers on each line of a string multiplied by two.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(old_io)]
|
||||
/// use std::old_io::*;
|
||||
/// let line = "1\n2\n3\n4\n";
|
||||
///
|
||||
/// let mut buffer: &[u8] = b"1\n2\n3\n4\n";
|
||||
/// let mut buffer = &mut buffer;
|
||||
///
|
||||
/// let mut sum = 0;
|
||||
///
|
||||
/// while !buffer.is_empty() {
|
||||
/// let line: IoResult<String> = buffer.read_line();
|
||||
/// // Convert the string line to a number using `map` and `from_str`
|
||||
/// let val: IoResult<i32> = line.map(|line| {
|
||||
/// line.trim_right().parse::<i32>().unwrap_or(0)
|
||||
/// });
|
||||
/// // Add the value if there were no errors, otherwise add 0
|
||||
/// sum += val.unwrap_or(0);
|
||||
/// for num in line.lines() {
|
||||
/// match num.parse::<i32>().map(|i| i * 2) {
|
||||
/// Ok(n) => println!("{}", n),
|
||||
/// Err(..) => {}
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert!(sum == 10);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -811,7 +793,7 @@ impl<T: fmt::Debug, E> Result<T, E> {
|
|||
reason = "use inherent method instead")]
|
||||
#[allow(deprecated)]
|
||||
impl<T, E> AsSlice<T> for Result<T, E> {
|
||||
/// Convert from `Result<T, E>` to `&[T]` (without copying)
|
||||
/// Converts from `Result<T, E>` to `&[T]` (without copying)
|
||||
#[inline]
|
||||
fn as_slice<'a>(&'a self) -> &'a [T] {
|
||||
match *self {
|
||||
|
@ -974,7 +956,7 @@ 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.
|
||||
/// Performs a fold operation over the result values from an iterator.
|
||||
///
|
||||
/// If an `Err` is encountered, it is immediately returned.
|
||||
/// Otherwise, the folded value is returned.
|
||||
|
|
|
@ -106,19 +106,19 @@ Section: Creating a string
|
|||
|
||||
/// Errors which can occur when attempting to interpret a byte slice as a `str`.
|
||||
#[derive(Copy, Eq, PartialEq, Clone, Debug)]
|
||||
#[unstable(feature = "core",
|
||||
reason = "error enumeration recently added and definitions may be refined")]
|
||||
pub enum Utf8Error {
|
||||
/// An invalid byte was detected at the byte offset given.
|
||||
///
|
||||
/// The offset is guaranteed to be in bounds of the slice in question, and
|
||||
/// the byte at the specified offset was the first invalid byte in the
|
||||
/// sequence detected.
|
||||
InvalidByte(usize),
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Utf8Error {
|
||||
valid_up_to: usize,
|
||||
}
|
||||
|
||||
/// The byte slice was invalid because more bytes were needed but no more
|
||||
/// bytes were available.
|
||||
TooShort,
|
||||
impl Utf8Error {
|
||||
/// Returns the index in the given string up to which valid UTF-8 was
|
||||
/// verified.
|
||||
///
|
||||
/// Starting at the index provided, but not necessarily at it precisely, an
|
||||
/// invalid UTF-8 encoding sequence was found.
|
||||
#[unstable(feature = "utf8_error", reason = "method just added")]
|
||||
pub fn valid_up_to(&self) -> usize { self.valid_up_to }
|
||||
}
|
||||
|
||||
/// Converts a slice of bytes to a string slice without performing any
|
||||
|
@ -147,14 +147,7 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for Utf8Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Utf8Error::InvalidByte(n) => {
|
||||
write!(f, "invalid utf-8: invalid byte at index {}", n)
|
||||
}
|
||||
Utf8Error::TooShort => {
|
||||
write!(f, "invalid utf-8: byte slice too short")
|
||||
}
|
||||
}
|
||||
write!(f, "invalid utf-8: invalid byte near index {}", self.valid_up_to)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,14 +1211,16 @@ fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
|
|||
// restore the iterator we had at the start of this codepoint.
|
||||
macro_rules! err { () => {{
|
||||
*iter = old.clone();
|
||||
return Err(Utf8Error::InvalidByte(whole.len() - iter.as_slice().len()))
|
||||
return Err(Utf8Error {
|
||||
valid_up_to: whole.len() - iter.as_slice().len()
|
||||
})
|
||||
}}}
|
||||
|
||||
macro_rules! next { () => {
|
||||
match iter.next() {
|
||||
Some(a) => *a,
|
||||
// we needed data, but there was none: error!
|
||||
None => return Err(Utf8Error::TooShort),
|
||||
None => err!(),
|
||||
}
|
||||
}}
|
||||
|
||||
|
|
|
@ -32,17 +32,17 @@ pub trait Pattern<'a>: Sized {
|
|||
/// Associated searcher for this pattern
|
||||
type Searcher: Searcher<'a>;
|
||||
|
||||
/// Construct the associated searcher from
|
||||
/// Constructs the associated searcher from
|
||||
/// `self` and the `haystack` to search in.
|
||||
fn into_searcher(self, haystack: &'a str) -> Self::Searcher;
|
||||
|
||||
/// Check whether the pattern matches anywhere in the haystack
|
||||
/// Checks whether the pattern matches anywhere in the haystack
|
||||
#[inline]
|
||||
fn is_contained_in(self, haystack: &'a str) -> bool {
|
||||
self.into_searcher(haystack).next_match().is_some()
|
||||
}
|
||||
|
||||
/// Check whether the pattern matches at the front of the haystack
|
||||
/// Checks whether the pattern matches at the front of the haystack
|
||||
#[inline]
|
||||
fn is_prefix_of(self, haystack: &'a str) -> bool {
|
||||
match self.into_searcher(haystack).next() {
|
||||
|
@ -51,7 +51,7 @@ pub trait Pattern<'a>: Sized {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check whether the pattern matches at the back of the haystack
|
||||
/// Checks whether the pattern matches at the back of the haystack
|
||||
#[inline]
|
||||
fn is_suffix_of(self, haystack: &'a str) -> bool
|
||||
where Self::Searcher: ReverseSearcher<'a>
|
||||
|
|
|
@ -169,42 +169,42 @@ fn test_radix_base_too_large() {
|
|||
mod u32 {
|
||||
use test::Bencher;
|
||||
use core::fmt::radix;
|
||||
use std::rand::{weak_rng, Rng};
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
use std::io::{Write, sink};
|
||||
|
||||
#[bench]
|
||||
fn format_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<u32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<u32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{}", rng.gen::<u32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<u32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_show(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<u32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<u32>(), 36)) })
|
||||
}
|
||||
}
|
||||
|
@ -212,42 +212,42 @@ mod u32 {
|
|||
mod i32 {
|
||||
use test::Bencher;
|
||||
use core::fmt::radix;
|
||||
use std::rand::{weak_rng, Rng};
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
use std::io::{Write, sink};
|
||||
|
||||
#[bench]
|
||||
fn format_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<i32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<i32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{}", rng.gen::<i32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<i32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_show(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<i32>()) })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<i32>(), 36)) })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,12 +155,11 @@ pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes,Error> {
|
|||
mod tests {
|
||||
#![allow(deprecated)]
|
||||
use super::{inflate_bytes, deflate_bytes};
|
||||
use std::rand;
|
||||
use std::rand::Rng;
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
|
||||
#[test]
|
||||
fn test_flate_round_trip() {
|
||||
let mut r = rand::thread_rng();
|
||||
let mut r = thread_rng();
|
||||
let mut words = vec![];
|
||||
for _ in 0..20 {
|
||||
let range = r.gen_range(1, 10);
|
||||
|
|
|
@ -3344,6 +3344,8 @@ pub mod consts {
|
|||
pub const _SC_XOPEN_REALTIME : c_int = 130;
|
||||
pub const _SC_XOPEN_REALTIME_THREADS : c_int = 131;
|
||||
|
||||
|
||||
|
||||
pub const PTHREAD_CREATE_JOINABLE: c_int = 0;
|
||||
pub const PTHREAD_CREATE_DETACHED: c_int = 1;
|
||||
|
||||
|
@ -3727,12 +3729,14 @@ pub mod consts {
|
|||
pub const _SC_2_FORT_RUN : c_int = 50;
|
||||
pub const _SC_2_SW_DEV : c_int = 51;
|
||||
pub const _SC_2_LOCALEDEF : c_int = 52;
|
||||
pub const _SC_NPROCESSORS_ONLN : c_int = 84;
|
||||
pub const _SC_2_CHAR_TERM : c_int = 95;
|
||||
pub const _SC_2_C_VERSION : c_int = 96;
|
||||
pub const _SC_2_UPE : c_int = 97;
|
||||
pub const _SC_XBS5_ILP32_OFF32 : c_int = 125;
|
||||
pub const _SC_XBS5_ILP32_OFFBIG : c_int = 126;
|
||||
pub const _SC_XBS5_LPBIG_OFFBIG : c_int = 128;
|
||||
|
||||
}
|
||||
#[cfg(target_os = "nacl")]
|
||||
pub mod sysconf {
|
||||
|
@ -3742,6 +3746,13 @@ pub mod consts {
|
|||
pub static _SC_NPROCESSORS_ONLN : c_int = 1;
|
||||
pub static _SC_PAGESIZE : c_int = 2;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod sysconf {
|
||||
use types::os::arch::c95::c_int;
|
||||
pub static _SC_NPROCESSORS_ONLN : c_int = 58;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod sysconf {
|
||||
use types::os::arch::c95::c_int;
|
||||
|
|
|
@ -56,18 +56,6 @@ impl Rand for Exp1 {
|
|||
///
|
||||
/// This distribution has density function: `f(x) = lambda *
|
||||
/// exp(-lambda * x)` for `x > 0`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Exp, IndependentSample};
|
||||
///
|
||||
/// let exp = Exp::new(2.0);
|
||||
/// let v = exp.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a Exp(2) distribution", v);
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Exp {
|
||||
/// `lambda` stored as `1/lambda`, since this is what we scale by.
|
||||
|
|
|
@ -37,18 +37,6 @@ use super::{IndependentSample, Sample, Exp};
|
|||
/// == 1`, and using the boosting technique described in [1] for
|
||||
/// `shape < 1`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{IndependentSample, Gamma};
|
||||
///
|
||||
/// let gamma = Gamma::new(2.0, 5.0);
|
||||
/// let v = gamma.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a Gamma(2, 5) distribution", v);
|
||||
/// ```
|
||||
///
|
||||
/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
|
||||
/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
|
||||
/// (September 2000),
|
||||
|
@ -184,18 +172,6 @@ impl IndependentSample<f64> for GammaLargeShape {
|
|||
/// of `k` independent standard normal random variables. For other
|
||||
/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
|
||||
/// 2)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{ChiSquared, IndependentSample};
|
||||
///
|
||||
/// let chi = ChiSquared::new(11.0);
|
||||
/// let v = chi.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a χ²(11) distribution", v)
|
||||
/// ```
|
||||
pub struct ChiSquared {
|
||||
repr: ChiSquaredRepr,
|
||||
}
|
||||
|
@ -242,18 +218,6 @@ impl IndependentSample<f64> for ChiSquared {
|
|||
/// This distribution is equivalent to the ratio of two normalised
|
||||
/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
|
||||
/// (χ²(n)/n)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{FisherF, IndependentSample};
|
||||
///
|
||||
/// let f = FisherF::new(2.0, 32.0);
|
||||
/// let v = f.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from an F(2, 32) distribution", v)
|
||||
/// ```
|
||||
pub struct FisherF {
|
||||
numer: ChiSquared,
|
||||
denom: ChiSquared,
|
||||
|
@ -287,18 +251,6 @@ impl IndependentSample<f64> for FisherF {
|
|||
|
||||
/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
|
||||
/// freedom.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{StudentT, IndependentSample};
|
||||
///
|
||||
/// let t = StudentT::new(11.0);
|
||||
/// let v = t.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a t(11) distribution", v)
|
||||
/// ```
|
||||
pub struct StudentT {
|
||||
chi: ChiSquared,
|
||||
dof: f64
|
||||
|
|
|
@ -90,24 +90,6 @@ pub struct Weighted<T> {
|
|||
/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
|
||||
/// all `T`, as is `usize`, so one can store references or indices into
|
||||
/// another vector.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
|
||||
///
|
||||
/// let mut items = vec!(Weighted { weight: 2, item: 'a' },
|
||||
/// Weighted { weight: 4, item: 'b' },
|
||||
/// Weighted { weight: 1, item: 'c' });
|
||||
/// let wc = WeightedChoice::new(&mut items[..]);
|
||||
/// let mut rng = rand::thread_rng();
|
||||
/// for _ in 0..16 {
|
||||
/// // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
|
||||
/// println!("{}", wc.ind_sample(&mut rng));
|
||||
/// }
|
||||
/// ```
|
||||
pub struct WeightedChoice<'a, T:'a> {
|
||||
items: &'a mut [Weighted<T>],
|
||||
weight_range: Range<usize>
|
||||
|
|
|
@ -72,19 +72,6 @@ impl Rand for StandardNormal {
|
|||
///
|
||||
/// This uses the ZIGNOR variant of the Ziggurat method, see
|
||||
/// `StandardNormal` for more details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Normal, IndependentSample};
|
||||
///
|
||||
/// // mean 2, standard deviation 3
|
||||
/// let normal = Normal::new(2.0, 3.0);
|
||||
/// let v = normal.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a N(2, 9) distribution", v)
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Normal {
|
||||
mean: f64,
|
||||
|
@ -121,19 +108,6 @@ impl IndependentSample<f64> for Normal {
|
|||
///
|
||||
/// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
|
||||
/// std_dev**2)` distributed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{LogNormal, IndependentSample};
|
||||
///
|
||||
/// // mean 2, standard deviation 3
|
||||
/// let log_normal = LogNormal::new(2.0, 3.0);
|
||||
/// let v = log_normal.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from an ln N(2, 9) distribution", v)
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LogNormal {
|
||||
norm: Normal
|
||||
|
|
|
@ -32,23 +32,6 @@ use distributions::{Sample, IndependentSample};
|
|||
/// including `high`, but this may be very difficult. All the
|
||||
/// primitive integer types satisfy this property, and the float types
|
||||
/// normally satisfy it, but rounding may mean `high` can occur.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::distributions::{IndependentSample, Range};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let between = Range::new(10, 10000);
|
||||
/// let mut rng = std::rand::thread_rng();
|
||||
/// let mut sum = 0;
|
||||
/// for _ in 0..1000 {
|
||||
/// sum += between.ind_sample(&mut rng);
|
||||
/// }
|
||||
/// println!("{}", sum);
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Range<X> {
|
||||
low: X,
|
||||
range: X,
|
||||
|
|
|
@ -24,15 +24,13 @@
|
|||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
#![feature(no_std)]
|
||||
#![no_std]
|
||||
#![unstable(feature = "rand")]
|
||||
#![feature(staged_api)]
|
||||
#![staged_api]
|
||||
#![unstable(feature = "rand")]
|
||||
#![feature(core)]
|
||||
#![feature(no_std)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(step_by)]
|
||||
#![deprecated(reason = "use the crates.io `rand` library instead",
|
||||
since = "1.0.0-alpha")]
|
||||
|
||||
#![cfg_attr(test, feature(test, rand, rustc_private))]
|
||||
|
||||
|
@ -145,17 +143,6 @@ pub trait Rng : Sized {
|
|||
/// with new data, and may panic if this is impossible
|
||||
/// (e.g. reading past the end of a file that is being used as the
|
||||
/// source of randomness).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand, core)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut v = [0; 13579];
|
||||
/// thread_rng().fill_bytes(&mut v);
|
||||
/// println!("{:?}", &v[..]);
|
||||
/// ```
|
||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
||||
// this could, in theory, be done by transmuting dest to a
|
||||
// [u64], but this is (1) likely to be undefined behaviour for
|
||||
|
@ -181,18 +168,6 @@ pub trait Rng : Sized {
|
|||
}
|
||||
|
||||
/// Return a random value of a `Rand` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let x: usize = rng.gen();
|
||||
/// println!("{}", x);
|
||||
/// println!("{:?}", rng.gen::<(f64, bool)>());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
fn gen<T: Rand>(&mut self) -> T {
|
||||
Rand::rand(self)
|
||||
|
@ -200,19 +175,6 @@ pub trait Rng : Sized {
|
|||
|
||||
/// Return an iterator that will yield an infinite number of randomly
|
||||
/// generated items.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let x = rng.gen_iter::<usize>().take(10).collect::<Vec<usize>>();
|
||||
/// println!("{:?}", x);
|
||||
/// println!("{:?}", rng.gen_iter::<(f64, bool)>().take(5)
|
||||
/// .collect::<Vec<(f64, bool)>>());
|
||||
/// ```
|
||||
fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
|
||||
Generator { rng: self, _marker: PhantomData }
|
||||
}
|
||||
|
@ -228,50 +190,17 @@ pub trait Rng : Sized {
|
|||
/// # Panics
|
||||
///
|
||||
/// Panics if `low >= high`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let n: usize = rng.gen_range(0, 10);
|
||||
/// println!("{}", n);
|
||||
/// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
|
||||
/// println!("{}", m);
|
||||
/// ```
|
||||
fn gen_range<T: PartialOrd + SampleRange>(&mut self, low: T, high: T) -> T {
|
||||
assert!(low < high, "Rng.gen_range called with low >= high");
|
||||
Range::new(low, high).ind_sample(self)
|
||||
}
|
||||
|
||||
/// Return a bool with a 1 in n chance of true
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// println!("{}", rng.gen_weighted_bool(3));
|
||||
/// ```
|
||||
fn gen_weighted_bool(&mut self, n: usize) -> bool {
|
||||
n <= 1 || self.gen_range(0, n) == 0
|
||||
}
|
||||
|
||||
/// Return an iterator of random characters from the set A-Z,a-z,0-9.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let s: String = thread_rng().gen_ascii_chars().take(10).collect();
|
||||
/// println!("{}", s);
|
||||
/// ```
|
||||
fn gen_ascii_chars<'a>(&'a mut self) -> AsciiGenerator<'a, Self> {
|
||||
AsciiGenerator { rng: self }
|
||||
}
|
||||
|
@ -279,18 +208,6 @@ pub trait Rng : Sized {
|
|||
/// Return a random element from `values`.
|
||||
///
|
||||
/// Return `None` if `values` is empty.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let choices = [1, 2, 4, 8, 16, 32];
|
||||
/// let mut rng = thread_rng();
|
||||
/// println!("{:?}", rng.choose(&choices));
|
||||
/// assert_eq!(rng.choose(&choices[..0]), None);
|
||||
/// ```
|
||||
fn choose<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
|
||||
if values.is_empty() {
|
||||
None
|
||||
|
@ -300,20 +217,6 @@ pub trait Rng : Sized {
|
|||
}
|
||||
|
||||
/// Shuffle a mutable slice in place.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand, core)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let mut y = [1, 2, 3];
|
||||
/// rng.shuffle(&mut y);
|
||||
/// println!("{:?}", y);
|
||||
/// rng.shuffle(&mut y);
|
||||
/// println!("{:?}", y);
|
||||
/// ```
|
||||
fn shuffle<T>(&mut self, values: &mut [T]) {
|
||||
let mut i = values.len();
|
||||
while i >= 2 {
|
||||
|
@ -364,33 +267,9 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
|
|||
/// the same stream of randomness multiple times.
|
||||
pub trait SeedableRng<Seed>: Rng {
|
||||
/// Reseed an RNG with the given seed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{Rng, SeedableRng, StdRng};
|
||||
///
|
||||
/// let seed: &[_] = &[1, 2, 3, 4];
|
||||
/// let mut rng: StdRng = SeedableRng::from_seed(seed);
|
||||
/// println!("{}", rng.gen::<f64>());
|
||||
/// rng.reseed(&[5, 6, 7, 8]);
|
||||
/// println!("{}", rng.gen::<f64>());
|
||||
/// ```
|
||||
fn reseed(&mut self, Seed);
|
||||
|
||||
/// Create a new RNG with the given seed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{Rng, SeedableRng, StdRng};
|
||||
///
|
||||
/// let seed: &[_] = &[1, 2, 3, 4];
|
||||
/// let mut rng: StdRng = SeedableRng::from_seed(seed);
|
||||
/// println!("{}", rng.gen::<f64>());
|
||||
/// ```
|
||||
fn from_seed(seed: Seed) -> Self;
|
||||
}
|
||||
|
||||
|
@ -486,16 +365,6 @@ impl Rand for XorShiftRng {
|
|||
/// Use `Closed01` for the closed interval `[0,1]`, and the default
|
||||
/// `Rand` implementation for `f32` and `f64` for the half-open
|
||||
/// `[0,1)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{random, Open01};
|
||||
///
|
||||
/// let Open01(val) = random::<Open01<f32>>();
|
||||
/// println!("f32 from (0,1): {}", val);
|
||||
/// ```
|
||||
pub struct Open01<F>(pub F);
|
||||
|
||||
/// A wrapper for generating floating point numbers uniformly in the
|
||||
|
@ -504,31 +373,17 @@ pub struct Open01<F>(pub F);
|
|||
/// Use `Open01` for the closed interval `(0,1)`, and the default
|
||||
/// `Rand` implementation of `f32` and `f64` for the half-open
|
||||
/// `[0,1)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{random, Closed01};
|
||||
///
|
||||
/// let Closed01(val) = random::<Closed01<f32>>();
|
||||
/// println!("f32 from [0,1]: {}", val);
|
||||
/// ```
|
||||
pub struct Closed01<F>(pub F);
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::rand;
|
||||
use std::__rand as rand;
|
||||
|
||||
pub struct MyRng<R> { inner: R }
|
||||
|
||||
impl<R: rand::Rng> ::Rng for MyRng<R> {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
fn next<T: rand::Rng>(t: &mut T) -> u32 {
|
||||
use std::rand::Rng;
|
||||
t.next_u32()
|
||||
}
|
||||
next(&mut self.inner)
|
||||
rand::Rng::next_u32(&mut self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,7 +391,7 @@ mod test {
|
|||
MyRng { inner: rand::thread_rng() }
|
||||
}
|
||||
|
||||
pub fn weak_rng() -> MyRng<rand::XorShiftRng> {
|
||||
MyRng { inner: rand::weak_rng() }
|
||||
pub fn weak_rng() -> MyRng<rand::ThreadRng> {
|
||||
MyRng { inner: rand::thread_rng() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,55 +211,3 @@ impl<T:Rand> Rand for Option<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rand::{Rng, thread_rng, Open01, Closed01};
|
||||
|
||||
struct ConstantRng(u64);
|
||||
impl Rng for ConstantRng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
let ConstantRng(v) = *self;
|
||||
v as u32
|
||||
}
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
let ConstantRng(v) = *self;
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn floating_point_edge_cases() {
|
||||
// the test for exact equality is correct here.
|
||||
assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
|
||||
assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rand_open() {
|
||||
// this is unlikely to catch an incorrect implementation that
|
||||
// generates exactly 0 or 1, but it keeps it sane.
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..1_000 {
|
||||
// strict inequalities
|
||||
let Open01(f) = rng.gen::<Open01<f64>>();
|
||||
assert!(0.0 < f && f < 1.0);
|
||||
|
||||
let Open01(f) = rng.gen::<Open01<f32>>();
|
||||
assert!(0.0 < f && f < 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rand_closed() {
|
||||
let mut rng = thread_rng();
|
||||
for _ in 0..1_000 {
|
||||
// strict inequalities
|
||||
let Closed01(f) = rng.gen::<Closed01<f64>>();
|
||||
assert!(0.0 <= f && f <= 1.0);
|
||||
|
||||
let Closed01(f) = rng.gen::<Closed01<f32>>();
|
||||
assert!(0.0 <= f && f <= 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,34 +99,6 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
|
|||
}
|
||||
|
||||
/// Something that can be used to reseed an RNG via `ReseedingRng`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{Rng, SeedableRng, StdRng};
|
||||
/// use std::rand::reseeding::{Reseeder, ReseedingRng};
|
||||
///
|
||||
/// struct TickTockReseeder { tick: bool }
|
||||
/// impl Reseeder<StdRng> for TickTockReseeder {
|
||||
/// fn reseed(&mut self, rng: &mut StdRng) {
|
||||
/// let val = if self.tick {0} else {1};
|
||||
/// rng.reseed(&[val]);
|
||||
/// self.tick = !self.tick;
|
||||
/// }
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// let rsdr = TickTockReseeder { tick: true };
|
||||
///
|
||||
/// let inner = StdRng::new().unwrap();
|
||||
/// let mut rng = ReseedingRng::new(inner, 10, rsdr);
|
||||
///
|
||||
/// // this will repeat, because it gets reseeded very regularly.
|
||||
/// let s: String = rng.gen_ascii_chars().take(100).collect();
|
||||
/// println!("{}", s);
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub trait Reseeder<R> {
|
||||
/// Reseed the given RNG.
|
||||
fn reseed(&mut self, rng: &mut R);
|
||||
|
|
|
@ -562,7 +562,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
|||
span: codemap::Span, id: ast::NodeId) {
|
||||
// Have to warn method here because methods are not ast::Item
|
||||
match fk {
|
||||
visit::FkMethod(name, _) => {
|
||||
visit::FkMethod(name, _, _) => {
|
||||
if !self.symbol_is_live(id, None) {
|
||||
self.warn_dead_code(id, span, name.name, "method");
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
block: &'v ast::Block, span: Span, _: ast::NodeId) {
|
||||
|
||||
let (is_item_fn, is_unsafe_fn) = match fn_kind {
|
||||
visit::FkItemFn(_, _, fn_style, _) =>
|
||||
visit::FkItemFn(_, _, fn_style, _, _) =>
|
||||
(true, fn_style == ast::Unsafety::Unsafe),
|
||||
visit::FkMethod(_, sig) =>
|
||||
visit::FkMethod(_, sig, _) =>
|
||||
(true, sig.unsafety == ast::Unsafety::Unsafe),
|
||||
_ => (false, false),
|
||||
};
|
||||
|
|
|
@ -142,12 +142,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
|
||||
b: &'v ast::Block, s: Span, _: ast::NodeId) {
|
||||
match fk {
|
||||
visit::FkItemFn(_, generics, _, _) => {
|
||||
visit::FkItemFn(_, generics, _, _, _) => {
|
||||
self.visit_early_late(subst::FnSpace, generics, |this| {
|
||||
visit::walk_fn(this, fk, fd, b, s)
|
||||
})
|
||||
}
|
||||
visit::FkMethod(_, sig) => {
|
||||
visit::FkMethod(_, sig, _) => {
|
||||
self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
|
||||
visit::walk_fn(this, fk, fd, b, s)
|
||||
})
|
||||
|
|
|
@ -96,8 +96,8 @@ impl<'a> Annotator<'a> {
|
|||
if tag == "unstable" || tag == "stable" || tag == "deprecated" {
|
||||
attr::mark_used(attr);
|
||||
self.sess.span_warn(attr.span(),
|
||||
"stability attributes are deprecated and \
|
||||
will soon become errors");
|
||||
"stability attributes are deprecated \
|
||||
and will soon become errors");
|
||||
}
|
||||
}
|
||||
f(self);
|
||||
|
|
|
@ -9,69 +9,42 @@
|
|||
// except according to those terms.
|
||||
|
||||
use std::io;
|
||||
use std::env;
|
||||
#[allow(deprecated)] use std::old_path::{self, GenericPath};
|
||||
#[allow(deprecated)] use std::old_io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Returns an absolute path in the filesystem that `path` points to. The
|
||||
/// returned path does not contain any symlinks in its hierarchy.
|
||||
#[allow(deprecated)] // readlink is deprecated
|
||||
#[cfg(windows)]
|
||||
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
|
||||
let old = old_path::Path::new(original.to_str().unwrap());
|
||||
match old_realpath(&old) {
|
||||
Ok(p) => Ok(PathBuf::from(p.as_str().unwrap())),
|
||||
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
|
||||
}
|
||||
Ok(original.to_path_buf())
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
|
||||
use std::old_io::fs;
|
||||
const MAX_LINKS_FOLLOWED: usize = 256;
|
||||
let original = old_path::Path::new(env::current_dir().unwrap()
|
||||
.to_str().unwrap()).join(original);
|
||||
#[cfg(unix)]
|
||||
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
|
||||
use libc;
|
||||
use std::ffi::{OsString, CString};
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
// Right now lstat on windows doesn't work quite well
|
||||
if cfg!(windows) {
|
||||
return Ok(original)
|
||||
extern {
|
||||
fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
|
||||
-> *mut libc::c_char;
|
||||
}
|
||||
|
||||
let result = original.root_path();
|
||||
let mut result = result.expect("make_absolute has no root_path");
|
||||
let mut followed = 0;
|
||||
|
||||
for part in original.components() {
|
||||
result.push(part);
|
||||
|
||||
loop {
|
||||
if followed == MAX_LINKS_FOLLOWED {
|
||||
return Err(old_io::standard_error(old_io::InvalidInput))
|
||||
}
|
||||
|
||||
match fs::lstat(&result) {
|
||||
Err(..) => break,
|
||||
Ok(ref stat) if stat.kind != old_io::FileType::Symlink => break,
|
||||
Ok(..) => {
|
||||
followed += 1;
|
||||
let path = try!(fs::readlink(&result));
|
||||
result.pop();
|
||||
result.push(path);
|
||||
let path = try!(CString::new(original.as_os_str().as_bytes()));
|
||||
let mut buf = vec![0u8; 16 * 1024];
|
||||
unsafe {
|
||||
let r = realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _);
|
||||
if r.is_null() {
|
||||
return Err(io::Error::last_os_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(result);
|
||||
let p = buf.iter().position(|i| *i == 0).unwrap();
|
||||
buf.truncate(p);
|
||||
Ok(PathBuf::from(OsString::from_vec(buf)))
|
||||
}
|
||||
|
||||
#[cfg(all(not(windows), test))]
|
||||
mod test {
|
||||
use std::old_io;
|
||||
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
|
||||
use super::old_realpath as realpath;
|
||||
use std::old_io::TempDir;
|
||||
use std::old_path::{Path, GenericPath};
|
||||
use tempdir::TempDir;
|
||||
use std::fs::{self, File};
|
||||
use super::realpath;
|
||||
|
||||
#[test]
|
||||
fn realpath_works() {
|
||||
|
@ -83,15 +56,15 @@ mod test {
|
|||
let linkdir = tmpdir.join("test3");
|
||||
|
||||
File::create(&file).unwrap();
|
||||
mkdir(&dir, old_io::USER_RWX).unwrap();
|
||||
symlink(&file, &link).unwrap();
|
||||
symlink(&dir, &linkdir).unwrap();
|
||||
fs::create_dir(&dir).unwrap();
|
||||
fs::soft_link(&file, &link).unwrap();
|
||||
fs::soft_link(&dir, &linkdir).unwrap();
|
||||
|
||||
assert!(realpath(&tmpdir).unwrap() == tmpdir);
|
||||
assert!(realpath(&file).unwrap() == file);
|
||||
assert!(realpath(&link).unwrap() == file);
|
||||
assert!(realpath(&linkdir).unwrap() == dir);
|
||||
assert!(realpath(&linkdir.join("link")).unwrap() == file);
|
||||
assert_eq!(realpath(&tmpdir).unwrap(), tmpdir);
|
||||
assert_eq!(realpath(&file).unwrap(), file);
|
||||
assert_eq!(realpath(&link).unwrap(), file);
|
||||
assert_eq!(realpath(&linkdir).unwrap(), dir);
|
||||
assert_eq!(realpath(&linkdir.join("link")).unwrap(), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -106,13 +79,13 @@ mod test {
|
|||
let e = d.join("e");
|
||||
let f = a.join("f");
|
||||
|
||||
mkdir_recursive(&b, old_io::USER_RWX).unwrap();
|
||||
mkdir_recursive(&d, old_io::USER_RWX).unwrap();
|
||||
fs::create_dir_all(&b).unwrap();
|
||||
fs::create_dir_all(&d).unwrap();
|
||||
File::create(&f).unwrap();
|
||||
symlink(&Path::new("../d/e"), &c).unwrap();
|
||||
symlink(&Path::new("../f"), &e).unwrap();
|
||||
fs::soft_link("../d/e", &c).unwrap();
|
||||
fs::soft_link("../f", &e).unwrap();
|
||||
|
||||
assert!(realpath(&c).unwrap() == f);
|
||||
assert!(realpath(&e).unwrap() == f);
|
||||
assert_eq!(realpath(&c).unwrap(), f);
|
||||
assert_eq!(realpath(&e).unwrap(), f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,17 +35,16 @@
|
|||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(core)]
|
||||
#![feature(old_fs)]
|
||||
#![feature(old_io)]
|
||||
#![feature(old_path)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(rand)]
|
||||
#![feature(path_ext)]
|
||||
#![feature(step_by)]
|
||||
#![feature(libc)]
|
||||
#![cfg_attr(test, feature(test, rand))]
|
||||
|
||||
extern crate syntax;
|
||||
extern crate libc;
|
||||
extern crate serialize;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
|
|
|
@ -97,8 +97,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
|
|||
let cwd = env::current_dir().unwrap();
|
||||
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
|
||||
lib.pop();
|
||||
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
|
||||
let mut output = cwd.join(&config.out_filename);
|
||||
output.pop();
|
||||
let output = (config.realpath)(&output).unwrap();
|
||||
let relative = path_relative_from(&lib, &output)
|
||||
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::env;
|
|||
use std::io::{self, Error, ErrorKind};
|
||||
use std::fs;
|
||||
use std::path::{self, PathBuf, Path};
|
||||
use std::rand::{thread_rng, Rng};
|
||||
use std::__rand::{thread_rng, Rng};
|
||||
|
||||
/// A wrapper for a path to temporary directory implementing automatic
|
||||
/// scope-based deletion.
|
||||
|
|
|
@ -957,7 +957,7 @@ impl LintPass for NonSnakeCase {
|
|||
fk: visit::FnKind, _: &ast::FnDecl,
|
||||
_: &ast::Block, span: Span, id: ast::NodeId) {
|
||||
match fk {
|
||||
visit::FkMethod(ident, _) => match method_context(cx, id, span) {
|
||||
visit::FkMethod(ident, _, _) => match method_context(cx, id, span) {
|
||||
MethodContext::PlainImpl => {
|
||||
self.check_snake_case(cx, "method", ident, span)
|
||||
},
|
||||
|
@ -966,7 +966,7 @@ impl LintPass for NonSnakeCase {
|
|||
},
|
||||
_ => (),
|
||||
},
|
||||
visit::FkItemFn(ident, _, _, _) => {
|
||||
visit::FkItemFn(ident, _, _, _, _) => {
|
||||
self.check_snake_case(cx, "function", ident, span)
|
||||
},
|
||||
_ => (),
|
||||
|
@ -1290,10 +1290,10 @@ impl LintPass for UnsafeCode {
|
|||
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
|
||||
_: &ast::Block, span: Span, _: ast::NodeId) {
|
||||
match fk {
|
||||
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
|
||||
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _, _) =>
|
||||
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
|
||||
|
||||
visit::FkMethod(_, sig) => {
|
||||
visit::FkMethod(_, sig, _) => {
|
||||
if sig.unsafety == ast::Unsafety::Unsafe {
|
||||
cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
|
||||
}
|
||||
|
@ -1818,8 +1818,8 @@ impl LintPass for UnconditionalRecursion {
|
|||
ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
|
||||
|
||||
let (name, checker) = match fn_kind {
|
||||
visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F),
|
||||
visit::FkMethod(name, _) => (name, id_refers_to_this_method as F),
|
||||
visit::FkItemFn(name, _, _, _, _) => (name, id_refers_to_this_fn as F),
|
||||
visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
|
||||
// closures can't recur, so they don't matter.
|
||||
visit::FkFnBlock => return
|
||||
};
|
||||
|
|
|
@ -242,11 +242,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
|||
_: Span,
|
||||
node_id: NodeId) {
|
||||
let rib_kind = match function_kind {
|
||||
visit::FkItemFn(_, generics, _, _) => {
|
||||
visit::FkItemFn(_, generics, _, _, _) => {
|
||||
self.visit_generics(generics);
|
||||
ItemRibKind
|
||||
}
|
||||
visit::FkMethod(_, sig) => {
|
||||
visit::FkMethod(_, sig, _) => {
|
||||
self.visit_generics(&sig.generics);
|
||||
self.visit_explicit_self(&sig.explicit_self);
|
||||
MethodRibKind
|
||||
|
|
|
@ -131,8 +131,10 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
|
||||
match b.expr {
|
||||
Some(ref e) => {
|
||||
if !bcx.unreachable.get() {
|
||||
bcx = expr::trans_into(bcx, &**e, dest);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
assert!(dest == expr::Ignore || bcx.unreachable.get());
|
||||
}
|
||||
|
|
|
@ -2616,8 +2616,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
actual)
|
||||
},
|
||||
expr_t, None);
|
||||
if let Some(t) = ty::ty_to_def_id(expr_t) {
|
||||
suggest_field_names(t, field, tcx, vec![]);
|
||||
if let ty::ty_struct(did, _) = expr_t.sty {
|
||||
suggest_field_names(did, field, tcx, vec![]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,9 +78,11 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if (e.which === 191 && $('#help').hasClass('hidden')) { // question mark
|
||||
if (e.which === 191) { // question mark
|
||||
if (e.shiftKey && $('#help').hasClass('hidden')) {
|
||||
e.preventDefault();
|
||||
$('#help').removeClass('hidden');
|
||||
}
|
||||
} else if (e.which === 27) { // esc
|
||||
if (!$('#help').hasClass('hidden')) {
|
||||
e.preventDefault();
|
||||
|
|
|
@ -130,10 +130,10 @@ struct Output {
|
|||
|
||||
pub fn main() {
|
||||
const STACK_SIZE: usize = 32000000; // 32MB
|
||||
let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || {
|
||||
let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
|
||||
let s = env::args().collect::<Vec<_>>();
|
||||
main_args(&s)
|
||||
}).unwrap().join();
|
||||
}).unwrap().join().unwrap();
|
||||
env::set_exit_status(res as i32);
|
||||
}
|
||||
|
||||
|
|
|
@ -2627,9 +2627,9 @@ mod tests {
|
|||
use super::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser,
|
||||
StackElement, Stack, Decoder, Encoder, EncoderError};
|
||||
use std::{i64, u64, f32, f64};
|
||||
use std::io::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use std::string;
|
||||
use std::old_io::Writer;
|
||||
|
||||
#[derive(RustcDecodable, Eq, PartialEq, Debug)]
|
||||
struct OptionData {
|
||||
|
@ -3464,7 +3464,6 @@ mod tests {
|
|||
#[test]
|
||||
fn test_encode_hashmap_with_numeric_key() {
|
||||
use std::str::from_utf8;
|
||||
use std::old_io::Writer;
|
||||
use std::collections::HashMap;
|
||||
let mut hm: HashMap<usize, bool> = HashMap::new();
|
||||
hm.insert(1, true);
|
||||
|
@ -3480,7 +3479,6 @@ mod tests {
|
|||
#[test]
|
||||
fn test_prettyencode_hashmap_with_numeric_key() {
|
||||
use std::str::from_utf8;
|
||||
use std::old_io::Writer;
|
||||
use std::collections::HashMap;
|
||||
let mut hm: HashMap<usize, bool> = HashMap::new();
|
||||
hm.insert(1, true);
|
||||
|
|
|
@ -30,13 +30,12 @@ Core encoding and decoding interfaces.
|
|||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(core)]
|
||||
#![feature(old_path)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(std_misc)]
|
||||
#![feature(unicode)]
|
||||
#![feature(str_char)]
|
||||
#![cfg_attr(test, feature(test, old_io))]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
// test harness access
|
||||
#[cfg(test)] extern crate test;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
Core encoding and decoding interfaces.
|
||||
*/
|
||||
|
||||
#[allow(deprecated)]
|
||||
use std::old_path::{self, GenericPath};
|
||||
use std::path;
|
||||
use std::rc::Rc;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
@ -540,36 +538,6 @@ macro_rules! tuple {
|
|||
|
||||
tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl Encodable for old_path::posix::Path {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
self.as_vec().encode(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl Decodable for old_path::posix::Path {
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<old_path::posix::Path, D::Error> {
|
||||
let bytes: Vec<u8> = try!(Decodable::decode(d));
|
||||
Ok(old_path::posix::Path::new(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl Encodable for old_path::windows::Path {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
self.as_vec().encode(e)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl Decodable for old_path::windows::Path {
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<old_path::windows::Path, D::Error> {
|
||||
let bytes: Vec<u8> = try!(Decodable::decode(d));
|
||||
Ok(old_path::windows::Path::new(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for path::PathBuf {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
self.to_str().unwrap().encode(e)
|
||||
|
|
|
@ -23,12 +23,12 @@ use mem;
|
|||
#[unstable(feature = "std_misc",
|
||||
reason = "would prefer to do this in a more general way")]
|
||||
pub trait OwnedAsciiExt {
|
||||
/// Convert the string to ASCII upper case:
|
||||
/// Converts the string to ASCII upper case:
|
||||
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
|
||||
/// but non-ASCII letters are unchanged.
|
||||
fn into_ascii_uppercase(self) -> Self;
|
||||
|
||||
/// Convert the string to ASCII lower case:
|
||||
/// Converts the string to ASCII lower case:
|
||||
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
|
||||
/// but non-ASCII letters are unchanged.
|
||||
fn into_ascii_lowercase(self) -> Self;
|
||||
|
@ -41,7 +41,7 @@ pub trait AsciiExt {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Owned;
|
||||
|
||||
/// Check if within the ASCII range.
|
||||
/// Checks if within the ASCII range.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -95,7 +95,7 @@ pub trait AsciiExt {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn to_ascii_lowercase(&self) -> Self::Owned;
|
||||
|
||||
/// Check that two strings are an ASCII case-insensitive match.
|
||||
/// Checks that two strings are an ASCII case-insensitive match.
|
||||
///
|
||||
/// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
|
||||
/// but without allocating and copying temporary strings.
|
||||
|
@ -117,7 +117,7 @@ pub trait AsciiExt {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
|
||||
|
||||
/// Convert this type to its ASCII upper case equivalent in-place.
|
||||
/// Converts this type to its ASCII upper case equivalent in-place.
|
||||
///
|
||||
/// See `to_ascii_uppercase` for more information.
|
||||
///
|
||||
|
@ -136,7 +136,7 @@ pub trait AsciiExt {
|
|||
#[unstable(feature = "ascii")]
|
||||
fn make_ascii_uppercase(&mut self);
|
||||
|
||||
/// Convert this type to its ASCII lower case equivalent in-place.
|
||||
/// Converts this type to its ASCII lower case equivalent in-place.
|
||||
///
|
||||
/// See `to_ascii_lowercase` for more information.
|
||||
///
|
||||
|
|
|
@ -506,7 +506,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
}
|
||||
|
||||
impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
|
||||
/// Create an empty HashMap.
|
||||
/// Creates an empty HashMap.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -563,7 +563,7 @@ impl<K, V, S> HashMap<K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
/// Create an empty HashMap with space for at least `capacity`
|
||||
/// Creates an empty HashMap with space for at least `capacity`
|
||||
/// elements, using `hasher` to hash the keys.
|
||||
///
|
||||
/// Warning: `hasher` is normally randomly generated, and
|
||||
|
@ -1596,7 +1596,7 @@ pub struct RandomState {
|
|||
#[unstable(feature = "std_misc",
|
||||
reason = "hashing an hash maps may be altered")]
|
||||
impl RandomState {
|
||||
/// Construct a new `RandomState` that is initialized with random keys.
|
||||
/// Constructs a new `RandomState` that is initialized with random keys.
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub fn new() -> RandomState {
|
||||
|
@ -1631,7 +1631,7 @@ mod test_map {
|
|||
use super::Entry::{Occupied, Vacant};
|
||||
use iter::{range_inclusive, range_step_inclusive, repeat};
|
||||
use cell::RefCell;
|
||||
use rand::{weak_rng, Rng};
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
#[test]
|
||||
fn test_create_capacity_zero() {
|
||||
|
@ -2290,7 +2290,7 @@ mod test_map {
|
|||
}
|
||||
|
||||
let mut m = HashMap::new();
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// Populate the map with some items.
|
||||
for _ in 0..50 {
|
||||
|
|
|
@ -111,7 +111,7 @@ pub struct HashSet<T, S = RandomState> {
|
|||
}
|
||||
|
||||
impl<T: Hash + Eq> HashSet<T, RandomState> {
|
||||
/// Create an empty HashSet.
|
||||
/// Creates an empty HashSet.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -125,7 +125,7 @@ impl<T: Hash + Eq> HashSet<T, RandomState> {
|
|||
HashSet::with_capacity(INITIAL_CAPACITY)
|
||||
}
|
||||
|
||||
/// Create an empty HashSet with space for at least `n` elements in
|
||||
/// Creates an empty HashSet with space for at least `n` elements in
|
||||
/// the hash table.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -166,7 +166,7 @@ impl<T, S> HashSet<T, S>
|
|||
HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state)
|
||||
}
|
||||
|
||||
/// Create an empty HashSet with space for at least `capacity`
|
||||
/// Creates an empty HashSet with space for at least `capacity`
|
||||
/// elements in the hash table, using `hasher` to hash the keys.
|
||||
///
|
||||
/// Warning: `hasher` is normally randomly generated, and
|
||||
|
@ -402,7 +402,7 @@ impl<T, S> HashSet<T, S>
|
|||
Union { iter: self.iter().chain(other.difference(self)) }
|
||||
}
|
||||
|
||||
/// Return the number of elements in the set
|
||||
/// Returns the number of elements in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -417,7 +417,7 @@ impl<T, S> HashSet<T, S>
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn len(&self) -> usize { self.map.len() }
|
||||
|
||||
/// Returns true if the set contains no elements
|
||||
/// Returns true if the set contains no elements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -105,7 +105,7 @@ impl DynamicLibrary {
|
|||
}
|
||||
}
|
||||
|
||||
/// Access the value at the symbol of the dynamic library
|
||||
/// Accesses the value at the symbol of the dynamic library.
|
||||
pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
|
||||
// This function should have a lifetime constraint of 'a on
|
||||
// T but that feature is still unimplemented
|
||||
|
|
|
@ -261,7 +261,7 @@ pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V)
|
|||
os_imp::setenv(k.as_ref(), v.as_ref())
|
||||
}
|
||||
|
||||
/// Remove an environment variable from the environment of the currently running process.
|
||||
/// Removes an environment variable from the environment of the currently running process.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -122,10 +122,7 @@ impl Error for str::ParseBoolError {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Error for str::Utf8Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
str::Utf8Error::TooShort => "invalid utf-8: not enough bytes",
|
||||
str::Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
|
||||
}
|
||||
"invalid utf-8: corrupt contents"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ use io;
|
|||
use iter::Iterator;
|
||||
use libc;
|
||||
use mem;
|
||||
#[allow(deprecated)]
|
||||
use old_io;
|
||||
use ops::Deref;
|
||||
use option::Option::{self, Some, None};
|
||||
use result::Result::{self, Ok, Err};
|
||||
|
@ -133,7 +131,7 @@ pub struct CStr {
|
|||
pub struct NulError(usize, Vec<u8>);
|
||||
|
||||
impl CString {
|
||||
/// Create a new C-compatible string from a container of bytes.
|
||||
/// Creates a new C-compatible string from a container of bytes.
|
||||
///
|
||||
/// This method will consume the provided data and use the underlying bytes
|
||||
/// to construct a new string, ensuring that there is a trailing 0 byte.
|
||||
|
@ -169,11 +167,12 @@ impl CString {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a C-compatible string from a byte vector without checking for
|
||||
/// Creates a C-compatible string from a byte vector without checking for
|
||||
/// interior 0 bytes.
|
||||
///
|
||||
/// This method is equivalent to `from_vec` except that no runtime assertion
|
||||
/// is made that `v` contains no 0 bytes.
|
||||
/// This method is equivalent to `new` except that no runtime assertion
|
||||
/// is made that `v` contains no 0 bytes, and it requires an actual
|
||||
/// byte vector, not anyhting that can be converted to one with Into.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
|
||||
v.push(0);
|
||||
|
@ -215,7 +214,7 @@ impl fmt::Debug for CString {
|
|||
|
||||
impl NulError {
|
||||
/// Returns the position of the nul byte in the slice that was provided to
|
||||
/// `CString::from_vec`.
|
||||
/// `CString::new`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn nul_position(&self) -> usize { self.0 }
|
||||
|
||||
|
@ -245,20 +244,8 @@ impl From<NulError> for io::Error {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow(deprecated)]
|
||||
impl From<NulError> for old_io::IoError {
|
||||
fn from(_: NulError) -> old_io::IoError {
|
||||
old_io::IoError {
|
||||
kind: old_io::IoErrorKind::InvalidInput,
|
||||
desc: "data provided contains a nul byte",
|
||||
detail: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CStr {
|
||||
/// Cast a raw C string to a safe C string wrapper.
|
||||
/// Casts a raw C string to a safe C string wrapper.
|
||||
///
|
||||
/// This function will cast the provided `ptr` to the `CStr` wrapper which
|
||||
/// allows inspection and interoperation of non-owned C strings. This method
|
||||
|
@ -301,7 +288,7 @@ impl CStr {
|
|||
mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
|
||||
}
|
||||
|
||||
/// Return the inner pointer to this C string.
|
||||
/// Returns the inner pointer to this C string.
|
||||
///
|
||||
/// The returned pointer will be valid for as long as `self` is and points
|
||||
/// to a contiguous region of memory terminated with a 0 byte to represent
|
||||
|
@ -311,7 +298,7 @@ impl CStr {
|
|||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
/// Convert this C string to a byte slice.
|
||||
/// Converts this C string to a byte slice.
|
||||
///
|
||||
/// This function will calculate the length of this string (which normally
|
||||
/// requires a linear amount of work to be done) and then return the
|
||||
|
@ -329,7 +316,7 @@ impl CStr {
|
|||
&bytes[..bytes.len() - 1]
|
||||
}
|
||||
|
||||
/// Convert this C string to a byte slice containing the trailing 0 byte.
|
||||
/// Converts this C string to a byte slice containing the trailing 0 byte.
|
||||
///
|
||||
/// This function is the equivalent of `to_bytes` except that it will retain
|
||||
/// the trailing nul instead of chopping it off.
|
||||
|
|
|
@ -25,6 +25,6 @@ mod os_str;
|
|||
/// Freely convertible to an `&OsStr` slice.
|
||||
#[unstable(feature = "std_misc")]
|
||||
pub trait AsOsStr {
|
||||
/// Convert to an `&OsStr` slice.
|
||||
/// Converts to an `&OsStr` slice.
|
||||
fn as_os_str(&self) -> &OsStr;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ use string::String;
|
|||
use ops;
|
||||
use cmp;
|
||||
use hash::{Hash, Hasher};
|
||||
use old_path::{Path, GenericPath};
|
||||
use vec::Vec;
|
||||
|
||||
use sys::os_str::{Buf, Slice};
|
||||
|
@ -69,7 +68,7 @@ impl OsString {
|
|||
OsString { inner: Buf::from_string(String::new()) }
|
||||
}
|
||||
|
||||
/// Construct an `OsString` from a byte sequence.
|
||||
/// Constructs an `OsString` from a byte sequence.
|
||||
///
|
||||
/// # Platform behavior
|
||||
///
|
||||
|
@ -94,13 +93,13 @@ impl OsString {
|
|||
from_bytes_inner(bytes.into())
|
||||
}
|
||||
|
||||
/// Convert to an `OsStr` slice.
|
||||
/// Converts to an `OsStr` slice.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn as_os_str(&self) -> &OsStr {
|
||||
self
|
||||
}
|
||||
|
||||
/// Convert the `OsString` into a `String` if it contains valid Unicode data.
|
||||
/// Converts the `OsString` into a `String` if it contains valid Unicode data.
|
||||
///
|
||||
/// On failure, ownership of the original `OsString` is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -108,7 +107,7 @@ impl OsString {
|
|||
self.inner.into_string().map_err(|buf| OsString { inner: buf} )
|
||||
}
|
||||
|
||||
/// Extend the string with the given `&OsStr` slice.
|
||||
/// Extends the string with the given `&OsStr` slice.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
|
||||
self.inner.push_slice(&s.as_ref().inner)
|
||||
|
@ -221,13 +220,13 @@ impl Hash for OsString {
|
|||
}
|
||||
|
||||
impl OsStr {
|
||||
/// Coerce into an `OsStr` slice.
|
||||
/// Coerces into an `OsStr` slice.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
|
||||
s.as_ref()
|
||||
}
|
||||
|
||||
/// Coerce directly from a `&str` slice to a `&OsStr` slice.
|
||||
/// Coerces directly from a `&str` slice to a `&OsStr` slice.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `OsStr::new` instead")]
|
||||
|
@ -235,7 +234,7 @@ impl OsStr {
|
|||
unsafe { mem::transmute(Slice::from_str(s)) }
|
||||
}
|
||||
|
||||
/// Yield a `&str` slice if the `OsStr` is valid unicode.
|
||||
/// Yields a `&str` slice if the `OsStr` is valid unicode.
|
||||
///
|
||||
/// This conversion may entail doing a check for UTF-8 validity.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -243,7 +242,7 @@ impl OsStr {
|
|||
self.inner.to_str()
|
||||
}
|
||||
|
||||
/// Convert an `OsStr` to a `Cow<str>`.
|
||||
/// Converts an `OsStr` to a `Cow<str>`.
|
||||
///
|
||||
/// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -251,13 +250,13 @@ impl OsStr {
|
|||
self.inner.to_string_lossy()
|
||||
}
|
||||
|
||||
/// Copy the slice into an owned `OsString`.
|
||||
/// Copies the slice into an owned `OsString`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn to_os_string(&self) -> OsString {
|
||||
OsString { inner: self.inner.to_owned() }
|
||||
}
|
||||
|
||||
/// Yield this `OsStr` as a byte slice.
|
||||
/// Yields this `OsStr` as a byte slice.
|
||||
///
|
||||
/// # Platform behavior
|
||||
///
|
||||
|
@ -275,7 +274,7 @@ impl OsStr {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a `CString` containing this `OsStr` data.
|
||||
/// Creates a `CString` containing this `OsStr` data.
|
||||
///
|
||||
/// Fails if the `OsStr` contains interior nulls.
|
||||
///
|
||||
|
@ -287,7 +286,7 @@ impl OsStr {
|
|||
self.to_bytes().and_then(|b| CString::new(b).ok())
|
||||
}
|
||||
|
||||
/// Get the underlying byte representation.
|
||||
/// Gets the underlying byte representation.
|
||||
///
|
||||
/// Note: it is *crucial* that this API is private, to avoid
|
||||
/// revealing the internal, platform-specific encodings.
|
||||
|
@ -447,21 +446,6 @@ impl AsRef<OsStr> for String {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
|
||||
impl AsOsStr for Path {
|
||||
#[cfg(unix)]
|
||||
fn as_os_str(&self) -> &OsStr {
|
||||
unsafe { mem::transmute(self.as_vec()) }
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn as_os_str(&self) -> &OsStr {
|
||||
// currently .as_str() is actually infallible on windows
|
||||
OsStr::from_str(self.as_str().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<Buf> for OsString {
|
||||
fn from_inner(buf: Buf) -> OsString {
|
||||
OsString { inner: buf }
|
||||
|
|
|
@ -123,7 +123,7 @@ pub struct WalkDir {
|
|||
/// Opening a file for both reading and writing, as well as creating it if it
|
||||
/// doesn't exist:
|
||||
///
|
||||
/// ```
|
||||
/// ```no_run
|
||||
/// use std::fs::OpenOptions;
|
||||
///
|
||||
/// let file = OpenOptions::new()
|
||||
|
@ -171,7 +171,7 @@ impl File {
|
|||
OpenOptions::new().read(true).open(path)
|
||||
}
|
||||
|
||||
/// Open a file in write-only mode.
|
||||
/// Opens a file in write-only mode.
|
||||
///
|
||||
/// This function will create a file if it does not exist,
|
||||
/// and will truncate it if it does.
|
||||
|
@ -201,7 +201,7 @@ impl File {
|
|||
self.path.as_ref().map(|p| &**p)
|
||||
}
|
||||
|
||||
/// Attempt to sync all OS-internal metadata to disk.
|
||||
/// Attempts to sync all OS-internal metadata to disk.
|
||||
///
|
||||
/// This function will attempt to ensure that all in-core data reaches the
|
||||
/// filesystem before returning.
|
||||
|
@ -362,7 +362,7 @@ impl OpenOptions {
|
|||
OpenOptions(fs_imp::OpenOptions::new())
|
||||
}
|
||||
|
||||
/// Set the option for read access.
|
||||
/// Sets the option for read access.
|
||||
///
|
||||
/// This option, when true, will indicate that the file should be
|
||||
/// `read`-able if opened.
|
||||
|
@ -379,7 +379,7 @@ impl OpenOptions {
|
|||
self.0.read(read); self
|
||||
}
|
||||
|
||||
/// Set the option for write access.
|
||||
/// Sets the option for write access.
|
||||
///
|
||||
/// This option, when true, will indicate that the file should be
|
||||
/// `write`-able if opened.
|
||||
|
@ -396,7 +396,7 @@ impl OpenOptions {
|
|||
self.0.write(write); self
|
||||
}
|
||||
|
||||
/// Set the option for the append mode.
|
||||
/// Sets the option for the append mode.
|
||||
///
|
||||
/// This option, when true, means that writes will append to a file instead
|
||||
/// of overwriting previous contents.
|
||||
|
@ -413,7 +413,7 @@ impl OpenOptions {
|
|||
self.0.append(append); self
|
||||
}
|
||||
|
||||
/// Set the option for truncating a previous file.
|
||||
/// Sets the option for truncating a previous file.
|
||||
///
|
||||
/// If a file is successfully opened with this option set it will truncate
|
||||
/// the file to 0 length if it already exists.
|
||||
|
@ -430,7 +430,7 @@ impl OpenOptions {
|
|||
self.0.truncate(truncate); self
|
||||
}
|
||||
|
||||
/// Set the option for creating a new file.
|
||||
/// Sets the option for creating a new file.
|
||||
///
|
||||
/// This option indicates whether a new file will be created if the file
|
||||
/// does not yet already exist.
|
||||
|
@ -447,7 +447,7 @@ impl OpenOptions {
|
|||
self.0.create(create); self
|
||||
}
|
||||
|
||||
/// Open a file at `path` with the options specified by `self`.
|
||||
/// Opens a file at `path` with the options specified by `self`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
@ -587,7 +587,7 @@ impl Permissions {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn readonly(&self) -> bool { self.0.readonly() }
|
||||
|
||||
/// Modify the readonly flag for this set of permissions.
|
||||
/// Modifies the readonly flag for this set of permissions.
|
||||
///
|
||||
/// This operation does **not** modify the filesystem. To modify the
|
||||
/// filesystem use the `fs::set_permissions` function.
|
||||
|
@ -670,7 +670,7 @@ impl DirEntry {
|
|||
pub fn path(&self) -> PathBuf { self.0.path() }
|
||||
}
|
||||
|
||||
/// Remove a file from the underlying filesystem.
|
||||
/// Removes a file from the underlying filesystem.
|
||||
///
|
||||
/// Note that, just because an unlink call was successful, it is not
|
||||
/// guaranteed that a file is immediately deleted (e.g. depending on
|
||||
|
@ -856,7 +856,7 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
|
|||
fs_imp::readlink(path.as_ref())
|
||||
}
|
||||
|
||||
/// Create a new, empty directory at the provided path
|
||||
/// Creates a new, empty directory at the provided path
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
@ -906,7 +906,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
|||
create_dir(path)
|
||||
}
|
||||
|
||||
/// Remove an existing, empty directory
|
||||
/// Removes an existing, empty directory.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
@ -1058,7 +1058,7 @@ impl Iterator for WalkDir {
|
|||
reason = "the precise set of methods exposed on this trait may \
|
||||
change and some methods may be removed")]
|
||||
pub trait PathExt {
|
||||
/// Get information on the file, directory, etc at this path.
|
||||
/// Gets information on the file, directory, etc at this path.
|
||||
///
|
||||
/// Consult the `fs::stat` documentation for more info.
|
||||
///
|
||||
|
@ -1195,7 +1195,8 @@ mod tests {
|
|||
|
||||
pub fn tmpdir() -> TempDir {
|
||||
let p = env::temp_dir();
|
||||
let ret = p.join(&format!("rust-{}", rand::random::<u32>()));
|
||||
let mut r = rand::thread_rng();
|
||||
let ret = p.join(&format!("rust-{}", r.next_u32()));
|
||||
check!(fs::create_dir(&ret));
|
||||
TempDir(ret)
|
||||
}
|
||||
|
|
|
@ -34,21 +34,21 @@ pub struct Cursor<T> {
|
|||
}
|
||||
|
||||
impl<T> Cursor<T> {
|
||||
/// Create a new cursor wrapping the provided underlying I/O object.
|
||||
/// Creates a new cursor wrapping the provided underlying I/O object.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(inner: T) -> Cursor<T> {
|
||||
Cursor { pos: 0, inner: inner }
|
||||
}
|
||||
|
||||
/// Consume this cursor, returning the underlying value.
|
||||
/// Consumes this cursor, returning the underlying value.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn into_inner(self) -> T { self.inner }
|
||||
|
||||
/// Get a reference to the underlying value in this cursor.
|
||||
/// Gets a reference to the underlying value in this cursor.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn get_ref(&self) -> &T { &self.inner }
|
||||
|
||||
/// Get a mutable reference to the underlying value in this cursor.
|
||||
/// Gets a mutable reference to the underlying value in this cursor.
|
||||
///
|
||||
/// Care should be taken to avoid modifying the internal I/O state of the
|
||||
/// underlying value as it may corrupt this cursor's position.
|
||||
|
|
|
@ -191,7 +191,7 @@ impl Error {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the corresponding `ErrorKind` for this error.
|
||||
/// Returns the corresponding `ErrorKind` for this error.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn kind(&self) -> ErrorKind {
|
||||
match self.repr {
|
||||
|
|
|
@ -172,14 +172,11 @@ pub trait Read {
|
|||
/// Read all bytes until EOF in this source, placing them into `buf`.
|
||||
///
|
||||
/// All bytes read from this source will be appended to the specified buffer
|
||||
/// `buf`. This function will return a call to `read` either:
|
||||
/// `buf`. This function will continuously call `read` to append more data to
|
||||
/// `buf` until `read` returns either `Ok(0)` or an error of
|
||||
/// non-`ErrorKind::Interrupted` kind.
|
||||
///
|
||||
/// 1. Returns `Ok(0)`.
|
||||
/// 2. Returns an error which is not of the kind `ErrorKind::Interrupted`.
|
||||
///
|
||||
/// Until one of these conditions is met the function will continuously
|
||||
/// invoke `read` to append more data to `buf`. If successful, this function
|
||||
/// will return the total number of bytes read.
|
||||
/// If successful, this function will return the total number of bytes read.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
|
@ -220,14 +217,14 @@ pub trait Read {
|
|||
append_to_string(buf, |b| read_to_end(self, b))
|
||||
}
|
||||
|
||||
/// Create a "by reference" adaptor for this instance of `Read`.
|
||||
/// Creates a "by reference" adaptor for this instance of `Read`.
|
||||
///
|
||||
/// The returned adaptor also implements `Read` and will simply borrow this
|
||||
/// current reader.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
|
||||
|
||||
/// Transform this `Read` instance to an `Iterator` over its bytes.
|
||||
/// Transforms this `Read` instance to an `Iterator` over its bytes.
|
||||
///
|
||||
/// The returned type implements `Iterator` where the `Item` is `Result<u8,
|
||||
/// R::Err>`. The yielded item is `Ok` if a byte was successfully read and
|
||||
|
@ -238,7 +235,7 @@ pub trait Read {
|
|||
Bytes { inner: self }
|
||||
}
|
||||
|
||||
/// Transform this `Read` instance to an `Iterator` over `char`s.
|
||||
/// Transforms this `Read` instance to an `Iterator` over `char`s.
|
||||
///
|
||||
/// This adaptor will attempt to interpret this reader as an UTF-8 encoded
|
||||
/// sequence of characters. The returned iterator will return `None` once
|
||||
|
@ -255,7 +252,7 @@ pub trait Read {
|
|||
Chars { inner: self }
|
||||
}
|
||||
|
||||
/// Create an adaptor which will chain this stream with another.
|
||||
/// Creates an adaptor which will chain this stream with another.
|
||||
///
|
||||
/// The returned `Read` instance will first read all bytes from this object
|
||||
/// until EOF is encountered. Afterwards the output is equivalent to the
|
||||
|
@ -265,7 +262,7 @@ pub trait Read {
|
|||
Chain { first: self, second: next, done_first: false }
|
||||
}
|
||||
|
||||
/// Create an adaptor which will read at most `limit` bytes from it.
|
||||
/// Creates an adaptor which will read at most `limit` bytes from it.
|
||||
///
|
||||
/// This function returns a new instance of `Read` which will read at most
|
||||
/// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any
|
||||
|
@ -406,7 +403,7 @@ pub trait Write {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a "by reference" adaptor for this instance of `Write`.
|
||||
/// Creates a "by reference" adaptor for this instance of `Write`.
|
||||
///
|
||||
/// The returned adaptor also implements `Write` and will simply borrow this
|
||||
/// current writer.
|
||||
|
|
|
@ -45,7 +45,7 @@ struct StdoutRaw(stdio::Stdout);
|
|||
/// the `std::io::stdio::stderr_raw` function.
|
||||
struct StderrRaw(stdio::Stderr);
|
||||
|
||||
/// Construct a new raw handle to the standard input of this process.
|
||||
/// Constructs a new raw handle to the standard input of this process.
|
||||
///
|
||||
/// The returned handle does not interact with any other handles created nor
|
||||
/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
|
||||
|
@ -54,7 +54,7 @@ struct StderrRaw(stdio::Stderr);
|
|||
/// The returned handle has no external synchronization or buffering.
|
||||
fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
|
||||
|
||||
/// Construct a new raw handle to the standard input stream of this process.
|
||||
/// Constructs a new raw handle to the standard input stream of this process.
|
||||
///
|
||||
/// The returned handle does not interact with any other handles created nor
|
||||
/// handles returned by `std::io::stdout`. Note that data is buffered by the
|
||||
|
@ -65,7 +65,7 @@ fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
|
|||
/// top.
|
||||
fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
|
||||
|
||||
/// Construct a new raw handle to the standard input stream of this process.
|
||||
/// Constructs a new raw handle to the standard input stream of this process.
|
||||
///
|
||||
/// The returned handle does not interact with any other handles created nor
|
||||
/// handles returned by `std::io::stdout`.
|
||||
|
@ -109,7 +109,7 @@ pub struct StdinLock<'a> {
|
|||
inner: MutexGuard<'a, BufReader<StdinRaw>>,
|
||||
}
|
||||
|
||||
/// Create a new handle to the global standard input stream of this process.
|
||||
/// Creates a new handle to the global standard input stream of this process.
|
||||
///
|
||||
/// The handle returned refers to a globally shared buffer between all threads.
|
||||
/// Access is synchronized and can be explicitly controlled with the `lock()`
|
||||
|
@ -139,7 +139,7 @@ pub fn stdin() -> Stdin {
|
|||
}
|
||||
|
||||
impl Stdin {
|
||||
/// Lock this handle to the standard input stream, returning a readable
|
||||
/// Locks this handle to the standard input stream, returning a readable
|
||||
/// guard.
|
||||
///
|
||||
/// The lock is released when the returned lock goes out of scope. The
|
||||
|
@ -243,7 +243,7 @@ pub fn stdout() -> Stdout {
|
|||
}
|
||||
|
||||
impl Stdout {
|
||||
/// Lock this handle to the standard output stream, returning a writable
|
||||
/// Locks this handle to the standard output stream, returning a writable
|
||||
/// guard.
|
||||
///
|
||||
/// The lock is released when the returned lock goes out of scope. The
|
||||
|
@ -315,7 +315,7 @@ pub fn stderr() -> Stderr {
|
|||
}
|
||||
|
||||
impl Stderr {
|
||||
/// Lock this handle to the standard error stream, returning a writable
|
||||
/// Locks this handle to the standard error stream, returning a writable
|
||||
/// guard.
|
||||
///
|
||||
/// The lock is released when the returned lock goes out of scope. The
|
||||
|
|
|
@ -262,12 +262,9 @@ pub mod ffi;
|
|||
pub mod fs;
|
||||
pub mod io;
|
||||
pub mod net;
|
||||
pub mod old_io;
|
||||
pub mod old_path;
|
||||
pub mod os;
|
||||
pub mod path;
|
||||
pub mod process;
|
||||
pub mod rand;
|
||||
pub mod sync;
|
||||
pub mod time;
|
||||
|
||||
|
@ -281,6 +278,18 @@ pub mod time;
|
|||
|
||||
pub mod rt;
|
||||
mod panicking;
|
||||
mod rand;
|
||||
|
||||
// Some external utilities of the standard library rely on randomness (aka
|
||||
// rustc_back::TempDir and tests) and need a way to get at the OS rng we've got
|
||||
// here. This module is not at all intended for stabilization as-is, however,
|
||||
// but it may be stabilized long-term. As a result we're exposing a hidden,
|
||||
// unstable module so we can get our build working.
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "rand")]
|
||||
pub mod __rand {
|
||||
pub use rand::{thread_rng, ThreadRng, Rng};
|
||||
}
|
||||
|
||||
// Modules that exist purely to document + host impl docs for primitive types
|
||||
|
||||
|
@ -297,8 +306,6 @@ mod std {
|
|||
pub use sync; // used for select!()
|
||||
pub use error; // used for try!()
|
||||
pub use fmt; // used for any formatting strings
|
||||
#[allow(deprecated)]
|
||||
pub use old_io; // used for println!()
|
||||
pub use option; // used for bitflags!{}
|
||||
pub use rt; // used for panic!()
|
||||
pub use vec; // used for vec![]
|
||||
|
|
|
@ -615,7 +615,7 @@ mod tests {
|
|||
fn ipv4_properties() {
|
||||
fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
|
||||
private: bool, link_local: bool, global: bool,
|
||||
multicast: bool) {
|
||||
multicast: bool, broadcast: bool, documentation: bool) {
|
||||
let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]);
|
||||
assert_eq!(octets, &ip.octets());
|
||||
|
||||
|
@ -625,20 +625,23 @@ mod tests {
|
|||
assert_eq!(ip.is_link_local(), link_local);
|
||||
assert_eq!(ip.is_global(), global);
|
||||
assert_eq!(ip.is_multicast(), multicast);
|
||||
assert_eq!(ip.is_broadcast(), broadcast);
|
||||
assert_eq!(ip.is_documentation(), documentation);
|
||||
}
|
||||
|
||||
// address unspec loopbk privt linloc global multicast
|
||||
check(&[0, 0, 0, 0], true, false, false, false, true, false);
|
||||
check(&[0, 0, 0, 1], false, false, false, false, true, false);
|
||||
check(&[1, 0, 0, 0], false, false, false, false, true, false);
|
||||
check(&[10, 9, 8, 7], false, false, true, false, false, false);
|
||||
check(&[127, 1, 2, 3], false, true, false, false, false, false);
|
||||
check(&[172, 31, 254, 253], false, false, true, false, false, false);
|
||||
check(&[169, 254, 253, 242], false, false, false, true, false, false);
|
||||
check(&[192, 168, 254, 253], false, false, true, false, false, false);
|
||||
check(&[224, 0, 0, 0], false, false, false, false, true, true);
|
||||
check(&[239, 255, 255, 255], false, false, false, false, true, true);
|
||||
check(&[255, 255, 255, 255], false, false, false, false, true, false);
|
||||
// address unspec loopbk privt linloc global multicast brdcast doc
|
||||
check(&[0, 0, 0, 0], true, false, false, false, true, false, false, false);
|
||||
check(&[0, 0, 0, 1], false, false, false, false, true, false, false, false);
|
||||
check(&[1, 0, 0, 0], false, false, false, false, true, false, false, false);
|
||||
check(&[10, 9, 8, 7], false, false, true, false, false, false, false, false);
|
||||
check(&[127, 1, 2, 3], false, true, false, false, false, false, false, false);
|
||||
check(&[172, 31, 254, 253], false, false, true, false, false, false, false, false);
|
||||
check(&[169, 254, 253, 242], false, false, false, true, false, false, false, false);
|
||||
check(&[192, 168, 254, 253], false, false, true, false, false, false, false, false);
|
||||
check(&[224, 0, 0, 0], false, false, false, false, true, true, false, false);
|
||||
check(&[239, 255, 255, 255], false, false, false, false, true, true, false, false);
|
||||
check(&[255, 255, 255, 255], false, false, false, false, false, false, true, false);
|
||||
check(&[198, 51, 100, 0], false, false, false, false, false, false, false, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -58,7 +58,7 @@ pub enum Ipv6MulticastScope {
|
|||
}
|
||||
|
||||
impl Ipv4Addr {
|
||||
/// Create a new IPv4 address from four eight-bit octets.
|
||||
/// Creates a new IPv4 address from four eight-bit octets.
|
||||
///
|
||||
/// The result will represent the IP address a.b.c.d
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -115,9 +115,11 @@ impl Ipv4Addr {
|
|||
///
|
||||
/// Non-globally-routable networks include the private networks (10.0.0.0/8,
|
||||
/// 172.16.0.0/12 and 192.168.0.0/16), the loopback network (127.0.0.0/8),
|
||||
/// and the link-local network (169.254.0.0/16).
|
||||
/// the link-local network (169.254.0.0/16), the broadcast address (255.255.255.255/32) and
|
||||
/// the test networks used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24)
|
||||
pub fn is_global(&self) -> bool {
|
||||
!self.is_private() && !self.is_loopback() && !self.is_link_local()
|
||||
!self.is_private() && !self.is_loopback() && !self.is_link_local() &&
|
||||
!self.is_broadcast() && !self.is_documentation()
|
||||
}
|
||||
|
||||
/// Returns true if this is a multicast address.
|
||||
|
@ -127,7 +129,30 @@ impl Ipv4Addr {
|
|||
self.octets()[0] >= 224 && self.octets()[0] <= 239
|
||||
}
|
||||
|
||||
/// Convert this address to an IPv4-compatible IPv6 address
|
||||
/// Returns true if this is a broadcast address.
|
||||
///
|
||||
/// A broadcast address has all octets set to 255 as defined in RFC 919
|
||||
pub fn is_broadcast(&self) -> bool {
|
||||
self.octets()[0] == 255 && self.octets()[1] == 255 &&
|
||||
self.octets()[2] == 255 && self.octets()[3] == 255
|
||||
}
|
||||
|
||||
/// Returns true if this address is in a range designated for documentation
|
||||
///
|
||||
/// This is defined in RFC 5737
|
||||
/// - 192.0.2.0/24 (TEST-NET-1)
|
||||
/// - 198.51.100.0/24 (TEST-NET-2)
|
||||
/// - 203.0.113.0/24 (TEST-NET-3)
|
||||
pub fn is_documentation(&self) -> bool {
|
||||
match(self.octets()[0], self.octets()[1], self.octets()[2], self.octets()[3]) {
|
||||
(192, _, 2, _) => true,
|
||||
(198, 51, 100, _) => true,
|
||||
(203, _, 113, _) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this address to an IPv4-compatible IPv6 address
|
||||
///
|
||||
/// a.b.c.d becomes ::a.b.c.d
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -137,7 +162,7 @@ impl Ipv4Addr {
|
|||
((self.octets()[2] as u16) << 8) | self.octets()[3] as u16)
|
||||
}
|
||||
|
||||
/// Convert this address to an IPv4-mapped IPv6 address
|
||||
/// Converts this address to an IPv4-mapped IPv6 address
|
||||
///
|
||||
/// a.b.c.d becomes ::ffff:a.b.c.d
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -220,7 +245,7 @@ impl FromInner<libc::in_addr> for Ipv4Addr {
|
|||
}
|
||||
|
||||
impl Ipv6Addr {
|
||||
/// Create a new IPv6 address from eight 16-bit segments.
|
||||
/// Creates a new IPv6 address from eight 16-bit segments.
|
||||
///
|
||||
/// The result will represent the IP address a:b:c:d:e:f:g:h
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -234,7 +259,7 @@ impl Ipv6Addr {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the eight 16-bit segments that make up this address
|
||||
/// Returns the eight 16-bit segments that make up this address
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn segments(&self) -> [u16; 8] {
|
||||
[ntoh(self.inner.s6_addr[0]),
|
||||
|
@ -324,7 +349,7 @@ impl Ipv6Addr {
|
|||
(self.segments()[0] & 0xff00) == 0xff00
|
||||
}
|
||||
|
||||
/// Convert this address to an IPv4 address. Returns None if this address is
|
||||
/// Converts this address to an IPv4 address. Returns None if this address is
|
||||
/// neither IPv4-compatible or IPv4-mapped.
|
||||
///
|
||||
/// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
|
||||
|
|
|
@ -82,7 +82,7 @@ pub struct TcpListener(net_imp::TcpListener);
|
|||
pub struct Incoming<'a> { listener: &'a TcpListener }
|
||||
|
||||
impl TcpStream {
|
||||
/// Open a TCP connection to a remote host.
|
||||
/// Opens a TCP connection to a remote host.
|
||||
///
|
||||
/// `addr` is an address of the remote host. Anything which implements
|
||||
/// `ToSocketAddrs` trait can be supplied for the address; see this trait
|
||||
|
@ -104,7 +104,7 @@ impl TcpStream {
|
|||
self.0.socket_addr()
|
||||
}
|
||||
|
||||
/// Shut down the read, write, or both halves of this connection.
|
||||
/// Shuts down the read, write, or both halves of this connection.
|
||||
///
|
||||
/// This function will cause all pending and future I/O on the specified
|
||||
/// portions to return immediately with an appropriate value (see the
|
||||
|
@ -114,7 +114,7 @@ impl TcpStream {
|
|||
self.0.shutdown(how)
|
||||
}
|
||||
|
||||
/// Create a new independently owned handle to the underlying socket.
|
||||
/// Creates a new independently owned handle to the underlying socket.
|
||||
///
|
||||
/// The returned `TcpStream` is a reference to the same stream that this
|
||||
/// object references. Both handles will read and write the same stream of
|
||||
|
@ -190,7 +190,7 @@ impl TcpListener {
|
|||
self.0.socket_addr()
|
||||
}
|
||||
|
||||
/// Create a new independently owned handle to the underlying socket.
|
||||
/// Creates a new independently owned handle to the underlying socket.
|
||||
///
|
||||
/// The returned `TcpListener` is a reference to the same socket that this
|
||||
/// object references. Both handles can be used to accept incoming
|
||||
|
|
|
@ -85,7 +85,7 @@ impl UdpSocket {
|
|||
self.0.socket_addr()
|
||||
}
|
||||
|
||||
/// Create a new independently owned handle to the underlying socket.
|
||||
/// Creates a new independently owned handle to the underlying socket.
|
||||
///
|
||||
/// The returned `UdpSocket` is a reference to the same socket that this
|
||||
/// object references. Both handles will read and write the same port, and
|
||||
|
@ -100,7 +100,7 @@ impl UdpSocket {
|
|||
self.0.set_broadcast(on)
|
||||
}
|
||||
|
||||
/// Set the multicast loop flag to the specified value
|
||||
/// Sets the multicast loop flag to the specified value
|
||||
///
|
||||
/// This lets multicast packets loop back to local sockets (if enabled)
|
||||
pub fn set_multicast_loop(&self, on: bool) -> io::Result<()> {
|
||||
|
|
|
@ -527,7 +527,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn round(self) -> f32 { num::Float::round(self) }
|
||||
|
||||
/// Return the integer part of a number.
|
||||
/// Returns the integer part of a number.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.3_f32;
|
||||
|
@ -666,7 +666,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) }
|
||||
|
||||
/// Take the reciprocal (inverse) of a number, `1/x`.
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
|
@ -680,7 +680,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn recip(self) -> f32 { num::Float::recip(self) }
|
||||
|
||||
/// Raise a number to an integer power.
|
||||
/// Raises a number to an integer power.
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
///
|
||||
|
@ -696,7 +696,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
|
||||
|
||||
/// Raise a number to a floating point power.
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
|
@ -710,7 +710,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
|
||||
|
||||
/// Take the square root of a number.
|
||||
/// Takes the square root of a number.
|
||||
///
|
||||
/// Returns NaN if `self` is a negative number.
|
||||
///
|
||||
|
@ -729,7 +729,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn sqrt(self) -> f32 { num::Float::sqrt(self) }
|
||||
|
||||
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
/// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -852,7 +852,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn log10(self) -> f32 { num::Float::log10(self) }
|
||||
|
||||
/// Convert radians to degrees.
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -868,7 +868,7 @@ impl f32 {
|
|||
#[inline]
|
||||
pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
|
||||
|
||||
/// Convert degrees to radians.
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -1003,7 +1003,7 @@ impl f32 {
|
|||
unsafe { cmath::fdimf(self, other) }
|
||||
}
|
||||
|
||||
/// Take the cubic root of a number.
|
||||
/// Takes the cubic root of a number.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
|
@ -1021,7 +1021,7 @@ impl f32 {
|
|||
unsafe { cmath::cbrtf(self) }
|
||||
}
|
||||
|
||||
/// Calculate the length of the hypotenuse of a right-angle triangle given
|
||||
/// Calculates the length of the hypotenuse of a right-angle triangle given
|
||||
/// legs of length `x` and `y`.
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -534,7 +534,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn round(self) -> f64 { num::Float::round(self) }
|
||||
|
||||
/// Return the integer part of a number.
|
||||
/// Returns the integer part of a number.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 3.3_f64;
|
||||
|
@ -671,7 +671,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) }
|
||||
|
||||
/// Take the reciprocal (inverse) of a number, `1/x`.
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
|
@ -683,7 +683,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn recip(self) -> f64 { num::Float::recip(self) }
|
||||
|
||||
/// Raise a number to an integer power.
|
||||
/// Raises a number to an integer power.
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
///
|
||||
|
@ -697,7 +697,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
|
||||
|
||||
/// Raise a number to a floating point power.
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
|
@ -709,7 +709,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
|
||||
|
||||
/// Take the square root of a number.
|
||||
/// Takes the square root of a number.
|
||||
///
|
||||
/// Returns NaN if `self` is a negative number.
|
||||
///
|
||||
|
@ -726,7 +726,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn sqrt(self) -> f64 { num::Float::sqrt(self) }
|
||||
|
||||
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
/// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -835,7 +835,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn log10(self) -> f64 { num::Float::log10(self) }
|
||||
|
||||
/// Convert radians to degrees.
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64::consts;
|
||||
|
@ -850,7 +850,7 @@ impl f64 {
|
|||
#[inline]
|
||||
pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
|
||||
|
||||
/// Convert degrees to radians.
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64::consts;
|
||||
|
@ -978,7 +978,7 @@ impl f64 {
|
|||
unsafe { cmath::fdim(self, other) }
|
||||
}
|
||||
|
||||
/// Take the cubic root of a number.
|
||||
/// Takes the cubic root of a number.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 8.0_f64;
|
||||
|
@ -994,7 +994,7 @@ impl f64 {
|
|||
unsafe { cmath::cbrt(self) }
|
||||
}
|
||||
|
||||
/// Calculate the length of the hypotenuse of a right-angle triangle given
|
||||
/// Calculates the length of the hypotenuse of a right-angle triangle given
|
||||
/// legs of length `x` and `y`.
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -383,7 +383,7 @@ pub trait Float
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn round(self) -> Self;
|
||||
/// Return the integer part of a number.
|
||||
/// Returns the integer part of a number.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::Float;
|
||||
|
@ -509,7 +509,7 @@ pub trait Float
|
|||
#[unstable(feature = "std_misc",
|
||||
reason = "unsure about its place in the world")]
|
||||
fn mul_add(self, a: Self, b: Self) -> Self;
|
||||
/// Take the reciprocal (inverse) of a number, `1/x`.
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -524,7 +524,7 @@ pub trait Float
|
|||
reason = "unsure about its place in the world")]
|
||||
fn recip(self) -> Self;
|
||||
|
||||
/// Raise a number to an integer power.
|
||||
/// Raises a number to an integer power.
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
///
|
||||
|
@ -538,7 +538,7 @@ pub trait Float
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn powi(self, n: i32) -> Self;
|
||||
/// Raise a number to a floating point power.
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::Float;
|
||||
|
@ -550,7 +550,7 @@ pub trait Float
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn powf(self, n: Self) -> Self;
|
||||
/// Take the square root of a number.
|
||||
/// Takes the square root of a number.
|
||||
///
|
||||
/// Returns NaN if `self` is a negative number.
|
||||
///
|
||||
|
@ -569,7 +569,7 @@ pub trait Float
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn sqrt(self) -> Self;
|
||||
|
||||
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
/// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -679,7 +679,7 @@ pub trait Float
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn log10(self) -> Self;
|
||||
|
||||
/// Convert radians to degrees.
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::Float;
|
||||
|
@ -693,7 +693,7 @@ pub trait Float
|
|||
/// ```
|
||||
#[unstable(feature = "std_misc", reason = "desirability is unclear")]
|
||||
fn to_degrees(self) -> Self;
|
||||
/// Convert degrees to radians.
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -807,7 +807,7 @@ pub trait Float
|
|||
/// ```
|
||||
#[unstable(feature = "std_misc", reason = "may be renamed")]
|
||||
fn abs_sub(self, other: Self) -> Self;
|
||||
/// Take the cubic root of a number.
|
||||
/// Takes the cubic root of a number.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(std_misc)]
|
||||
|
@ -822,7 +822,7 @@ pub trait Float
|
|||
/// ```
|
||||
#[unstable(feature = "std_misc", reason = "may be renamed")]
|
||||
fn cbrt(self) -> Self;
|
||||
/// Calculate the length of the hypotenuse of a right-angle triangle given
|
||||
/// Calculates the length of the hypotenuse of a right-angle triangle given
|
||||
/// legs of length `x` and `y`.
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -464,7 +464,7 @@ mod bench {
|
|||
|
||||
mod usize {
|
||||
use super::test::Bencher;
|
||||
use rand::{weak_rng, Rng};
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::fmt;
|
||||
|
||||
#[inline]
|
||||
|
@ -474,38 +474,38 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn to_str_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<usize>(), 2); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<usize>(), 8); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<usize>(), 10); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<usize>(), 16); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<usize>(), 36); })
|
||||
}
|
||||
}
|
||||
|
||||
mod isize {
|
||||
use super::test::Bencher;
|
||||
use rand::{weak_rng, Rng};
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::fmt;
|
||||
|
||||
#[inline]
|
||||
|
@ -515,43 +515,43 @@ mod bench {
|
|||
|
||||
#[bench]
|
||||
fn to_str_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<isize>(), 2); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<isize>(), 8); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<isize>(), 10); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<isize>(), 16); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn to_str_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { to_string(rng.gen::<isize>(), 36); })
|
||||
}
|
||||
}
|
||||
|
||||
mod f64 {
|
||||
use super::test::Bencher;
|
||||
use rand::{weak_rng, Rng};
|
||||
use rand::{thread_rng, Rng};
|
||||
use f64;
|
||||
|
||||
#[bench]
|
||||
fn float_to_string(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
let mut rng = thread_rng();
|
||||
b.iter(|| { f64::to_string(rng.gen()); })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,702 +0,0 @@
|
|||
// Copyright 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.
|
||||
//
|
||||
// ignore-lexer-test FIXME #15883
|
||||
|
||||
//! Buffering wrappers for I/O traits
|
||||
|
||||
use cmp;
|
||||
use fmt;
|
||||
use old_io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
|
||||
use iter::{Iterator, ExactSizeIterator, repeat};
|
||||
use ops::Drop;
|
||||
use option::Option;
|
||||
use option::Option::{Some, None};
|
||||
use result::Result::Ok;
|
||||
use slice;
|
||||
use vec::Vec;
|
||||
|
||||
/// Wraps a Reader and buffers input from it
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with a `Reader`. For
|
||||
/// example, every call to `read` on `TcpStream` results in a system call. A
|
||||
/// `BufferedReader` performs large, infrequent reads on the underlying
|
||||
/// `Reader` and maintains an in-memory buffer of the results.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(old_io, old_path)]
|
||||
/// use std::old_io::*;
|
||||
/// use std::old_path::Path;
|
||||
///
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut reader = BufferedReader::new(file);
|
||||
///
|
||||
/// let mut buf = [0; 100];
|
||||
/// match reader.read(&mut buf) {
|
||||
/// Ok(nread) => println!("Read {} bytes", nread),
|
||||
/// Err(e) => println!("error reading: {}", e)
|
||||
/// }
|
||||
/// ```
|
||||
pub struct BufferedReader<R> {
|
||||
inner: R,
|
||||
buf: Vec<u8>,
|
||||
pos: usize,
|
||||
cap: usize,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<R> fmt::Debug for BufferedReader<R> where R: fmt::Debug {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "BufferedReader {{ reader: {:?}, buffer: {}/{} }}",
|
||||
self.inner, self.cap - self.pos, self.buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> BufferedReader<R> {
|
||||
/// Creates a new `BufferedReader` with the specified buffer capacity
|
||||
pub fn with_capacity(cap: usize, inner: R) -> BufferedReader<R> {
|
||||
BufferedReader {
|
||||
inner: inner,
|
||||
// We can't use the same trick here as we do for BufferedWriter,
|
||||
// since this memory is visible to the inner Reader.
|
||||
buf: repeat(0).take(cap).collect(),
|
||||
pos: 0,
|
||||
cap: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `BufferedReader` with a default buffer capacity
|
||||
pub fn new(inner: R) -> BufferedReader<R> {
|
||||
BufferedReader::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying reader.
|
||||
pub fn get_ref<'a>(&self) -> &R { &self.inner }
|
||||
|
||||
/// Gets a mutable reference to the underlying reader.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying reader.
|
||||
pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
|
||||
|
||||
/// Unwraps this `BufferedReader`, returning the underlying reader.
|
||||
///
|
||||
/// Note that any leftover data in the internal buffer is lost.
|
||||
pub fn into_inner(self) -> R { self.inner }
|
||||
}
|
||||
|
||||
impl<R: Reader> Buffer for BufferedReader<R> {
|
||||
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||
if self.pos == self.cap {
|
||||
self.cap = try!(self.inner.read(&mut self.buf));
|
||||
self.pos = 0;
|
||||
}
|
||||
Ok(&self.buf[self.pos..self.cap])
|
||||
}
|
||||
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.pos += amt;
|
||||
assert!(self.pos <= self.cap);
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> Reader for BufferedReader<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
if self.pos == self.cap && buf.len() >= self.buf.len() {
|
||||
return self.inner.read(buf);
|
||||
}
|
||||
let nread = {
|
||||
let available = try!(self.fill_buf());
|
||||
let nread = cmp::min(available.len(), buf.len());
|
||||
slice::bytes::copy_memory(&available[..nread], buf);
|
||||
nread
|
||||
};
|
||||
self.pos += nread;
|
||||
Ok(nread)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a Writer and buffers output to it
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with a `Writer`. For
|
||||
/// example, every call to `write` on `TcpStream` results in a system call. A
|
||||
/// `BufferedWriter` keeps an in memory buffer of data and writes it to the
|
||||
/// underlying `Writer` in large, infrequent batches.
|
||||
///
|
||||
/// This writer will be flushed when it is dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(old_io, old_path)]
|
||||
/// use std::old_io::*;
|
||||
/// use std::old_path::Path;
|
||||
///
|
||||
/// let file = File::create(&Path::new("message.txt")).unwrap();
|
||||
/// let mut writer = BufferedWriter::new(file);
|
||||
///
|
||||
/// writer.write_str("hello, world").unwrap();
|
||||
/// writer.flush().unwrap();
|
||||
/// ```
|
||||
pub struct BufferedWriter<W: Writer> {
|
||||
inner: Option<W>,
|
||||
buf: Vec<u8>,
|
||||
pos: usize
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<W: Writer> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
|
||||
self.inner.as_ref().unwrap(), self.pos, self.buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Writer> BufferedWriter<W> {
|
||||
/// Creates a new `BufferedWriter` with the specified buffer capacity
|
||||
pub fn with_capacity(cap: usize, inner: W) -> BufferedWriter<W> {
|
||||
// It's *much* faster to create an uninitialized buffer than it is to
|
||||
// fill everything in with 0. This buffer is entirely an implementation
|
||||
// detail and is never exposed, so we're safe to not initialize
|
||||
// everything up-front. This allows creation of BufferedWriter instances
|
||||
// to be very cheap (large mallocs are not nearly as expensive as large
|
||||
// callocs).
|
||||
let mut buf = Vec::with_capacity(cap);
|
||||
unsafe { buf.set_len(cap); }
|
||||
BufferedWriter {
|
||||
inner: Some(inner),
|
||||
buf: buf,
|
||||
pos: 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `BufferedWriter` with a default buffer capacity
|
||||
pub fn new(inner: W) -> BufferedWriter<W> {
|
||||
BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||
}
|
||||
|
||||
fn flush_buf(&mut self) -> IoResult<()> {
|
||||
if self.pos != 0 {
|
||||
let ret = self.inner.as_mut().unwrap().write_all(&self.buf[..self.pos]);
|
||||
self.pos = 0;
|
||||
ret
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying writer.
|
||||
pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
|
||||
|
||||
/// Gets a mutable reference to the underlying write.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying writer.
|
||||
pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
|
||||
|
||||
/// Unwraps this `BufferedWriter`, returning the underlying writer.
|
||||
///
|
||||
/// The buffer is flushed before returning the writer.
|
||||
pub fn into_inner(mut self) -> W {
|
||||
// FIXME(#12628): is panicking the right thing to do if flushing panicks?
|
||||
self.flush_buf().unwrap();
|
||||
self.inner.take().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Writer> Writer for BufferedWriter<W> {
|
||||
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
if self.pos + buf.len() > self.buf.len() {
|
||||
try!(self.flush_buf());
|
||||
}
|
||||
|
||||
if buf.len() > self.buf.len() {
|
||||
self.inner.as_mut().unwrap().write_all(buf)
|
||||
} else {
|
||||
let dst = &mut self.buf[self.pos..];
|
||||
slice::bytes::copy_memory(buf, dst);
|
||||
self.pos += buf.len();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
self.flush_buf().and_then(|()| self.inner.as_mut().unwrap().flush())
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<W: Writer> Drop for BufferedWriter<W> {
|
||||
fn drop(&mut self) {
|
||||
if self.inner.is_some() {
|
||||
// dtors should not panic, so we ignore a panicked flush
|
||||
let _ = self.flush_buf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a Writer and buffers output to it, flushing whenever a newline (`0x0a`,
|
||||
/// `'\n'`) is detected.
|
||||
///
|
||||
/// This writer will be flushed when it is dropped.
|
||||
pub struct LineBufferedWriter<W: Writer> {
|
||||
inner: BufferedWriter<W>,
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<W: Writer> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
|
||||
self.inner.inner, self.inner.pos, self.inner.buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Writer> LineBufferedWriter<W> {
|
||||
/// Creates a new `LineBufferedWriter`
|
||||
pub fn new(inner: W) -> LineBufferedWriter<W> {
|
||||
// Lines typically aren't that long, don't use a giant buffer
|
||||
LineBufferedWriter {
|
||||
inner: BufferedWriter::with_capacity(1024, inner)
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying writer.
|
||||
///
|
||||
/// This type does not expose the ability to get a mutable reference to the
|
||||
/// underlying reader because that could possibly corrupt the buffer.
|
||||
pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
|
||||
|
||||
/// Unwraps this `LineBufferedWriter`, returning the underlying writer.
|
||||
///
|
||||
/// The internal buffer is flushed before returning the writer.
|
||||
pub fn into_inner(self) -> W { self.inner.into_inner() }
|
||||
}
|
||||
|
||||
impl<W: Writer> Writer for LineBufferedWriter<W> {
|
||||
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
match buf.iter().rposition(|&b| b == b'\n') {
|
||||
Some(i) => {
|
||||
try!(self.inner.write_all(&buf[..i + 1]));
|
||||
try!(self.inner.flush());
|
||||
try!(self.inner.write_all(&buf[i + 1..]));
|
||||
Ok(())
|
||||
}
|
||||
None => self.inner.write_all(buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
|
||||
}
|
||||
|
||||
struct InternalBufferedWriter<W: Writer>(BufferedWriter<W>);
|
||||
|
||||
impl<W: Writer> InternalBufferedWriter<W> {
|
||||
fn get_mut<'a>(&'a mut self) -> &'a mut BufferedWriter<W> {
|
||||
let InternalBufferedWriter(ref mut w) = *self;
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Reader + Writer> Reader for InternalBufferedWriter<W> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
self.get_mut().inner.as_mut().unwrap().read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a Stream and buffers input and output to and from it.
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with a `Stream`. For
|
||||
/// example, every call to `read` or `write` on `TcpStream` results in a system
|
||||
/// call. A `BufferedStream` keeps in memory buffers of data, making large,
|
||||
/// infrequent calls to `read` and `write` on the underlying `Stream`.
|
||||
///
|
||||
/// The output half will be flushed when this stream is dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(old_io, old_path)]
|
||||
/// # #![allow(unused_must_use)]
|
||||
/// use std::old_io::*;
|
||||
/// use std::old_path::Path;
|
||||
///
|
||||
/// let file = File::open(&Path::new("message.txt"));
|
||||
/// let mut stream = BufferedStream::new(file);
|
||||
///
|
||||
/// stream.write_all("hello, world".as_bytes());
|
||||
/// stream.flush();
|
||||
///
|
||||
/// let mut buf = [0; 100];
|
||||
/// match stream.read(&mut buf) {
|
||||
/// Ok(nread) => println!("Read {} bytes", nread),
|
||||
/// Err(e) => println!("error reading: {}", e)
|
||||
/// }
|
||||
/// ```
|
||||
pub struct BufferedStream<S: Writer> {
|
||||
inner: BufferedReader<InternalBufferedWriter<S>>
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<S: Writer> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let reader = &self.inner;
|
||||
let writer = &self.inner.inner.0;
|
||||
write!(fmt, "BufferedStream {{ stream: {:?}, write_buffer: {}/{}, read_buffer: {}/{} }}",
|
||||
writer.inner,
|
||||
writer.pos, writer.buf.len(),
|
||||
reader.cap - reader.pos, reader.buf.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Stream> BufferedStream<S> {
|
||||
/// Creates a new buffered stream with explicitly listed capacities for the
|
||||
/// reader/writer buffer.
|
||||
pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
|
||||
-> BufferedStream<S> {
|
||||
let writer = BufferedWriter::with_capacity(writer_cap, inner);
|
||||
let internal_writer = InternalBufferedWriter(writer);
|
||||
let reader = BufferedReader::with_capacity(reader_cap,
|
||||
internal_writer);
|
||||
BufferedStream { inner: reader }
|
||||
}
|
||||
|
||||
/// Creates a new buffered stream with the default reader/writer buffer
|
||||
/// capacities.
|
||||
pub fn new(inner: S) -> BufferedStream<S> {
|
||||
BufferedStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
|
||||
inner)
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying stream.
|
||||
pub fn get_ref(&self) -> &S {
|
||||
let InternalBufferedWriter(ref w) = self.inner.inner;
|
||||
w.get_ref()
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying stream.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// It is inadvisable to read directly from or write directly to the
|
||||
/// underlying stream.
|
||||
pub fn get_mut(&mut self) -> &mut S {
|
||||
let InternalBufferedWriter(ref mut w) = self.inner.inner;
|
||||
w.get_mut()
|
||||
}
|
||||
|
||||
/// Unwraps this `BufferedStream`, returning the underlying stream.
|
||||
///
|
||||
/// The internal buffer is flushed before returning the stream. Any leftover
|
||||
/// data in the read buffer is lost.
|
||||
pub fn into_inner(self) -> S {
|
||||
let InternalBufferedWriter(w) = self.inner.inner;
|
||||
w.into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Stream> Buffer for BufferedStream<S> {
|
||||
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
|
||||
fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
|
||||
}
|
||||
|
||||
impl<S: Stream> Reader for BufferedStream<S> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
self.inner.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Stream> Writer for BufferedStream<S> {
|
||||
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.inner.inner.get_mut().write_all(buf)
|
||||
}
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
self.inner.inner.get_mut().flush()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
extern crate test;
|
||||
use old_io::{self, Reader, Writer, Buffer, BufferPrelude};
|
||||
use prelude::v1::*;
|
||||
use super::*;
|
||||
use super::super::{IoResult, EndOfFile};
|
||||
use super::super::mem::MemReader;
|
||||
use self::test::Bencher;
|
||||
|
||||
/// A type, free to create, primarily intended for benchmarking creation of
|
||||
/// wrappers that, just for construction, don't need a Reader/Writer that
|
||||
/// does anything useful. Is equivalent to `/dev/null` in semantics.
|
||||
#[derive(Clone,PartialEq,PartialOrd)]
|
||||
pub struct NullStream;
|
||||
|
||||
impl Reader for NullStream {
|
||||
fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
|
||||
Err(old_io::standard_error(old_io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer for NullStream {
|
||||
fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
|
||||
}
|
||||
|
||||
/// A dummy reader intended at testing short-reads propagation.
|
||||
pub struct ShortReader {
|
||||
lengths: Vec<usize>,
|
||||
}
|
||||
|
||||
impl Reader for ShortReader {
|
||||
fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
|
||||
if self.lengths.is_empty() {
|
||||
Err(old_io::standard_error(old_io::EndOfFile))
|
||||
} else {
|
||||
Ok(self.lengths.remove(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buffered_reader() {
|
||||
let inner = MemReader::new(vec!(5, 6, 7, 0, 1, 2, 3, 4));
|
||||
let mut reader = BufferedReader::with_capacity(2, inner);
|
||||
|
||||
let mut buf = [0, 0, 0];
|
||||
let nread = reader.read(&mut buf);
|
||||
assert_eq!(Ok(3), nread);
|
||||
let b: &[_] = &[5, 6, 7];
|
||||
assert_eq!(buf, b);
|
||||
|
||||
let mut buf = [0, 0];
|
||||
let nread = reader.read(&mut buf);
|
||||
assert_eq!(Ok(2), nread);
|
||||
let b: &[_] = &[0, 1];
|
||||
assert_eq!(buf, b);
|
||||
|
||||
let mut buf = [0];
|
||||
let nread = reader.read(&mut buf);
|
||||
assert_eq!(Ok(1), nread);
|
||||
let b: &[_] = &[2];
|
||||
assert_eq!(buf, b);
|
||||
|
||||
let mut buf = [0, 0, 0];
|
||||
let nread = reader.read(&mut buf);
|
||||
assert_eq!(Ok(1), nread);
|
||||
let b: &[_] = &[3, 0, 0];
|
||||
assert_eq!(buf, b);
|
||||
|
||||
let nread = reader.read(&mut buf);
|
||||
assert_eq!(Ok(1), nread);
|
||||
let b: &[_] = &[4, 0, 0];
|
||||
assert_eq!(buf, b);
|
||||
|
||||
assert!(reader.read(&mut buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buffered_writer() {
|
||||
let inner = Vec::new();
|
||||
let mut writer = BufferedWriter::with_capacity(2, inner);
|
||||
|
||||
writer.write_all(&[0, 1]).unwrap();
|
||||
let b: &[_] = &[];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
|
||||
writer.write_all(&[2]).unwrap();
|
||||
let b: &[_] = &[0, 1];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
|
||||
writer.write_all(&[3]).unwrap();
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
|
||||
writer.flush().unwrap();
|
||||
let a: &[_] = &[0, 1, 2, 3];
|
||||
assert_eq!(a, &writer.get_ref()[..]);
|
||||
|
||||
writer.write_all(&[4]).unwrap();
|
||||
writer.write_all(&[5]).unwrap();
|
||||
assert_eq!(a, &writer.get_ref()[..]);
|
||||
|
||||
writer.write_all(&[6]).unwrap();
|
||||
let a: &[_] = &[0, 1, 2, 3, 4, 5];
|
||||
assert_eq!(a, &writer.get_ref()[..]);
|
||||
|
||||
writer.write_all(&[7, 8]).unwrap();
|
||||
let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
|
||||
assert_eq!(a, &writer.get_ref()[..]);
|
||||
|
||||
writer.write_all(&[9, 10, 11]).unwrap();
|
||||
let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
||||
assert_eq!(a, &writer.get_ref()[..]);
|
||||
|
||||
writer.flush().unwrap();
|
||||
assert_eq!(a, &writer.get_ref()[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buffered_writer_inner_flushes() {
|
||||
let mut w = BufferedWriter::with_capacity(3, Vec::new());
|
||||
w.write_all(&[0, 1]).unwrap();
|
||||
let a: &[_] = &[];
|
||||
assert_eq!(&w.get_ref()[..], a);
|
||||
let w = w.into_inner();
|
||||
let a: &[_] = &[0, 1];
|
||||
assert_eq!(a, &w[..]);
|
||||
}
|
||||
|
||||
// This is just here to make sure that we don't infinite loop in the
|
||||
// newtype struct autoderef weirdness
|
||||
#[test]
|
||||
fn test_buffered_stream() {
|
||||
struct S;
|
||||
|
||||
impl old_io::Writer for S {
|
||||
fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
|
||||
}
|
||||
|
||||
impl old_io::Reader for S {
|
||||
fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
|
||||
Err(old_io::standard_error(old_io::EndOfFile))
|
||||
}
|
||||
}
|
||||
|
||||
let mut stream = BufferedStream::new(S);
|
||||
let mut buf = [];
|
||||
assert!(stream.read(&mut buf).is_err());
|
||||
stream.write_all(&buf).unwrap();
|
||||
stream.flush().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_until() {
|
||||
let inner = MemReader::new(vec!(0, 1, 2, 1, 0));
|
||||
let mut reader = BufferedReader::with_capacity(2, inner);
|
||||
assert_eq!(reader.read_until(0), Ok(vec!(0)));
|
||||
assert_eq!(reader.read_until(2), Ok(vec!(1, 2)));
|
||||
assert_eq!(reader.read_until(1), Ok(vec!(1)));
|
||||
assert_eq!(reader.read_until(8), Ok(vec!(0)));
|
||||
assert!(reader.read_until(9).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_line_buffer() {
|
||||
let mut writer = LineBufferedWriter::new(Vec::new());
|
||||
writer.write_all(&[0]).unwrap();
|
||||
let b: &[_] = &[];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
writer.write_all(&[1]).unwrap();
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
writer.flush().unwrap();
|
||||
let b: &[_] = &[0, 1];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
writer.write_all(&[0, b'\n', 1, b'\n', 2]).unwrap();
|
||||
let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n'];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
writer.flush().unwrap();
|
||||
let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
writer.write_all(&[3, b'\n']).unwrap();
|
||||
let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n'];
|
||||
assert_eq!(&writer.get_ref()[..], b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_line() {
|
||||
let in_buf = MemReader::new(b"a\nb\nc".to_vec());
|
||||
let mut reader = BufferedReader::with_capacity(2, in_buf);
|
||||
assert_eq!(reader.read_line(), Ok("a\n".to_string()));
|
||||
assert_eq!(reader.read_line(), Ok("b\n".to_string()));
|
||||
assert_eq!(reader.read_line(), Ok("c".to_string()));
|
||||
assert!(reader.read_line().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lines() {
|
||||
let in_buf = MemReader::new(b"a\nb\nc".to_vec());
|
||||
let mut reader = BufferedReader::with_capacity(2, in_buf);
|
||||
let mut it = reader.lines();
|
||||
assert_eq!(it.next(), Some(Ok("a\n".to_string())));
|
||||
assert_eq!(it.next(), Some(Ok("b\n".to_string())));
|
||||
assert_eq!(it.next(), Some(Ok("c".to_string())));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_reads() {
|
||||
let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]};
|
||||
let mut reader = BufferedReader::new(inner);
|
||||
let mut buf = [0, 0];
|
||||
assert_eq!(reader.read(&mut buf), Ok(0));
|
||||
assert_eq!(reader.read(&mut buf), Ok(1));
|
||||
assert_eq!(reader.read(&mut buf), Ok(2));
|
||||
assert_eq!(reader.read(&mut buf), Ok(0));
|
||||
assert_eq!(reader.read(&mut buf), Ok(1));
|
||||
assert_eq!(reader.read(&mut buf), Ok(0));
|
||||
assert!(reader.read(&mut buf).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_char_buffered() {
|
||||
let buf = [195, 159];
|
||||
let mut reader = BufferedReader::with_capacity(1, &buf[..]);
|
||||
assert_eq!(reader.read_char(), Ok('ß'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chars() {
|
||||
let buf = [195, 159, b'a'];
|
||||
let mut reader = BufferedReader::with_capacity(1, &buf[..]);
|
||||
let mut it = reader.chars();
|
||||
assert_eq!(it.next(), Some(Ok('ß')));
|
||||
assert_eq!(it.next(), Some(Ok('a')));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn dont_panic_in_drop_on_panicked_flush() {
|
||||
struct FailFlushWriter;
|
||||
|
||||
impl Writer for FailFlushWriter {
|
||||
fn write_all(&mut self, _buf: &[u8]) -> IoResult<()> { Ok(()) }
|
||||
fn flush(&mut self) -> IoResult<()> { Err(old_io::standard_error(EndOfFile)) }
|
||||
}
|
||||
|
||||
let writer = FailFlushWriter;
|
||||
let _writer = BufferedWriter::new(writer);
|
||||
|
||||
// If writer panics *again* due to the flush error then the process will abort.
|
||||
panic!();
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_buffered_reader(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
BufferedReader::new(NullStream)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_buffered_writer(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
BufferedWriter::new(NullStream)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_buffered_stream(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
BufferedStream::new(NullStream);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,247 +0,0 @@
|
|||
// Copyright 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.
|
||||
|
||||
use clone::Clone;
|
||||
use cmp;
|
||||
use sync::mpsc::{Sender, Receiver};
|
||||
use old_io;
|
||||
use option::Option::{None, Some};
|
||||
use result::Result::{Ok, Err};
|
||||
use slice::bytes;
|
||||
use super::{Buffer, Reader, Writer, IoResult};
|
||||
use vec::Vec;
|
||||
|
||||
/// Allows reading from a rx.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(old_io)]
|
||||
/// use std::sync::mpsc::channel;
|
||||
/// use std::old_io::*;
|
||||
///
|
||||
/// let (tx, rx) = channel();
|
||||
/// # drop(tx);
|
||||
/// let mut reader = ChanReader::new(rx);
|
||||
///
|
||||
/// let mut buf = [0; 100];
|
||||
/// match reader.read(&mut buf) {
|
||||
/// Ok(nread) => println!("Read {} bytes", nread),
|
||||
/// Err(e) => println!("read error: {}", e),
|
||||
/// }
|
||||
/// ```
|
||||
pub struct ChanReader {
|
||||
buf: Vec<u8>, // A buffer of bytes received but not consumed.
|
||||
pos: usize, // How many of the buffered bytes have already be consumed.
|
||||
rx: Receiver<Vec<u8>>, // The Receiver to pull data from.
|
||||
closed: bool, // Whether the channel this Receiver connects to has been closed.
|
||||
}
|
||||
|
||||
impl ChanReader {
|
||||
/// Wraps a `Port` in a `ChanReader` structure
|
||||
pub fn new(rx: Receiver<Vec<u8>>) -> ChanReader {
|
||||
ChanReader {
|
||||
buf: Vec::new(),
|
||||
pos: 0,
|
||||
rx: rx,
|
||||
closed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer for ChanReader {
|
||||
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||
if self.pos >= self.buf.len() {
|
||||
self.pos = 0;
|
||||
match self.rx.recv() {
|
||||
Ok(bytes) => {
|
||||
self.buf = bytes;
|
||||
},
|
||||
Err(..) => {
|
||||
self.closed = true;
|
||||
self.buf = Vec::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.closed {
|
||||
Err(old_io::standard_error(old_io::EndOfFile))
|
||||
} else {
|
||||
Ok(&self.buf[self.pos..])
|
||||
}
|
||||
}
|
||||
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.pos += amt;
|
||||
assert!(self.pos <= self.buf.len());
|
||||
}
|
||||
}
|
||||
|
||||
impl Reader for ChanReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
let mut num_read = 0;
|
||||
loop {
|
||||
let count = match self.fill_buf().ok() {
|
||||
Some(src) => {
|
||||
let dst = &mut buf[num_read..];
|
||||
let count = cmp::min(src.len(), dst.len());
|
||||
bytes::copy_memory(&src[..count], dst);
|
||||
count
|
||||
},
|
||||
None => 0,
|
||||
};
|
||||
self.consume(count);
|
||||
num_read += count;
|
||||
if num_read == buf.len() || self.closed {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if self.closed && num_read == 0 {
|
||||
Err(old_io::standard_error(old_io::EndOfFile))
|
||||
} else {
|
||||
Ok(num_read)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows writing to a tx.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(old_io, io)]
|
||||
/// # #![allow(unused_must_use)]
|
||||
/// use std::sync::mpsc::channel;
|
||||
/// use std::old_io::*;
|
||||
///
|
||||
/// let (tx, rx) = channel();
|
||||
/// # drop(rx);
|
||||
/// let mut writer = ChanWriter::new(tx);
|
||||
/// writer.write("hello, world".as_bytes());
|
||||
/// ```
|
||||
pub struct ChanWriter {
|
||||
tx: Sender<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl ChanWriter {
|
||||
/// Wraps a channel in a `ChanWriter` structure
|
||||
pub fn new(tx: Sender<Vec<u8>>) -> ChanWriter {
|
||||
ChanWriter { tx: tx }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Clone for ChanWriter {
|
||||
fn clone(&self) -> ChanWriter {
|
||||
ChanWriter { tx: self.tx.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer for ChanWriter {
|
||||
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
|
||||
self.tx.send(buf.to_vec()).map_err(|_| {
|
||||
old_io::IoError {
|
||||
kind: old_io::BrokenPipe,
|
||||
desc: "Pipe closed",
|
||||
detail: None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use prelude::v1::*;
|
||||
|
||||
use sync::mpsc::channel;
|
||||
use super::*;
|
||||
use old_io::{self, Reader, Writer, Buffer};
|
||||
use thread;
|
||||
|
||||
#[test]
|
||||
fn test_rx_reader() {
|
||||
let (tx, rx) = channel();
|
||||
thread::spawn(move|| {
|
||||
tx.send(vec![1, 2]).unwrap();
|
||||
tx.send(vec![]).unwrap();
|
||||
tx.send(vec![3, 4]).unwrap();
|
||||
tx.send(vec![5, 6]).unwrap();
|
||||
tx.send(vec![7, 8]).unwrap();
|
||||
});
|
||||
|
||||
let mut reader = ChanReader::new(rx);
|
||||
let mut buf = [0; 3];
|
||||
|
||||
assert_eq!(Ok(0), reader.read(&mut []));
|
||||
|
||||
assert_eq!(Ok(3), reader.read(&mut buf));
|
||||
let a: &[u8] = &[1,2,3];
|
||||
assert_eq!(a, buf);
|
||||
|
||||
assert_eq!(Ok(3), reader.read(&mut buf));
|
||||
let a: &[u8] = &[4,5,6];
|
||||
assert_eq!(a, buf);
|
||||
|
||||
assert_eq!(Ok(2), reader.read(&mut buf));
|
||||
let a: &[u8] = &[7,8,6];
|
||||
assert_eq!(a, buf);
|
||||
|
||||
match reader.read(&mut buf) {
|
||||
Ok(..) => panic!(),
|
||||
Err(e) => assert_eq!(e.kind, old_io::EndOfFile),
|
||||
}
|
||||
assert_eq!(a, buf);
|
||||
|
||||
// Ensure it continues to panic in the same way.
|
||||
match reader.read(&mut buf) {
|
||||
Ok(..) => panic!(),
|
||||
Err(e) => assert_eq!(e.kind, old_io::EndOfFile),
|
||||
}
|
||||
assert_eq!(a, buf);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rx_buffer() {
|
||||
let (tx, rx) = channel();
|
||||
thread::spawn(move|| {
|
||||
tx.send(b"he".to_vec()).unwrap();
|
||||
tx.send(b"llo wo".to_vec()).unwrap();
|
||||
tx.send(b"".to_vec()).unwrap();
|
||||
tx.send(b"rld\nhow ".to_vec()).unwrap();
|
||||
tx.send(b"are you?".to_vec()).unwrap();
|
||||
tx.send(b"".to_vec()).unwrap();
|
||||
});
|
||||
|
||||
let mut reader = ChanReader::new(rx);
|
||||
|
||||
assert_eq!(Ok("hello world\n".to_string()), reader.read_line());
|
||||
assert_eq!(Ok("how are you?".to_string()), reader.read_line());
|
||||
match reader.read_line() {
|
||||
Ok(..) => panic!(),
|
||||
Err(e) => assert_eq!(e.kind, old_io::EndOfFile),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chan_writer() {
|
||||
let (tx, rx) = channel();
|
||||
let mut writer = ChanWriter::new(tx);
|
||||
writer.write_be_u32(42).unwrap();
|
||||
|
||||
let wanted = vec![0, 0, 0, 42];
|
||||
let got = thread::scoped(move|| { rx.recv().unwrap() }).join();
|
||||
assert_eq!(wanted, got);
|
||||
|
||||
match writer.write_u8(1) {
|
||||
Ok(..) => panic!(),
|
||||
Err(e) => assert_eq!(e.kind, old_io::BrokenPipe),
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue