Merge remote-tracking branch 'origin/master' into 0.11.0-release
Conflicts: src/libstd/lib.rs
This commit is contained in:
commit
ff1dd44b40
715 changed files with 10358 additions and 8207 deletions
18
README.md
18
README.md
|
@ -54,10 +54,26 @@ documentation.
|
|||
When complete, `make install` will place several programs into
|
||||
`/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
|
||||
API-documentation tool.
|
||||
system.
|
||||
3. Read the [tutorial].
|
||||
4. Enjoy!
|
||||
|
||||
### Building on Windows
|
||||
|
||||
To easily build on windows we can use [MSYS2](http://sourceforge.net/projects/msys2/):
|
||||
|
||||
1. Grab the latest MSYS2 installer and go through the installer.
|
||||
2. Now from the MSYS2 terminal we want to install the mingw64 toolchain and the other
|
||||
tools we need.
|
||||
|
||||
$ pacman -S mingw-w64-i686-toolchain
|
||||
$ pacman -S base-devel
|
||||
|
||||
3. With that now start `mingw32_shell.bat` from where you installed MSYS2 (i.e. `C:\msys`).
|
||||
4. From there just navigate to where you have Rust's source code, configure and build it:
|
||||
|
||||
$ ./configure --build=i686-pc-mingw32
|
||||
$ make && make install
|
||||
|
||||
[repo]: https://github.com/rust-lang/rust
|
||||
[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz
|
||||
[tutorial]: http://doc.rust-lang.org/tutorial.html
|
||||
|
|
|
@ -38,6 +38,15 @@ directory to load plugins from (default: /tmp/rustdoc_ng/plugins)
|
|||
-L --library-path <val>
|
||||
directory to add to crate search path
|
||||
.TP
|
||||
--html-in-header <val>
|
||||
file to add to <head>
|
||||
.TP
|
||||
--html-before-content <val>
|
||||
file to add in <body>, before content
|
||||
.TP
|
||||
--html-after-content <val>
|
||||
file to add in <body>, after content
|
||||
.TP
|
||||
-h, --help
|
||||
Print help
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ PKG_FILES := \
|
|||
driver \
|
||||
etc \
|
||||
$(foreach crate,$(CRATES),lib$(crate)) \
|
||||
libcoretest \
|
||||
libbacktrace \
|
||||
rt \
|
||||
rustllvm \
|
||||
|
|
|
@ -35,16 +35,16 @@ DOCS := index intro tutorial guide guide-ffi guide-macros guide-lifetimes \
|
|||
PDF_DOCS := tutorial rust
|
||||
|
||||
RUSTDOC_DEPS_rust := doc/full-toc.inc
|
||||
RUSTDOC_FLAGS_rust := --markdown-in-header=doc/full-toc.inc
|
||||
RUSTDOC_FLAGS_rust := --html-in-header=doc/full-toc.inc
|
||||
|
||||
L10N_LANGS := ja
|
||||
|
||||
# Generally no need to edit below here.
|
||||
|
||||
# The options are passed to the documentation generators.
|
||||
RUSTDOC_HTML_OPTS_NO_CSS = --markdown-before-content=doc/version_info.html \
|
||||
--markdown-in-header=doc/favicon.inc \
|
||||
--markdown-after-content=doc/footer.inc \
|
||||
RUSTDOC_HTML_OPTS_NO_CSS = --html-before-content=doc/version_info.html \
|
||||
--html-in-header=doc/favicon.inc \
|
||||
--html-after-content=doc/footer.inc \
|
||||
--markdown-playground-url='http://play.rust-lang.org/'
|
||||
|
||||
RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css
|
||||
|
|
|
@ -14,7 +14,12 @@
|
|||
######################################################################
|
||||
|
||||
# The names of crates that must be tested
|
||||
TEST_TARGET_CRATES = $(TARGET_CRATES)
|
||||
|
||||
# libcore tests are in a separate crate
|
||||
DEPS_coretest :=
|
||||
$(eval $(call RUST_CRATE,coretest))
|
||||
|
||||
TEST_TARGET_CRATES = $(filter-out core,$(TARGET_CRATES)) coretest
|
||||
TEST_DOC_CRATES = $(DOC_CRATES)
|
||||
TEST_HOST_CRATES = $(HOST_CRATES)
|
||||
TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
|
||||
|
@ -172,7 +177,7 @@ check-notidy: cleantmptestlogs cleantestlibs all check-stage2
|
|||
$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
|
||||
|
||||
check-lite: cleantestlibs cleantmptestlogs \
|
||||
$(foreach crate,$(TARGET_CRATES),check-stage2-$(crate)) \
|
||||
$(foreach crate,$(TEST_TARGET_CRATES),check-stage2-$(crate)) \
|
||||
check-stage2-rpass \
|
||||
check-stage2-rfail check-stage2-cfail check-stage2-rmake
|
||||
$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
|
||||
|
|
|
@ -42,7 +42,7 @@ pub mod common;
|
|||
pub mod errors;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
|
|
|
@ -50,19 +50,19 @@ use libc::{c_int, size_t};
|
|||
|
||||
#[link(name = "snappy")]
|
||||
extern {
|
||||
fn snappy_compress(input: *u8,
|
||||
fn snappy_compress(input: *const u8,
|
||||
input_length: size_t,
|
||||
compressed: *mut u8,
|
||||
compressed_length: *mut size_t) -> c_int;
|
||||
fn snappy_uncompress(compressed: *u8,
|
||||
fn snappy_uncompress(compressed: *const u8,
|
||||
compressed_length: size_t,
|
||||
uncompressed: *mut u8,
|
||||
uncompressed_length: *mut size_t) -> c_int;
|
||||
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
|
||||
fn snappy_uncompressed_length(compressed: *u8,
|
||||
fn snappy_uncompressed_length(compressed: *const u8,
|
||||
compressed_length: size_t,
|
||||
result: *mut size_t) -> c_int;
|
||||
fn snappy_validate_compressed_buffer(compressed: *u8,
|
||||
fn snappy_validate_compressed_buffer(compressed: *const u8,
|
||||
compressed_length: size_t) -> c_int;
|
||||
}
|
||||
# fn main() {}
|
||||
|
@ -82,7 +82,7 @@ the allocated memory. The length is less than or equal to the capacity.
|
|||
~~~~
|
||||
# extern crate libc;
|
||||
# use libc::{c_int, size_t};
|
||||
# unsafe fn snappy_validate_compressed_buffer(_: *u8, _: size_t) -> c_int { 0 }
|
||||
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
|
||||
# fn main() {}
|
||||
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
|
||||
unsafe {
|
||||
|
@ -106,7 +106,7 @@ the true length after compression for setting the length.
|
|||
~~~~
|
||||
# extern crate libc;
|
||||
# use libc::{size_t, c_int};
|
||||
# unsafe fn snappy_compress(a: *u8, b: size_t, c: *mut u8,
|
||||
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
|
||||
# d: *mut size_t) -> c_int { 0 }
|
||||
# unsafe fn snappy_max_compressed_length(a: size_t) -> size_t { a }
|
||||
# fn main() {}
|
||||
|
@ -132,11 +132,11 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ
|
|||
~~~~
|
||||
# extern crate libc;
|
||||
# use libc::{size_t, c_int};
|
||||
# unsafe fn snappy_uncompress(compressed: *u8,
|
||||
# unsafe fn snappy_uncompress(compressed: *const u8,
|
||||
# compressed_length: size_t,
|
||||
# uncompressed: *mut u8,
|
||||
# uncompressed_length: *mut size_t) -> c_int { 0 }
|
||||
# unsafe fn snappy_uncompressed_length(compressed: *u8,
|
||||
# unsafe fn snappy_uncompressed_length(compressed: *const u8,
|
||||
# compressed_length: size_t,
|
||||
# result: *mut size_t) -> c_int { 0 }
|
||||
# fn main() {}
|
||||
|
@ -418,7 +418,7 @@ Unsafe functions, on the other hand, advertise it to the world. An unsafe functi
|
|||
this:
|
||||
|
||||
~~~~
|
||||
unsafe fn kaboom(ptr: *int) -> int { *ptr }
|
||||
unsafe fn kaboom(ptr: *const int) -> int { *ptr }
|
||||
~~~~
|
||||
|
||||
This function can only be called from an `unsafe` block or another `unsafe` function.
|
||||
|
@ -453,7 +453,7 @@ use std::ptr;
|
|||
|
||||
#[link(name = "readline")]
|
||||
extern {
|
||||
static mut rl_prompt: *libc::c_char;
|
||||
static mut rl_prompt: *const libc::c_char;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -478,7 +478,7 @@ extern crate libc;
|
|||
#[link(name = "kernel32")]
|
||||
#[allow(non_snake_case_functions)]
|
||||
extern "stdcall" {
|
||||
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> libc::c_int;
|
||||
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
|
||||
}
|
||||
# fn main() { }
|
||||
~~~~
|
||||
|
|
|
@ -355,6 +355,7 @@ macro_rules! biased_match_rec (
|
|||
_ => { $err }
|
||||
}
|
||||
);
|
||||
// Produce the requested values
|
||||
( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )
|
||||
)
|
||||
|
||||
|
@ -364,7 +365,7 @@ macro_rules! biased_match (
|
|||
( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
|
||||
binds $bind_res:ident
|
||||
) => (
|
||||
let ( $( $bind_res ),* ) = biased_match_rec!(
|
||||
let $bind_res = biased_match_rec!(
|
||||
$( ($e) ~ ($p) else $err ; )*
|
||||
binds $bind_res
|
||||
);
|
||||
|
|
|
@ -245,7 +245,7 @@ extern crate green;
|
|||
extern crate rustuv;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int {
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
green::start(argc, argv, rustuv::event_loop, main)
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,9 @@ inside of an OS thread.
|
|||
extern crate native;
|
||||
|
||||
#[start]
|
||||
fn start(argc: int, argv: **u8) -> int { native::start(argc, argv, main) }
|
||||
fn start(argc: int, argv: *const *const u8) -> int {
|
||||
native::start(argc, argv, main)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
~~~
|
||||
|
|
|
@ -457,6 +457,8 @@ the string in response. The child terminates when it receives `0`.
|
|||
Here is the function that implements the child task:
|
||||
|
||||
~~~
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::comm::DuplexStream;
|
||||
# fn main() {
|
||||
fn stringifier(channel: &DuplexStream<String, uint>) {
|
||||
|
@ -481,6 +483,8 @@ response itself is simply the stringified version of the received value,
|
|||
Here is the code for the parent task:
|
||||
|
||||
~~~
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::comm::duplex;
|
||||
# use std::task::spawn;
|
||||
# use std::comm::DuplexStream;
|
||||
|
|
|
@ -79,7 +79,7 @@ let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
|
|||
## Raw pointers
|
||||
|
||||
Rust offers two additional pointer types "raw pointers", written as
|
||||
`*T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
|
||||
`*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
|
||||
respectively; indeed, one of their most common uses is for FFI,
|
||||
interfacing with external C libraries.
|
||||
|
||||
|
@ -100,7 +100,7 @@ offered by the Rust language and libraries. For example, they
|
|||
- lack any form of lifetimes, unlike `&`, and so the compiler cannot
|
||||
reason about dangling pointers; and
|
||||
- have no guarantees about aliasing or mutability other than mutation
|
||||
not being allowed directly through a `*T`.
|
||||
not being allowed directly through a `*const T`.
|
||||
|
||||
Fortunately, they come with a redeeming feature: the weaker guarantees
|
||||
mean weaker restrictions. The missing restrictions make raw pointers
|
||||
|
@ -131,13 +131,13 @@ unsafe, and neither is converting to an integer.
|
|||
|
||||
At runtime, a raw pointer `*` and a reference pointing to the same
|
||||
piece of data have an identical representation. In fact, an `&T`
|
||||
reference will implicitly coerce to an `*T` raw pointer in safe code
|
||||
reference will implicitly coerce to an `*const T` raw pointer in safe code
|
||||
and similarly for the `mut` variants (both coercions can be performed
|
||||
explicitly with, respectively, `value as *T` and `value as *mut T`).
|
||||
explicitly with, respectively, `value as *const T` and `value as *mut T`).
|
||||
|
||||
Going the opposite direction, from `*` to a reference `&`, is not
|
||||
Going the opposite direction, from `*const` to a reference `&`, is not
|
||||
safe. A `&T` is always valid, and so, at a minimum, the raw pointer
|
||||
`*T` has to be a valid to a valid instance of type `T`. Furthermore,
|
||||
`*const T` has to be a valid to a valid instance of type `T`. Furthermore,
|
||||
the resulting pointer must satisfy the aliasing and mutability laws of
|
||||
references. The compiler assumes these properties are true for any
|
||||
references, no matter how they are created, and so any conversion from
|
||||
|
@ -149,7 +149,7 @@ The recommended method for the conversion is
|
|||
```
|
||||
let i: u32 = 1;
|
||||
// explicit cast
|
||||
let p_imm: *u32 = &i as *u32;
|
||||
let p_imm: *const u32 = &i as *const u32;
|
||||
let mut m: u32 = 2;
|
||||
// implicit coercion
|
||||
let p_mut: *mut u32 = &mut m;
|
||||
|
@ -256,7 +256,7 @@ impl<T: Send> Drop for Unique<T> {
|
|||
// Copy the object out from the pointer onto the stack,
|
||||
// where it is covered by normal Rust destructor semantics
|
||||
// and cleans itself up, if necessary
|
||||
ptr::read(self.ptr as *T);
|
||||
ptr::read(self.ptr as *const T);
|
||||
|
||||
// clean-up our allocation
|
||||
free(self.ptr as *mut c_void)
|
||||
|
@ -267,12 +267,12 @@ impl<T: Send> Drop for Unique<T> {
|
|||
// A comparison between the built-in `Box` and this reimplementation
|
||||
fn main() {
|
||||
{
|
||||
let mut x = box 5;
|
||||
let mut x = box 5i;
|
||||
*x = 10;
|
||||
} // `x` is freed here
|
||||
|
||||
{
|
||||
let mut y = Unique::new(5);
|
||||
let mut y = Unique::new(5i);
|
||||
*y.borrow_mut() = 10;
|
||||
} // `y` is freed here
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ extern crate libc;
|
|||
|
||||
// Entry point for this program
|
||||
#[start]
|
||||
fn start(_argc: int, _argv: **u8) -> int {
|
||||
fn start(_argc: int, _argv: *const *const u8) -> int {
|
||||
0
|
||||
}
|
||||
|
||||
|
@ -482,7 +482,7 @@ compiler's name mangling too:
|
|||
extern crate libc;
|
||||
|
||||
#[no_mangle] // ensure that this symbol is called `main` in the output
|
||||
pub extern fn main(argc: int, argv: **u8) -> int {
|
||||
pub extern fn main(argc: int, argv: *const *const u8) -> int {
|
||||
0
|
||||
}
|
||||
|
||||
|
@ -540,8 +540,8 @@ use core::mem;
|
|||
use core::raw::Slice;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn dot_product(a: *u32, a_len: u32,
|
||||
b: *u32, b_len: u32) -> u32 {
|
||||
pub extern fn dot_product(a: *const u32, a_len: u32,
|
||||
b: *const u32, b_len: u32) -> u32 {
|
||||
// Convert the provided arrays into Rust slices.
|
||||
// The core::raw module guarantees that the Slice
|
||||
// structure has the same memory layout as a &[T]
|
||||
|
@ -573,7 +573,7 @@ extern fn begin_unwind(args: &core::fmt::Arguments,
|
|||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
# #[start] fn start(argc: int, argv: **u8) -> int { 0 }
|
||||
# #[start] fn start(argc: int, argv: *const *const u8) -> int { 0 }
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
|
@ -627,7 +627,7 @@ via a declaration like
|
|||
extern "rust-intrinsic" {
|
||||
fn transmute<T, U>(x: T) -> U;
|
||||
|
||||
fn offset<T>(dst: *T, offset: int) -> *T;
|
||||
fn offset<T>(dst: *const T, offset: int) -> *const T;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -677,8 +677,8 @@ unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
|
|||
}
|
||||
|
||||
#[start]
|
||||
fn main(argc: int, argv: **u8) -> int {
|
||||
let x = box 1;
|
||||
fn main(argc: int, argv: *const *const u8) -> int {
|
||||
let x = box 1i;
|
||||
|
||||
0
|
||||
}
|
||||
|
|
242
src/doc/guide.md
242
src/doc/guide.md
|
@ -160,7 +160,7 @@ Save the file, and then type this into your terminal window:
|
|||
|
||||
```{bash}
|
||||
$ rustc hello_world.rs
|
||||
$ ./hello_world # just 'hello_world' on Windows
|
||||
$ ./hello_world # or hello_world.exe on Windows
|
||||
Hello, world
|
||||
```
|
||||
|
||||
|
@ -243,7 +243,7 @@ There are now two files: our source code, with the `.rs` extension, and the
|
|||
executable (`hello_world.exe` on Windows, `hello_world` everywhere else)
|
||||
|
||||
```{bash}
|
||||
$ ./hello_world # or ./hello_world.exe on Windows
|
||||
$ ./hello_world # or hello_world.exe on Windows
|
||||
```
|
||||
|
||||
This prints out our `Hello, world!` text to our terminal.
|
||||
|
@ -285,8 +285,9 @@ At first, your program doesn't have any dependencies, so we'll only be using
|
|||
the first part of its functionality. Eventually, we'll add more. Since we
|
||||
started off by using Cargo, it'll be easy to add later.
|
||||
|
||||
Let's convert Hello World to Cargo. The first thing we need to do is install
|
||||
it. To do this, we need to build it from source. There are no binaries yet.
|
||||
Let's convert Hello World to Cargo. The first thing we need to do to begin using Cargo
|
||||
is to install Cargo. To do this, we need to build it from source. There are no binaries
|
||||
yet.
|
||||
|
||||
First, let's go back to our projects directory. We don't want Cargo to
|
||||
live in our project!
|
||||
|
@ -412,6 +413,202 @@ rest of your Rust career.
|
|||
Next, we'll learn more about Rust itself, by starting to write a more complicated
|
||||
program. We hope you want to do more with Rust than just print "Hello, world!"
|
||||
|
||||
## Guessing Game
|
||||
|
||||
Let's write a bigger program in Rust. We could just go through a laundry list
|
||||
of Rust features, but that's boring. Instead, we'll learn more about how to
|
||||
code in Rust by writing a few example projects.
|
||||
|
||||
For our first project, we'll implement a classic beginner programming problem:
|
||||
the guessing game. Here's how it works: Our program will generate a random
|
||||
integer between one and a hundred. It will then prompt us to enter a guess.
|
||||
Upon entering our guess, it will tell us if we're too low or too high. Once we
|
||||
guess correctly, it will congratulate us, and print the number of guesses we've
|
||||
taken to the screen. Sound good? It sounds easy, but it'll end up showing off a
|
||||
number of basic features of Rust.
|
||||
|
||||
### Set up
|
||||
|
||||
Let's set up a new project. Go to your projects directory, and make a new
|
||||
directory for the project, as well as a `src` directory for our code:
|
||||
|
||||
```{bash}
|
||||
$ cd ~/projects
|
||||
$ mkdir guessing_game
|
||||
$ cd guessing_game
|
||||
$ mkdir src
|
||||
```
|
||||
|
||||
Great. Next, let's make a `Cargo.toml` file so Cargo knows how to build our
|
||||
project:
|
||||
|
||||
```{ignore}
|
||||
[package]
|
||||
|
||||
name = "guessing_game"
|
||||
version = "0.1.0"
|
||||
authors = [ "someone@example.com" ]
|
||||
|
||||
[[bin]]
|
||||
|
||||
name = "guessing_game"
|
||||
```
|
||||
|
||||
Finally, we need our source file. Let's just make it hello world for now, so we
|
||||
can check that our setup works. In `src/guessing_game.rs`:
|
||||
|
||||
```{rust}
|
||||
fn main() {
|
||||
println!("Hello world!");
|
||||
}
|
||||
```
|
||||
|
||||
Let's make sure that worked:
|
||||
|
||||
```{bash}
|
||||
$ cargo build
|
||||
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
|
||||
$
|
||||
```
|
||||
|
||||
Excellent! Open up your `src/guessing_game.rs` again. We'll be writing all of
|
||||
our code in this file. The next section of the tutorial will show you how to
|
||||
build multiple-file projects.
|
||||
|
||||
## Variable bindings
|
||||
|
||||
The first thing we'll learn about are 'variable bindings.' They look like this:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
```
|
||||
|
||||
In many languages, this is called a 'variable.' But Rust's variable bindings
|
||||
have a few tricks up their sleeves. Rust has a very powerful feature called
|
||||
'pattern matching' that we'll get into detail with later, but the left
|
||||
hand side of a `let` expression is a full pattern, not just a variable name.
|
||||
This means we can do things like:
|
||||
|
||||
```{rust}
|
||||
let (x, y) = (1i, 2i);
|
||||
```
|
||||
|
||||
After this expression is evaluated, `x` will be one, and `y` will be two.
|
||||
Patterns are really powerful, but this is about all we can do with them so far.
|
||||
So let's just keep this in the back of our minds as we go forward.
|
||||
|
||||
By the way, in these examples, `i` indicates that the number is an integer.
|
||||
|
||||
Rust is a statically typed language, which means that we specify our types up
|
||||
front. So why does our first example compile? Well, Rust has this thing called
|
||||
"[Hindley-Milner type
|
||||
inference](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)",
|
||||
named after some really smart type theorists. If you clicked that link, don't
|
||||
be scared: what this means for you is that Rust will attempt to infer the types
|
||||
in your program, and it's pretty good at it. If it can infer the type, Rust
|
||||
doesn't require you to actually type it out.
|
||||
|
||||
We can add the type if we want to. Types come after a colon (`:`):
|
||||
|
||||
```{rust}
|
||||
let x: int = 5;
|
||||
```
|
||||
|
||||
If I asked you to read this out loud to the rest of the class, you'd say "`x`
|
||||
is a binding with the type `int` and the value `five`." Rust requires you to
|
||||
initialize the binding with a value before you're allowed to use it. If
|
||||
we try...
|
||||
|
||||
```{ignore}
|
||||
let x;
|
||||
```
|
||||
|
||||
...we'll get an error:
|
||||
|
||||
```{ignore}
|
||||
src/guessing_game.rs:2:9: 2:10 error: cannot determine a type for this local variable: unconstrained type
|
||||
src/guessing_game.rs:2 let x;
|
||||
^
|
||||
```
|
||||
|
||||
Giving it a type will compile, though:
|
||||
|
||||
```{ignore}
|
||||
let x: int;
|
||||
```
|
||||
|
||||
Let's try it out. Change your `src/guessing_game.rs` file to look like this:
|
||||
|
||||
```{rust}
|
||||
fn main() {
|
||||
let x: int;
|
||||
|
||||
println!("Hello world!");
|
||||
}
|
||||
```
|
||||
|
||||
You can use `cargo build` on the command line to build it. You'll get a warning,
|
||||
but it will still print "Hello, world!":
|
||||
|
||||
```{ignore,notrust}
|
||||
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
|
||||
src/guessing_game.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
|
||||
src/guessing_game.rs:2 let x: int;
|
||||
^
|
||||
```
|
||||
|
||||
Rust warns us that we never use the variable binding, but since we never use it,
|
||||
no harm, no foul. Things change if we try to actually use this `x`, however. Let's
|
||||
do that. Change your program to look like this:
|
||||
|
||||
```{rust,ignore}
|
||||
fn main() {
|
||||
let x: int;
|
||||
|
||||
println!("The value of x is: {}", x);
|
||||
}
|
||||
```
|
||||
|
||||
And try to build it. You'll get an error:
|
||||
|
||||
```{bash}
|
||||
$ cargo build
|
||||
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
|
||||
src/guessing_game.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
|
||||
src/guessing_game.rs:4 println!("The value of x is: {}", x);
|
||||
^
|
||||
note: in expansion of format_args!
|
||||
<std macros>:2:23: 2:77 note: expansion site
|
||||
<std macros>:1:1: 3:2 note: in expansion of println!
|
||||
src/guessing_game.rs:4:5: 4:42 note: expansion site
|
||||
error: aborting due to previous error
|
||||
Could not execute process `rustc src/guessing_game.rs --crate-type bin --out-dir /home/you/projects/guessing_game/target -L /home/you/projects/guessing_game/target -L /home/you/projects/guessing_game/target/deps` (status=101)
|
||||
```
|
||||
|
||||
Rust will not let us use a value that has not been initialized. So why let us
|
||||
declare a binding without initializing it? You'd think our first example would
|
||||
have errored. Well, Rust is smarter than that. Before we get to that, let's talk
|
||||
about this stuff we've added to `println!`.
|
||||
|
||||
If you include two curly braces (`{}`, some call them moustaches...) in your
|
||||
string to print, Rust will interpret this as a request to interpolate some sort
|
||||
of value. **String interpolation** is a computer science term that means "stick
|
||||
in the middle of a string." We add a comma, and then `x`, to indicate that we
|
||||
want `x` to be the value we're interpolating. The comma is used to separate
|
||||
arguments we pass to functions and macros, if you're passing more than one.
|
||||
|
||||
When you just use the double curly braces, Rust will attempt to display the
|
||||
value in a meaningful way by checking out its type. If you want to specify the
|
||||
format in a more detailed manner, there are a [wide number of options
|
||||
available](/std/fmt/index.html). Fow now, we'll just stick to the default:
|
||||
integers aren't very complicated to print.
|
||||
|
||||
So, we've cleared up all of the confusion around bindings, with one exception:
|
||||
why does Rust let us declare a variable binding without an initial value if we
|
||||
must initialize the binding before we use it? And how does it know that we have
|
||||
or have not initialized the binding? For that, we need to learn our next
|
||||
concept: `if`.
|
||||
|
||||
## If
|
||||
|
||||
## Functions
|
||||
|
@ -420,16 +617,6 @@ return
|
|||
|
||||
comments
|
||||
|
||||
## Testing
|
||||
|
||||
attributes
|
||||
|
||||
stability markers
|
||||
|
||||
## Crates and Modules
|
||||
|
||||
visibility
|
||||
|
||||
## Compound Data Types
|
||||
|
||||
Tuples
|
||||
|
@ -450,10 +637,35 @@ loop
|
|||
|
||||
break/continue
|
||||
|
||||
iterators
|
||||
## Guessing Game: complete
|
||||
|
||||
At this point, you have successfully built the Guessing Game! Congratulations!
|
||||
For reference, [We've placed the sample code on
|
||||
GitHub](https://github.com/steveklabnik/guessing_game).
|
||||
|
||||
You've now learned the basic syntax of Rust. All of this is relatively close to
|
||||
various other programming languages you have used in the past. These
|
||||
fundamental syntactical and semantic elements will form the foundation for the
|
||||
rest of your Rust education.
|
||||
|
||||
Now that you're an expert at the basics, it's time to learn about some of
|
||||
Rust's more unique features.
|
||||
|
||||
## iterators
|
||||
|
||||
## Lambdas
|
||||
|
||||
## Testing
|
||||
|
||||
attributes
|
||||
|
||||
stability markers
|
||||
|
||||
## Crates and Modules
|
||||
|
||||
visibility
|
||||
|
||||
|
||||
## Generics
|
||||
|
||||
## Traits
|
||||
|
|
|
@ -133,7 +133,7 @@ Check it out:
|
|||
```
|
||||
|
||||
fn dangling() -> Box<int> {
|
||||
let i = box 1234;
|
||||
let i = box 1234i;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -143,8 +143,8 @@ fn add_one() -> int {
|
|||
}
|
||||
```
|
||||
|
||||
Now instead of a stack allocated `1234`,
|
||||
we have a heap allocated `box 1234`.
|
||||
Now instead of a stack allocated `1234i`,
|
||||
we have a heap allocated `box 1234i`.
|
||||
Whereas `&` borrows a pointer to existing memory,
|
||||
creating an owned box allocates memory on the heap and places a value in it,
|
||||
giving you the sole pointer to that memory.
|
||||
|
@ -152,7 +152,7 @@ You can roughly compare these two lines:
|
|||
|
||||
```
|
||||
// Rust
|
||||
let i = box 1234;
|
||||
let i = box 1234i;
|
||||
```
|
||||
|
||||
```cpp
|
||||
|
@ -252,7 +252,7 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
This will result an error indicating that the value is no longer in scope:
|
||||
The compiler will produce an error indicating that the value is no longer in scope:
|
||||
|
||||
```text
|
||||
concurrency.rs:12:20: 12:27 error: use of moved value: 'numbers'
|
||||
|
|
|
@ -442,17 +442,14 @@ of integer literal suffix:
|
|||
The type of an _unsuffixed_ integer literal is determined by type inference.
|
||||
If an integer type can be _uniquely_ determined from the surrounding program
|
||||
context, the unsuffixed integer literal has that type. If the program context
|
||||
underconstrains the type, the unsuffixed integer literal's type is `int`; if
|
||||
the program context overconstrains the type, it is considered a static type
|
||||
error.
|
||||
underconstrains the type, it is considered a static type error;
|
||||
if the program context overconstrains the type,
|
||||
it is also considered a static type error.
|
||||
|
||||
Examples of integer literals of various forms:
|
||||
|
||||
~~~~
|
||||
123; 0xff00; // type determined by program context
|
||||
// defaults to int in absence of type
|
||||
// information
|
||||
|
||||
123i; // type int
|
||||
123u; // type uint
|
||||
123_u; // type uint
|
||||
0xff_u8; // type u8
|
||||
|
@ -469,8 +466,10 @@ A _floating-point literal_ has one of two forms:
|
|||
second decimal literal.
|
||||
* A single _decimal literal_ followed by an _exponent_.
|
||||
|
||||
By default, a floating-point literal has a generic type, but will fall back to
|
||||
`f64`. A floating-point literal may be followed (immediately, without any
|
||||
By default, a floating-point literal has a generic type,
|
||||
and, like integer literals, the type must be uniquely determined
|
||||
from the context.
|
||||
A floating-point literal may be followed (immediately, without any
|
||||
spaces) by a _floating-point suffix_, which changes the type of the literal.
|
||||
There are two floating-point suffixes: `f32`, and `f64` (the 32-bit and 64-bit
|
||||
floating point types).
|
||||
|
@ -478,8 +477,8 @@ floating point types).
|
|||
Examples of floating-point literals of various forms:
|
||||
|
||||
~~~~
|
||||
123.0; // type f64
|
||||
0.1; // type f64
|
||||
123.0f64; // type f64
|
||||
0.1f64; // type f64
|
||||
0.1f32; // type f32
|
||||
12E+99_f64; // type f64
|
||||
~~~~
|
||||
|
@ -1614,7 +1613,7 @@ extern crate libc;
|
|||
use libc::{c_char, FILE};
|
||||
|
||||
extern {
|
||||
fn fopen(filename: *c_char, mode: *c_char) -> *FILE;
|
||||
fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE;
|
||||
}
|
||||
# fn main() {}
|
||||
~~~~
|
||||
|
@ -2700,9 +2699,9 @@ must be a constant expression that can be evaluated at compile time, such
|
|||
as a [literal](#literals) or a [static item](#static-items).
|
||||
|
||||
~~~~
|
||||
[1, 2, 3, 4];
|
||||
[1i, 2, 3, 4];
|
||||
["a", "b", "c", "d"];
|
||||
[0, ..128]; // vector with 128 zeros
|
||||
[0i, ..128]; // vector with 128 zeros
|
||||
[0u8, 0u8, 0u8, 0u8];
|
||||
~~~~
|
||||
|
||||
|
@ -2881,7 +2880,7 @@ equals sign (`=`) and an [rvalue](#lvalues-rvalues-and-temporaries) expression.
|
|||
Evaluating an assignment expression [either copies or moves](#moved-and-copied-types) its right-hand operand to its left-hand operand.
|
||||
|
||||
~~~~
|
||||
# let mut x = 0;
|
||||
# let mut x = 0i;
|
||||
# let y = 0;
|
||||
|
||||
x = y;
|
||||
|
@ -2932,7 +2931,7 @@ paren_expr : '(' expr ')' ;
|
|||
An example of a parenthesized expression:
|
||||
|
||||
~~~~
|
||||
let x = (2 + 3) * 4;
|
||||
let x: int = (2 + 3) * 4;
|
||||
~~~~
|
||||
|
||||
|
||||
|
@ -3016,7 +3015,7 @@ conditional expression evaluates to `false`, the `while` expression completes.
|
|||
An example:
|
||||
|
||||
~~~~
|
||||
let mut i = 0;
|
||||
let mut i = 0u;
|
||||
|
||||
while i < 10 {
|
||||
println!("hello");
|
||||
|
@ -3262,7 +3261,7 @@ Patterns can also dereference pointers by using the `&`,
|
|||
on `x: &int` are equivalent:
|
||||
|
||||
~~~~
|
||||
# let x = &3;
|
||||
# let x = &3i;
|
||||
let y = match *x { 0 => "zero", _ => "some" };
|
||||
let z = match x { &0 => "zero", _ => "some" };
|
||||
|
||||
|
@ -3285,7 +3284,7 @@ A range of values may be specified with `..`.
|
|||
For example:
|
||||
|
||||
~~~~
|
||||
# let x = 2;
|
||||
# let x = 2i;
|
||||
|
||||
let message = match x {
|
||||
0 | 1 => "not many",
|
||||
|
|
|
@ -103,6 +103,17 @@ rustdoc can also generate JSON, for consumption by other tools, with
|
|||
`rustdoc --output-format json`, and also consume already-generated JSON with
|
||||
`rustdoc --input-format json`.
|
||||
|
||||
rustdoc also supports personalizing the output from crates' documentation,
|
||||
similar to markdown options.
|
||||
|
||||
- `--html-in-header FILE`: includes the contents of `FILE` at the
|
||||
end of the `<head>...</head>` section.
|
||||
- `--html-before-content FILE`: includes the contents of `FILE`
|
||||
directly after `<body>`, before the rendered content (including the
|
||||
search bar).
|
||||
- `--html-after-content FILE`: includes the contents of `FILE`
|
||||
after all the rendered content.
|
||||
|
||||
# Using the Documentation
|
||||
|
||||
The web pages generated by rustdoc present the same logical hierarchy that one
|
||||
|
@ -238,16 +249,16 @@ detected by a `.md` or `.markdown` extension.
|
|||
There are 4 options to modify the output that Rustdoc creates.
|
||||
|
||||
- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`.
|
||||
- `--markdown-in-header FILE`: includes the contents of `FILE` at the
|
||||
- `--html-in-header FILE`: includes the contents of `FILE` at the
|
||||
end of the `<head>...</head>` section.
|
||||
- `--markdown-before-content FILE`: includes the contents of `FILE`
|
||||
- `--html-before-content FILE`: includes the contents of `FILE`
|
||||
directly after `<body>`, before the rendered content (including the
|
||||
title).
|
||||
- `--markdown-after-content FILE`: includes the contents of `FILE`
|
||||
- `--html-after-content FILE`: includes the contents of `FILE`
|
||||
directly before `</body>`, after all the rendered content.
|
||||
|
||||
All of these can be specified multiple times, and they are output in
|
||||
the order in which they are specified. The first line of the file must
|
||||
the order in which they are specified. The first line of the file being rendered must
|
||||
be the title, prefixed with `%` (e.g. this page has `% Rust
|
||||
Documentation` on the first line).
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ write function, variable, and module names with lowercase letters, using
|
|||
underscores where they help readability, while writing types in camel case.
|
||||
|
||||
~~~
|
||||
let my_variable = 100;
|
||||
let my_variable = 100i;
|
||||
type MyType = int; // primitive types are _not_ camel case
|
||||
~~~
|
||||
|
||||
|
@ -276,7 +276,7 @@ write a piece of code like this:
|
|||
|
||||
~~~~
|
||||
# let item = "salad";
|
||||
let price;
|
||||
let price: f64;
|
||||
if item == "salad" {
|
||||
price = 3.50;
|
||||
} else if item == "muffin" {
|
||||
|
@ -290,7 +290,7 @@ But, in Rust, you don't have to repeat the name `price`:
|
|||
|
||||
~~~~
|
||||
# let item = "salad";
|
||||
let price =
|
||||
let price: f64 =
|
||||
if item == "salad" {
|
||||
3.50
|
||||
} else if item == "muffin" {
|
||||
|
@ -337,11 +337,10 @@ suffix that can be used to indicate the type of a literal: `i` for `int`,
|
|||
In the absence of an integer literal suffix, Rust will infer the
|
||||
integer type based on type annotations and function signatures in the
|
||||
surrounding program. In the absence of any type information at all,
|
||||
Rust will assume that an unsuffixed integer literal has type
|
||||
`int`.
|
||||
Rust will report an error and request that the type be specified explicitly.
|
||||
|
||||
~~~~
|
||||
let a = 1; // `a` is an `int`
|
||||
let a: int = 1; // `a` is an `int`
|
||||
let b = 10i; // `b` is an `int`, due to the `i` suffix
|
||||
let c = 100u; // `c` is a `uint`
|
||||
let d = 1000i32; // `d` is an `i32`
|
||||
|
@ -475,7 +474,7 @@ against each pattern in order until one matches. The matching pattern
|
|||
executes its corresponding arm.
|
||||
|
||||
~~~~
|
||||
let my_number = 1;
|
||||
let my_number = 1i;
|
||||
match my_number {
|
||||
0 => println!("zero"),
|
||||
1 | 2 => println!("one or two"),
|
||||
|
@ -501,7 +500,7 @@ matches any single value. (`..`) is a different wildcard that can match
|
|||
one or more fields in an `enum` variant.
|
||||
|
||||
~~~
|
||||
# let my_number = 1;
|
||||
# let my_number = 1i;
|
||||
match my_number {
|
||||
0 => { println!("zero") }
|
||||
_ => { println!("something else") }
|
||||
|
@ -584,7 +583,7 @@ keyword `break` aborts the loop, and `continue` aborts the current
|
|||
iteration and continues with the next.
|
||||
|
||||
~~~~
|
||||
let mut cake_amount = 8;
|
||||
let mut cake_amount = 8i;
|
||||
while cake_amount > 0 {
|
||||
cake_amount -= 1;
|
||||
}
|
||||
|
@ -944,7 +943,7 @@ The `box` operator performs memory allocation on the heap:
|
|||
~~~~
|
||||
{
|
||||
// an integer allocated on the heap
|
||||
let y = box 10;
|
||||
let y = box 10i;
|
||||
}
|
||||
// the destructor frees the heap memory as soon as `y` goes out of scope
|
||||
~~~~
|
||||
|
@ -1165,7 +1164,7 @@ let z = x;
|
|||
The mutability of a value may be changed by moving it to a new owner:
|
||||
|
||||
~~~~
|
||||
let r = box 13;
|
||||
let r = box 13i;
|
||||
let mut s = r; // box becomes mutable
|
||||
*s += 1;
|
||||
let t = s; // box becomes immutable
|
||||
|
@ -1285,9 +1284,9 @@ Using the generic `List<T>` works much like before, thanks to type inference:
|
|||
# Cons(value, box xs)
|
||||
# }
|
||||
let mut xs = Nil; // Unknown type! This is a `List<T>`, but `T` can be anything.
|
||||
xs = prepend(xs, 10); // Here the compiler infers `xs`'s type as `List<int>`.
|
||||
xs = prepend(xs, 15);
|
||||
xs = prepend(xs, 20);
|
||||
xs = prepend(xs, 10i); // Here the compiler infers `xs`'s type as `List<int>`.
|
||||
xs = prepend(xs, 15i);
|
||||
xs = prepend(xs, 20i);
|
||||
~~~
|
||||
|
||||
The code sample above demonstrates type inference making most type annotations optional. It is
|
||||
|
@ -1410,12 +1409,12 @@ Beyond the properties granted by the size, an owned box behaves as a regular
|
|||
value by inheriting the mutability and lifetime of the owner:
|
||||
|
||||
~~~~
|
||||
let x = 5; // immutable
|
||||
let mut y = 5; // mutable
|
||||
let x = 5i; // immutable
|
||||
let mut y = 5i; // mutable
|
||||
y += 2;
|
||||
|
||||
let x = box 5; // immutable
|
||||
let mut y = box 5; // mutable
|
||||
let x = box 5i; // immutable
|
||||
let mut y = box 5i; // mutable
|
||||
*y += 2; // the `*` operator is needed to access the contained value
|
||||
~~~~
|
||||
|
||||
|
@ -1507,7 +1506,7 @@ freezing enforced statically at compile-time. An example of a non-`Freeze` type
|
|||
is [`RefCell<T>`][refcell].
|
||||
|
||||
~~~~
|
||||
let mut x = 5;
|
||||
let mut x = 5i;
|
||||
{
|
||||
let y = &x; // `x` is now frozen. It cannot be modified or re-assigned.
|
||||
}
|
||||
|
@ -1523,8 +1522,8 @@ Rust uses the unary star operator (`*`) to access the contents of a
|
|||
box or pointer, similarly to C.
|
||||
|
||||
~~~
|
||||
let owned = box 10;
|
||||
let borrowed = &20;
|
||||
let owned = box 10i;
|
||||
let borrowed = &20i;
|
||||
|
||||
let sum = *owned + *borrowed;
|
||||
~~~
|
||||
|
@ -1534,9 +1533,9 @@ assignments. Such an assignment modifies the value that the pointer
|
|||
points to.
|
||||
|
||||
~~~
|
||||
let mut owned = box 10;
|
||||
let mut owned = box 10i;
|
||||
|
||||
let mut value = 20;
|
||||
let mut value = 20i;
|
||||
let borrowed = &mut value;
|
||||
|
||||
*owned = *borrowed + 100;
|
||||
|
@ -1654,12 +1653,12 @@ Unicode code points, so they cannot be freely mutated without the ability to
|
|||
alter the length.
|
||||
|
||||
~~~
|
||||
let mut xs = [1, 2, 3];
|
||||
let mut xs = [1i, 2i, 3i];
|
||||
let view = xs.mut_slice(0, 2);
|
||||
view[0] = 5;
|
||||
|
||||
// The type of a mutable slice is written as `&mut [T]`
|
||||
let ys: &mut [int] = &mut [1, 2, 3];
|
||||
let ys: &mut [int] = &mut [1i, 2i, 3i];
|
||||
~~~
|
||||
|
||||
Square brackets denote indexing into a slice or fixed-size vector:
|
||||
|
|
|
@ -44,6 +44,7 @@ exceptions = [
|
|||
"libsync/mpsc_intrusive.rs", # BSD
|
||||
"test/bench/shootout-binarytrees.rs", # BSD
|
||||
"test/bench/shootout-fannkuch-redux.rs", # BSD
|
||||
"test/bench/shootout-mandelbrot.rs", # BSD
|
||||
"test/bench/shootout-meteor.rs", # BSD
|
||||
"test/bench/shootout-pidigits.rs", # BSD
|
||||
"test/bench/shootout-regex-dna.rs", # BSD
|
||||
|
|
|
@ -77,34 +77,39 @@ syn keyword rustEnumVariant Ok Err
|
|||
"syn keyword rustFunction drop
|
||||
|
||||
" Types and traits {{{3
|
||||
syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr IntoBytes
|
||||
syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr
|
||||
syn keyword rustTrait IntoBytes
|
||||
syn keyword rustTrait ToCStr
|
||||
syn keyword rustTrait Char
|
||||
syn keyword rustTrait Clone
|
||||
syn keyword rustTrait Eq Ord PartialEq PartialOrd Ordering Equiv
|
||||
syn keyword rustTrait PartialEq PartialOrd Eq Ord Equiv
|
||||
syn keyword rustEnum Ordering
|
||||
syn keyword rustEnumVariant Less Equal Greater
|
||||
syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
|
||||
syn keyword rustTrait FromIterator Extendable
|
||||
syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator CloneableIterator
|
||||
syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
|
||||
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul
|
||||
syn keyword rustTrait Signed Unsigned
|
||||
syn keyword rustTrait Primitive Int Float FloatMath ToPrimitive FromPrimitive
|
||||
"syn keyword rustTrait Expect
|
||||
syn keyword rustTrait Collection Mutable Map MutableMap
|
||||
syn keyword rustTrait Set MutableSet
|
||||
syn keyword rustTrait FromIterator Extendable ExactSize
|
||||
syn keyword rustTrait Iterator DoubleEndedIterator
|
||||
syn keyword rustTrait RandomAccessIterator CloneableIterator
|
||||
syn keyword rustTrait OrdIterator MutableDoubleEndedIterator
|
||||
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv
|
||||
syn keyword rustTrait Signed Unsigned Primitive Int Float
|
||||
syn keyword rustTrait FloatMath ToPrimitive FromPrimitive
|
||||
syn keyword rustTrait Box
|
||||
syn keyword rustTrait GenericPath Path PosixPath WindowsPath
|
||||
syn keyword rustTrait RawPtr
|
||||
syn keyword rustTrait Buffer Writer Reader Seek
|
||||
syn keyword rustTrait Str StrVector StrSlice OwnedStr IntoMaybeOwned
|
||||
syn keyword rustTrait StrAllocating
|
||||
syn keyword rustTrait Str StrVector StrSlice OwnedStr
|
||||
syn keyword rustTrait IntoMaybeOwned StrAllocating
|
||||
syn keyword rustTrait ToStr IntoStr
|
||||
syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
|
||||
syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
|
||||
syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
|
||||
syn keyword rustTrait CloneableVector ImmutableCloneableVector MutableCloneableVector
|
||||
syn keyword rustTrait CloneableVector ImmutableCloneableVector
|
||||
syn keyword rustTrait MutableCloneableVector MutableOrdVector
|
||||
syn keyword rustTrait ImmutableVector MutableVector
|
||||
syn keyword rustTrait ImmutableEqVector ImmutableOrdVector MutableOrdVector
|
||||
syn keyword rustTrait Vector VectorVector OwnedVector MutableVectorAllocating
|
||||
syn keyword rustTrait ImmutableEqVector ImmutableOrdVector
|
||||
syn keyword rustTrait Vector VectorVector
|
||||
syn keyword rustTrait MutableVectorAllocating
|
||||
syn keyword rustTrait String
|
||||
syn keyword rustTrait Vec
|
||||
|
||||
|
|
|
@ -376,14 +376,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_live() {
|
||||
let x = Arc::new(5);
|
||||
let x = Arc::new(5i);
|
||||
let y = x.downgrade();
|
||||
assert!(y.upgrade().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dead() {
|
||||
let x = Arc::new(5);
|
||||
let x = Arc::new(5i);
|
||||
let y = x.downgrade();
|
||||
drop(x);
|
||||
assert!(y.upgrade().is_none());
|
||||
|
|
|
@ -99,7 +99,7 @@ pub static mut EMPTY: uint = 12345;
|
|||
#[inline]
|
||||
unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 {
|
||||
if size == 0 {
|
||||
&EMPTY as *uint as *mut u8
|
||||
&EMPTY as *const uint as *mut u8
|
||||
} else {
|
||||
allocate(size, align)
|
||||
}
|
||||
|
@ -144,9 +144,10 @@ mod imp {
|
|||
flags: c_int) -> size_t;
|
||||
fn je_dallocx(ptr: *mut c_void, flags: c_int);
|
||||
fn je_nallocx(size: size_t, flags: c_int) -> size_t;
|
||||
fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void, *c_char)>,
|
||||
fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void,
|
||||
*const c_char)>,
|
||||
cbopaque: *mut c_void,
|
||||
opts: *c_char);
|
||||
opts: *const c_char);
|
||||
}
|
||||
|
||||
// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough
|
||||
|
@ -226,7 +227,7 @@ mod imp {
|
|||
// a block of memory, so we special case everything under `*uint` to
|
||||
// just pass it to malloc, which is guaranteed to align to at least the
|
||||
// size of `*uint`.
|
||||
if align < mem::size_of::<*uint>() {
|
||||
if align < mem::size_of::<uint>() {
|
||||
libc_heap::malloc_raw(size)
|
||||
} else {
|
||||
let mut out = 0 as *mut libc::c_void;
|
||||
|
@ -244,7 +245,7 @@ mod imp {
|
|||
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
|
||||
old_size: uint) -> *mut u8 {
|
||||
let new_ptr = allocate(size, align);
|
||||
ptr::copy_memory(new_ptr, ptr as *u8, old_size);
|
||||
ptr::copy_memory(new_ptr, ptr as *const u8, old_size);
|
||||
deallocate(ptr, old_size, align);
|
||||
return new_ptr;
|
||||
}
|
||||
|
@ -328,7 +329,7 @@ mod bench {
|
|||
#[bench]
|
||||
fn alloc_owned_small(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
box 10
|
||||
box 10i
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
|
||||
#![no_std]
|
||||
#![feature(lang_items, phase, unsafe_destructor)]
|
||||
#![allow(unknown_features)] // NOTE: remove after a stage0 snap
|
||||
|
||||
#[phase(plugin, link)]
|
||||
extern crate core;
|
||||
|
|
|
@ -16,7 +16,9 @@ use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
|
|||
use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::intrinsics;
|
||||
use core::kinds::Send;
|
||||
use core::mem;
|
||||
use core::option::Option;
|
||||
use core::raw::TraitObject;
|
||||
use core::result::{Ok, Err, Result};
|
||||
|
||||
|
@ -36,7 +38,7 @@ pub static HEAP: () = ();
|
|||
|
||||
/// A type that represents a uniquely-owned value.
|
||||
#[lang="owned_box"]
|
||||
pub struct Box<T>(*T);
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
impl<T: Default> Default for Box<T> {
|
||||
fn default() -> Box<T> { box Default::default() }
|
||||
|
@ -63,6 +65,10 @@ impl<T:PartialEq> PartialEq for Box<T> {
|
|||
fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
impl<T:PartialOrd> PartialOrd for Box<T> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
|
||||
(**self).partial_cmp(*other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
|
||||
#[inline]
|
||||
|
@ -106,6 +112,34 @@ impl AnyOwnExt for Box<Any> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Extension methods for an owning `Any+Send` trait object
|
||||
pub trait AnySendOwnExt {
|
||||
/// Returns the boxed value if it is of type `T`, or
|
||||
/// `Err(Self)` if it isn't.
|
||||
fn move_send<T: 'static>(self) -> Result<Box<T>, Self>;
|
||||
}
|
||||
|
||||
impl AnySendOwnExt for Box<Any+Send> {
|
||||
#[inline]
|
||||
fn move_send<T: 'static>(self) -> Result<Box<T>, Box<Any+Send>> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
// Get the raw representation of the trait object
|
||||
let to: TraitObject =
|
||||
*mem::transmute::<&Box<Any+Send>, &TraitObject>(&self);
|
||||
|
||||
// Prevent destructor on self being run
|
||||
intrinsics::forget(self);
|
||||
|
||||
// Extract the data pointer
|
||||
Ok(mem::transmute(to.data))
|
||||
}
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Show> fmt::Show for Box<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(**self).fmt(f)
|
||||
|
@ -117,3 +151,51 @@ impl fmt::Show for Box<Any> {
|
|||
f.pad("Box<Any>")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_owned_clone() {
|
||||
let a = box 5i;
|
||||
let b: Box<int> = a.clone();
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_move() {
|
||||
let a = box 8u as Box<Any>;
|
||||
let b = box Test as Box<Any>;
|
||||
|
||||
match a.move::<uint>() {
|
||||
Ok(a) => { assert!(a == box 8u); }
|
||||
Err(..) => fail!()
|
||||
}
|
||||
match b.move::<Test>() {
|
||||
Ok(a) => { assert!(a == box Test); }
|
||||
Err(..) => fail!()
|
||||
}
|
||||
|
||||
let a = box 8u as Box<Any>;
|
||||
let b = box Test as Box<Any>;
|
||||
|
||||
assert!(a.move::<Box<Test>>().is_err());
|
||||
assert!(b.move::<Box<uint>>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let a = box 8u as Box<Any>;
|
||||
let b = box Test as Box<Any>;
|
||||
let a_str = a.to_str();
|
||||
let b_str = b.to_str();
|
||||
assert_eq!(a_str.as_slice(), "Box<Any>");
|
||||
assert_eq!(b_str.as_slice(), "Box<Any>");
|
||||
|
||||
let a = &8u as &Any;
|
||||
let b = &Test as &Any;
|
||||
let s = format!("{}", a);
|
||||
assert_eq!(s.as_slice(), "&Any");
|
||||
let s = format!("{}", b);
|
||||
assert_eq!(s.as_slice(), "&Any");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -10,16 +10,141 @@
|
|||
|
||||
/*! Task-local reference-counted boxes (`Rc` type)
|
||||
|
||||
The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
|
||||
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
|
||||
overhead of atomic reference counting.
|
||||
The `Rc` type provides shared ownership of an immutable value. Destruction is
|
||||
deterministic, and will occur as soon as the last owner is gone. It is marked
|
||||
as non-sendable because it avoids the overhead of atomic reference counting.
|
||||
|
||||
The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
|
||||
pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
|
||||
freed.
|
||||
The `downgrade` method can be used to create a non-owning `Weak` pointer to the
|
||||
box. A `Weak` pointer can be upgraded to an `Rc` pointer, but will return
|
||||
`None` if the value has already been freed.
|
||||
|
||||
For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
|
||||
pointers, and then storing the parent pointers as `Weak` pointers.
|
||||
For example, a tree with parent pointers can be represented by putting the
|
||||
nodes behind strong `Rc` pointers, and then storing the parent pointers as
|
||||
`Weak` pointers.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
Consider a scenario where a set of Gadgets are owned by a given Owner. We want
|
||||
to have our Gadgets point to their Owner. We can't do this with unique
|
||||
ownership, because more than one gadget may belong to the same Owner. Rc
|
||||
allows us to share an Owner between multiple Gadgets, and have the Owner kept
|
||||
alive as long as any Gadget points at it.
|
||||
|
||||
```rust
|
||||
use std::rc::Rc;
|
||||
|
||||
struct Owner {
|
||||
name: String
|
||||
// ...other fields
|
||||
}
|
||||
|
||||
struct Gadget {
|
||||
id: int,
|
||||
owner: Rc<Owner>
|
||||
// ...other fields
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Create a reference counted Owner.
|
||||
let gadget_owner : Rc<Owner> = Rc::new(
|
||||
Owner { name: String::from_str("Gadget Man") }
|
||||
);
|
||||
|
||||
// Create Gadgets belonging to gadget_owner. To increment the reference
|
||||
// count we clone the Rc object.
|
||||
let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() };
|
||||
let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() };
|
||||
|
||||
drop(gadget_owner);
|
||||
|
||||
// Despite dropping gadget_owner, we're still able to print out the name of
|
||||
// the Owner of the Gadgets. This is because we've only dropped the
|
||||
// reference count object, not the Owner it wraps. As long as there are
|
||||
// other Rc objects pointing at the same Owner, it will stay alive. Notice
|
||||
// that the Rc wrapper around Gadget.owner gets automatically dereferenced
|
||||
// for us.
|
||||
println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
|
||||
println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
|
||||
|
||||
// At the end of the method, gadget1 and gadget2 get destroyed, and with
|
||||
// them the last counted references to our Owner. Gadget Man now gets
|
||||
// destroyed as well.
|
||||
}
|
||||
```
|
||||
|
||||
If our requirements change, and we also need to be able to traverse from
|
||||
Owner->Gadget, we will run into problems: an Rc pointer from Owner->Gadget
|
||||
introduces a cycle between the objects. This means that their reference counts
|
||||
can never reach 0, and the objects will stay alive: a memory leak. In order to
|
||||
get around this, we can use `Weak` pointers. These are reference counted
|
||||
pointers that don't keep an object alive if there are no normal `Rc` (or
|
||||
*strong*) pointers left.
|
||||
|
||||
Rust actually makes it somewhat difficult to produce this loop in the first
|
||||
place: in order to end up with two objects that point at each other, one of
|
||||
them needs to be mutable. This is problematic because Rc enforces memory
|
||||
safety by only giving out shared references to the object it wraps, and these
|
||||
don't allow direct mutation. We need to wrap the part of the object we wish to
|
||||
mutate in a `RefCell`, which provides *interior mutability*: a method to
|
||||
achieve mutability through a shared reference. `RefCell` enforces Rust's
|
||||
borrowing rules at runtime. Read the `Cell` documentation for more details on
|
||||
interior mutability.
|
||||
|
||||
```rust
|
||||
use std::rc::Rc;
|
||||
use std::rc::Weak;
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct Owner {
|
||||
name: String,
|
||||
gadgets: RefCell<Vec<Weak<Gadget>>>
|
||||
// ...other fields
|
||||
}
|
||||
|
||||
struct Gadget {
|
||||
id: int,
|
||||
owner: Rc<Owner>
|
||||
// ...other fields
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Create a reference counted Owner. Note the fact that we've put the
|
||||
// Owner's vector of Gadgets inside a RefCell so that we can mutate it
|
||||
// through a shared reference.
|
||||
let gadget_owner : Rc<Owner> = Rc::new(
|
||||
Owner {
|
||||
name: "Gadget Man".to_string(),
|
||||
gadgets: RefCell::new(Vec::new())
|
||||
}
|
||||
);
|
||||
|
||||
// Create Gadgets belonging to gadget_owner as before.
|
||||
let gadget1 = Rc::new(Gadget{id: 1, owner: gadget_owner.clone()});
|
||||
let gadget2 = Rc::new(Gadget{id: 2, owner: gadget_owner.clone()});
|
||||
|
||||
// Add the Gadgets to their Owner. To do this we mutably borrow from
|
||||
// the RefCell holding the Owner's Gadgets.
|
||||
gadget_owner.gadgets.borrow_mut().push(gadget1.clone().downgrade());
|
||||
gadget_owner.gadgets.borrow_mut().push(gadget2.clone().downgrade());
|
||||
|
||||
// Iterate over our Gadgets, printing their details out
|
||||
for gadget_opt in gadget_owner.gadgets.borrow().iter() {
|
||||
|
||||
// gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee
|
||||
// that their object is still alive, we need to call upgrade() on them
|
||||
// to turn them into a strong reference. This returns an Option, which
|
||||
// contains a reference to our object if it still exists.
|
||||
let gadget = gadget_opt.upgrade().unwrap();
|
||||
println!("Gadget {} owned by {}", gadget.id, gadget.owner.name);
|
||||
}
|
||||
|
||||
// At the end of the method, gadget_owner, gadget1 and gadget2 get
|
||||
// destroyed. There are now no strong (Rc) references to the gadgets.
|
||||
// Once they get destroyed, the Gadgets get destroyed. This zeroes the
|
||||
// reference count on Gadget Man, so he gets destroyed as well.
|
||||
}
|
||||
```
|
||||
|
||||
*/
|
||||
|
||||
|
@ -27,6 +152,7 @@ use core::mem::transmute;
|
|||
use core::cell::Cell;
|
||||
use core::clone::Clone;
|
||||
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
|
||||
use core::default::Default;
|
||||
use core::kinds::marker;
|
||||
use core::ops::{Deref, Drop};
|
||||
use core::option::{Option, Some, None};
|
||||
|
@ -152,6 +278,13 @@ impl<T> Clone for Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Default for Rc<T> {
|
||||
#[inline]
|
||||
fn default() -> Rc<T> {
|
||||
Rc::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> PartialEq for Rc<T> {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
|
||||
|
@ -162,6 +295,11 @@ impl<T: PartialEq> PartialEq for Rc<T> {
|
|||
impl<T: Eq> Eq for Rc<T> {}
|
||||
|
||||
impl<T: PartialOrd> PartialOrd for Rc<T> {
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
|
||||
(**self).partial_cmp(&**other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ impl Chunk {
|
|||
self.data.borrow().capacity()
|
||||
}
|
||||
|
||||
unsafe fn as_ptr(&self) -> *u8 {
|
||||
unsafe fn as_ptr(&self) -> *const u8 {
|
||||
self.data.borrow().as_ptr()
|
||||
}
|
||||
}
|
||||
|
@ -140,22 +140,22 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
|||
let fill = chunk.fill.get();
|
||||
|
||||
while idx < fill {
|
||||
let tydesc_data: *uint = mem::transmute(buf.offset(idx as int));
|
||||
let tydesc_data: *const uint = mem::transmute(buf.offset(idx as int));
|
||||
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
|
||||
let (size, align) = ((*tydesc).size, (*tydesc).align);
|
||||
|
||||
let after_tydesc = idx + mem::size_of::<*TyDesc>();
|
||||
let after_tydesc = idx + mem::size_of::<*const TyDesc>();
|
||||
|
||||
let start = round_up(after_tydesc, align);
|
||||
|
||||
//debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
|
||||
// start, size, align, is_done);
|
||||
if is_done {
|
||||
((*tydesc).drop_glue)(buf.offset(start as int) as *i8);
|
||||
((*tydesc).drop_glue)(buf.offset(start as int) as *const i8);
|
||||
}
|
||||
|
||||
// Find where the next tydesc lives
|
||||
idx = round_up(start + size, mem::align_of::<*TyDesc>());
|
||||
idx = round_up(start + size, mem::align_of::<*const TyDesc>());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,12 +164,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
|
|||
// is necessary in order to properly do cleanup if a failure occurs
|
||||
// during an initializer.
|
||||
#[inline]
|
||||
fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
|
||||
fn bitpack_tydesc_ptr(p: *const TyDesc, is_done: bool) -> uint {
|
||||
p as uint | (is_done as uint)
|
||||
}
|
||||
#[inline]
|
||||
fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
|
||||
((p & !1) as *TyDesc, p & 1 == 1)
|
||||
fn un_bitpack_tydesc_ptr(p: uint) -> (*const TyDesc, bool) {
|
||||
((p & !1) as *const TyDesc, p & 1 == 1)
|
||||
}
|
||||
|
||||
impl Arena {
|
||||
|
@ -178,7 +178,7 @@ impl Arena {
|
|||
}
|
||||
|
||||
// Functions for the POD part of the arena
|
||||
fn alloc_copy_grow(&self, n_bytes: uint, align: uint) -> *u8 {
|
||||
fn alloc_copy_grow(&self, n_bytes: uint, align: uint) -> *const u8 {
|
||||
// Allocate a new chunk.
|
||||
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
|
||||
self.chunks.borrow_mut().push(self.copy_head.borrow().clone());
|
||||
|
@ -190,7 +190,7 @@ impl Arena {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn alloc_copy_inner(&self, n_bytes: uint, align: uint) -> *u8 {
|
||||
fn alloc_copy_inner(&self, n_bytes: uint, align: uint) -> *const u8 {
|
||||
let start = round_up(self.copy_head.borrow().fill.get(), align);
|
||||
|
||||
let end = start + n_bytes;
|
||||
|
@ -218,7 +218,8 @@ impl Arena {
|
|||
}
|
||||
|
||||
// Functions for the non-POD part of the arena
|
||||
fn alloc_noncopy_grow(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
|
||||
fn alloc_noncopy_grow(&self, n_bytes: uint,
|
||||
align: uint) -> (*const u8, *const u8) {
|
||||
// Allocate a new chunk.
|
||||
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
|
||||
self.chunks.borrow_mut().push(self.head.borrow().clone());
|
||||
|
@ -230,7 +231,8 @@ impl Arena {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn alloc_noncopy_inner(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
|
||||
fn alloc_noncopy_inner(&self, n_bytes: uint,
|
||||
align: uint) -> (*const u8, *const u8) {
|
||||
// Be careful to not maintain any `head` borrows active, because
|
||||
// `alloc_noncopy_grow` borrows it mutably.
|
||||
let (start, end, tydesc_start, head_capacity) = {
|
||||
|
@ -238,7 +240,7 @@ impl Arena {
|
|||
let fill = head.fill.get();
|
||||
|
||||
let tydesc_start = fill;
|
||||
let after_tydesc = fill + mem::size_of::<*TyDesc>();
|
||||
let after_tydesc = fill + mem::size_of::<*const TyDesc>();
|
||||
let start = round_up(after_tydesc, align);
|
||||
let end = start + n_bytes;
|
||||
|
||||
|
@ -250,7 +252,7 @@ impl Arena {
|
|||
}
|
||||
|
||||
let head = self.head.borrow();
|
||||
head.fill.set(round_up(end, mem::align_of::<*TyDesc>()));
|
||||
head.fill.set(round_up(end, mem::align_of::<*const TyDesc>()));
|
||||
|
||||
unsafe {
|
||||
let buf = head.as_ptr();
|
||||
|
@ -348,11 +350,11 @@ fn test_arena_destructors_fail() {
|
|||
/// run again for these objects.
|
||||
pub struct TypedArena<T> {
|
||||
/// A pointer to the next object to be allocated.
|
||||
ptr: Cell<*T>,
|
||||
ptr: Cell<*const T>,
|
||||
|
||||
/// A pointer to the end of the allocated area. When this pointer is
|
||||
/// reached, a new chunk is allocated.
|
||||
end: Cell<*T>,
|
||||
end: Cell<*const T>,
|
||||
|
||||
/// A pointer to the first arena segment.
|
||||
first: RefCell<TypedArenaChunkRef<T>>,
|
||||
|
@ -398,7 +400,7 @@ impl<T> TypedArenaChunk<T> {
|
|||
if intrinsics::needs_drop::<T>() {
|
||||
let mut start = self.start();
|
||||
for _ in range(0, len) {
|
||||
ptr::read(start as *T); // run the destructor on the pointer
|
||||
ptr::read(start as *const T); // run the destructor on the pointer
|
||||
start = start.offset(mem::size_of::<T>() as int)
|
||||
}
|
||||
}
|
||||
|
@ -417,8 +419,8 @@ impl<T> TypedArenaChunk<T> {
|
|||
|
||||
// Returns a pointer to the first allocated object.
|
||||
#[inline]
|
||||
fn start(&self) -> *u8 {
|
||||
let this: *TypedArenaChunk<T> = self;
|
||||
fn start(&self) -> *const u8 {
|
||||
let this: *const TypedArenaChunk<T> = self;
|
||||
unsafe {
|
||||
mem::transmute(round_up(this.offset(1) as uint,
|
||||
mem::min_align_of::<T>()))
|
||||
|
@ -427,7 +429,7 @@ impl<T> TypedArenaChunk<T> {
|
|||
|
||||
// Returns a pointer to the end of the allocated space.
|
||||
#[inline]
|
||||
fn end(&self) -> *u8 {
|
||||
fn end(&self) -> *const u8 {
|
||||
unsafe {
|
||||
let size = mem::size_of::<T>().checked_mul(&self.capacity).unwrap();
|
||||
self.start().offset(size as int)
|
||||
|
@ -448,8 +450,8 @@ impl<T> TypedArena<T> {
|
|||
pub fn with_capacity(capacity: uint) -> TypedArena<T> {
|
||||
let chunk = TypedArenaChunk::<T>::new(None, capacity);
|
||||
TypedArena {
|
||||
ptr: Cell::new(chunk.start() as *T),
|
||||
end: Cell::new(chunk.end() as *T),
|
||||
ptr: Cell::new(chunk.start() as *const T),
|
||||
end: Cell::new(chunk.end() as *const T),
|
||||
first: RefCell::new(Some(chunk)),
|
||||
}
|
||||
}
|
||||
|
@ -477,8 +479,8 @@ impl<T> TypedArena<T> {
|
|||
let chunk = self.first.borrow_mut().take_unwrap();
|
||||
let new_capacity = chunk.capacity.checked_mul(&2).unwrap();
|
||||
let chunk = TypedArenaChunk::<T>::new(Some(chunk), new_capacity);
|
||||
self.ptr.set(chunk.start() as *T);
|
||||
self.end.set(chunk.end() as *T);
|
||||
self.ptr.set(chunk.start() as *const T);
|
||||
self.end.set(chunk.end() as *const T);
|
||||
*self.first.borrow_mut() = Some(chunk)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,8 +107,8 @@ impl<K: Ord, V: Eq> PartialEq for BTree<K, V> {
|
|||
impl<K: Ord, V: Eq> Eq for BTree<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for BTree<K, V> {
|
||||
fn lt(&self, other: &BTree<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &BTree<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,8 +229,8 @@ impl<K: Ord, V: Eq> PartialEq for Node<K, V> {
|
|||
impl<K: Ord, V: Eq> Eq for Node<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for Node<K, V> {
|
||||
fn lt(&self, other: &Node<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &Node<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,8 +408,8 @@ impl<K: Ord, V: Eq> PartialEq for Leaf<K, V> {
|
|||
impl<K: Ord, V: Eq> Eq for Leaf<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for Leaf<K, V> {
|
||||
fn lt(&self, other: &Leaf<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &Leaf<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -638,8 +638,8 @@ impl<K: Ord, V: Eq> PartialEq for Branch<K, V> {
|
|||
impl<K: Ord, V: Eq> Eq for Branch<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for Branch<K, V> {
|
||||
fn lt(&self, other: &Branch<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &Branch<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -706,8 +706,8 @@ impl<K: Ord, V: Eq> PartialEq for LeafElt<K, V> {
|
|||
impl<K: Ord, V: Eq> Eq for LeafElt<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for LeafElt<K, V> {
|
||||
fn lt(&self, other: &LeafElt<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &LeafElt<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,8 +755,8 @@ impl<K: Ord, V: Eq> PartialEq for BranchElt<K, V>{
|
|||
impl<K: Ord, V: Eq> Eq for BranchElt<K, V>{}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for BranchElt<K, V> {
|
||||
fn lt(&self, other: &BranchElt<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &BranchElt<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -595,17 +595,8 @@ impl<A: PartialEq> PartialEq for DList<A> {
|
|||
}
|
||||
|
||||
impl<A: PartialOrd> PartialOrd for DList<A> {
|
||||
fn lt(&self, other: &DList<A>) -> bool {
|
||||
iter::order::lt(self.iter(), other.iter())
|
||||
}
|
||||
fn le(&self, other: &DList<A>) -> bool {
|
||||
iter::order::le(self.iter(), other.iter())
|
||||
}
|
||||
fn gt(&self, other: &DList<A>) -> bool {
|
||||
iter::order::gt(self.iter(), other.iter())
|
||||
}
|
||||
fn ge(&self, other: &DList<A>) -> bool {
|
||||
iter::order::ge(self.iter(), other.iter())
|
||||
fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
|
||||
iter::order::partial_cmp(self.iter(), other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -652,7 +643,7 @@ mod tests {
|
|||
(None , None ) => {}
|
||||
(None , _ ) => fail!("prev link for list_head"),
|
||||
(Some(p), Some(pptr)) => {
|
||||
assert_eq!(p as *Node<T>, pptr as *Node<T>);
|
||||
assert_eq!(p as *const Node<T>, pptr as *const Node<T>);
|
||||
}
|
||||
_ => fail!("prev link is none, not good"),
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ impl<S: Writer, T: Hash<S>> Hash<S> for Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Writer, T> Hash<S> for *T {
|
||||
impl<S: Writer, T> Hash<S> for *const T {
|
||||
#[inline]
|
||||
fn hash(&self, state: &mut S) {
|
||||
// NB: raw-pointer Hash does _not_ dereference
|
||||
|
@ -342,12 +342,12 @@ mod tests {
|
|||
assert_eq!(hasher.hash(& &[1u8, 2u8, 3u8]), 9);
|
||||
|
||||
unsafe {
|
||||
let ptr: *int = mem::transmute(5);
|
||||
let ptr: *const int = mem::transmute(5i);
|
||||
assert_eq!(hasher.hash(&ptr), 5);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ptr: *mut int = mem::transmute(5);
|
||||
let ptr: *mut int = mem::transmute(5i);
|
||||
assert_eq!(hasher.hash(&ptr), 5);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,8 +265,6 @@ pub fn hash_with_keys<T: Hash<SipState>>(k0: u64, k1: u64, value: &T) -> u64 {
|
|||
state.result()
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test::Bencher;
|
||||
|
|
|
@ -572,7 +572,7 @@ mod tests {
|
|||
fn bench_push_back(b: &mut test::Bencher) {
|
||||
let mut deq = RingBuf::new();
|
||||
b.iter(|| {
|
||||
deq.push_back(0);
|
||||
deq.push_back(0i);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -580,7 +580,7 @@ mod tests {
|
|||
fn bench_push_front(b: &mut test::Bencher) {
|
||||
let mut deq = RingBuf::new();
|
||||
b.iter(|| {
|
||||
deq.push_front(0);
|
||||
deq.push_front(0i);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -589,7 +589,7 @@ mod tests {
|
|||
let mut deq = RingBuf::new();
|
||||
b.iter(|| {
|
||||
for _ in range(0i, 65) {
|
||||
deq.push_front(1);
|
||||
deq.push_front(1i);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -651,10 +651,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_with_capacity() {
|
||||
let mut d = RingBuf::with_capacity(0);
|
||||
d.push_back(1);
|
||||
d.push_back(1i);
|
||||
assert_eq!(d.len(), 1);
|
||||
let mut d = RingBuf::with_capacity(50);
|
||||
d.push_back(1);
|
||||
d.push_back(1i);
|
||||
assert_eq!(d.len(), 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ Vectors are Rust's list type. Vectors contain zero or more values of
|
|||
homogeneous types:
|
||||
|
||||
```rust
|
||||
let int_vector = [1,2,3];
|
||||
let int_vector = [1i, 2i, 3i];
|
||||
let str_vector = ["one", "two", "three"];
|
||||
```
|
||||
|
||||
|
@ -41,9 +41,9 @@ An example is the method `.slice(a, b)` that returns an immutable "view" into
|
|||
a vector or a vector slice from the index interval `[a, b)`:
|
||||
|
||||
```rust
|
||||
let numbers = [0, 1, 2];
|
||||
let numbers = [0i, 1i, 2i];
|
||||
let last_numbers = numbers.slice(1, 3);
|
||||
// last_numbers is now &[1, 2]
|
||||
// last_numbers is now &[1i, 2i]
|
||||
```
|
||||
|
||||
Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
|
||||
|
@ -54,9 +54,9 @@ An example is the method `.push(element)` that will add an element at the end
|
|||
of the vector:
|
||||
|
||||
```rust
|
||||
let mut numbers = vec![0, 1, 2];
|
||||
let mut numbers = vec![0i, 1i, 2i];
|
||||
numbers.push(7);
|
||||
// numbers is now vec![0, 1, 2, 7];
|
||||
// numbers is now vec![0i, 1i, 2i, 7i];
|
||||
```
|
||||
|
||||
## Implementations of other traits
|
||||
|
@ -341,7 +341,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
|||
let mut j = i;
|
||||
unsafe {
|
||||
// `i` is in bounds.
|
||||
let read_ptr = buf_v.offset(i) as *T;
|
||||
let read_ptr = buf_v.offset(i) as *const T;
|
||||
|
||||
// find where to insert, we need to do strict <,
|
||||
// rather than <=, to maintain stability.
|
||||
|
@ -365,7 +365,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
|||
&*buf_v.offset(j),
|
||||
(i - j) as uint);
|
||||
ptr::copy_nonoverlapping_memory(buf_v.offset(j),
|
||||
&tmp as *T,
|
||||
&tmp as *const T,
|
||||
1);
|
||||
mem::forget(tmp);
|
||||
}
|
||||
|
@ -779,7 +779,7 @@ mod tests {
|
|||
fn test_is_empty() {
|
||||
let xs: [int, ..0] = [];
|
||||
assert!(xs.is_empty());
|
||||
assert!(![0].is_empty());
|
||||
assert!(![0i].is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1528,7 +1528,7 @@ mod tests {
|
|||
fn test_permute_fail() {
|
||||
let v = [(box 0i, Rc::new(0i)), (box 0i, Rc::new(0i)),
|
||||
(box 0i, Rc::new(0i)), (box 0i, Rc::new(0i))];
|
||||
let mut i = 0;
|
||||
let mut i = 0u;
|
||||
for _ in v.permutations() {
|
||||
if i == 2 {
|
||||
fail!()
|
||||
|
@ -1870,16 +1870,16 @@ mod tests {
|
|||
fn test_overflow_does_not_cause_segfault() {
|
||||
let mut v = vec![];
|
||||
v.reserve_exact(-1);
|
||||
v.push(1);
|
||||
v.push(1i);
|
||||
v.push(2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_overflow_does_not_cause_segfault_managed() {
|
||||
let mut v = vec![Rc::new(1)];
|
||||
let mut v = vec![Rc::new(1i)];
|
||||
v.reserve_exact(-1);
|
||||
v.push(Rc::new(2));
|
||||
v.push(Rc::new(2i));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2279,7 +2279,7 @@ mod bench {
|
|||
v.set_len(1024);
|
||||
}
|
||||
for x in v.mut_iter() {
|
||||
*x = 0;
|
||||
*x = 0i;
|
||||
}
|
||||
v
|
||||
});
|
||||
|
|
|
@ -97,6 +97,15 @@ Section: Creating a string
|
|||
///
|
||||
/// Returns `Err` with the original vector if the vector contains invalid
|
||||
/// UTF-8.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::str;
|
||||
/// let hello_vec = vec![104, 101, 108, 108, 111];
|
||||
/// let string = str::from_utf8_owned(hello_vec);
|
||||
/// assert_eq!(string, Ok("hello".to_string()));
|
||||
/// ```
|
||||
pub fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>> {
|
||||
String::from_utf8(vv)
|
||||
}
|
||||
|
@ -106,12 +115,28 @@ pub fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>> {
|
|||
/// # Failure
|
||||
///
|
||||
/// Fails if invalid UTF-8
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::str;
|
||||
/// let string = str::from_byte(104);
|
||||
/// assert_eq!(string.as_slice(), "h");
|
||||
/// ```
|
||||
pub fn from_byte(b: u8) -> String {
|
||||
assert!(b < 128u8);
|
||||
String::from_char(1, b as char)
|
||||
}
|
||||
|
||||
/// Convert a char to a string
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::str;
|
||||
/// let string = str::from_char('b');
|
||||
/// assert_eq!(string.as_slice(), "b");
|
||||
/// ```
|
||||
pub fn from_char(ch: char) -> String {
|
||||
let mut buf = String::new();
|
||||
buf.push_char(ch);
|
||||
|
@ -119,6 +144,15 @@ pub fn from_char(ch: char) -> String {
|
|||
}
|
||||
|
||||
/// Convert a vector of chars to a string
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::str;
|
||||
/// let chars = ['h', 'e', 'l', 'l', 'o'];
|
||||
/// let string = str::from_chars(chars);
|
||||
/// assert_eq!(string.as_slice(), "hello");
|
||||
/// ```
|
||||
pub fn from_chars(chs: &[char]) -> String {
|
||||
chs.iter().map(|c| *c).collect()
|
||||
}
|
||||
|
@ -572,8 +606,8 @@ impl<'a> Eq for MaybeOwned<'a> {}
|
|||
|
||||
impl<'a> PartialOrd for MaybeOwned<'a> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &MaybeOwned) -> bool {
|
||||
self.as_slice().lt(&other.as_slice())
|
||||
fn partial_cmp(&self, other: &MaybeOwned) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,7 +695,7 @@ pub mod raw {
|
|||
pub use core::str::raw::{slice_unchecked};
|
||||
|
||||
/// Create a Rust string from a *u8 buffer of the given length
|
||||
pub unsafe fn from_buf_len(buf: *u8, len: uint) -> String {
|
||||
pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
|
||||
let mut result = String::new();
|
||||
result.push_bytes(mem::transmute(Slice {
|
||||
data: buf,
|
||||
|
@ -671,7 +705,7 @@ pub mod raw {
|
|||
}
|
||||
|
||||
/// Create a Rust string from a null-terminated C string
|
||||
pub unsafe fn from_c_str(c_string: *i8) -> String {
|
||||
pub unsafe fn from_c_str(c_string: *const i8) -> String {
|
||||
let mut buf = String::new();
|
||||
let mut len = 0;
|
||||
while *c_string.offset(len) != 0 {
|
||||
|
@ -803,15 +837,9 @@ pub trait StrAllocating: Str {
|
|||
}
|
||||
|
||||
/// Converts to a vector of `u16` encoded as UTF-16.
|
||||
#[deprecated = "use `utf16_units` instead"]
|
||||
fn to_utf16(&self) -> Vec<u16> {
|
||||
let me = self.as_slice();
|
||||
let mut u = Vec::new();
|
||||
for ch in me.chars() {
|
||||
let mut buf = [0u16, ..2];
|
||||
let n = ch.encode_utf16(buf /* as mut slice! */);
|
||||
u.push_all(buf.slice_to(n));
|
||||
}
|
||||
u
|
||||
self.as_slice().utf16_units().collect::<Vec<u16>>()
|
||||
}
|
||||
|
||||
/// Given a string, make a new string with repeated copies of it.
|
||||
|
@ -1103,7 +1131,7 @@ mod tests {
|
|||
assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
|
||||
assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
|
||||
fn a_million_letter_a() -> String {
|
||||
let mut i = 0;
|
||||
let mut i = 0u;
|
||||
let mut rs = String::new();
|
||||
while i < 100000 {
|
||||
rs.push_str("aaaaaaaaaa");
|
||||
|
@ -1112,7 +1140,7 @@ mod tests {
|
|||
rs
|
||||
}
|
||||
fn half_a_million_letter_a() -> String {
|
||||
let mut i = 0;
|
||||
let mut i = 0u;
|
||||
let mut rs = String::new();
|
||||
while i < 100000 {
|
||||
rs.push_str("aaaaa");
|
||||
|
@ -1220,7 +1248,7 @@ mod tests {
|
|||
assert_eq!("华", data.slice(30, 33));
|
||||
|
||||
fn a_million_letter_x() -> String {
|
||||
let mut i = 0;
|
||||
let mut i = 0u;
|
||||
let mut rs = String::new();
|
||||
while i < 100000 {
|
||||
rs.push_str("华华华华华华华华华华");
|
||||
|
@ -1229,7 +1257,7 @@ mod tests {
|
|||
rs
|
||||
}
|
||||
fn half_a_million_letter_x() -> String {
|
||||
let mut i = 0;
|
||||
let mut i = 0u;
|
||||
let mut rs = String::new();
|
||||
while i < 100000 {
|
||||
rs.push_str("华华华华华");
|
||||
|
@ -1541,8 +1569,8 @@ mod tests {
|
|||
let n2: uint = v.len();
|
||||
assert_eq!(n1, n2);
|
||||
while i < n1 {
|
||||
let a: u8 = s1.as_slice()[i];
|
||||
let b: u8 = s2.as_slice()[i];
|
||||
let a: u8 = s1.as_bytes()[i];
|
||||
let b: u8 = s2.as_bytes()[i];
|
||||
debug!("{}", a);
|
||||
debug!("{}", b);
|
||||
assert_eq!(a, b);
|
||||
|
@ -1619,14 +1647,17 @@ mod tests {
|
|||
|
||||
for p in pairs.iter() {
|
||||
let (s, u) = (*p).clone();
|
||||
assert!(is_utf16(u.as_slice()));
|
||||
assert_eq!(s.to_utf16(), u);
|
||||
let s_as_utf16 = s.as_slice().utf16_units().collect::<Vec<u16>>();
|
||||
let u_as_string = from_utf16(u.as_slice()).unwrap();
|
||||
|
||||
assert_eq!(from_utf16(u.as_slice()).unwrap(), s);
|
||||
assert!(is_utf16(u.as_slice()));
|
||||
assert_eq!(s_as_utf16, u);
|
||||
|
||||
assert_eq!(u_as_string, s);
|
||||
assert_eq!(from_utf16_lossy(u.as_slice()), s);
|
||||
|
||||
assert_eq!(from_utf16(s.to_utf16().as_slice()).unwrap(), s);
|
||||
assert_eq!(from_utf16(u.as_slice()).unwrap().to_utf16(), u);
|
||||
assert_eq!(from_utf16(s_as_utf16.as_slice()).unwrap(), s);
|
||||
assert_eq!(u_as_string.as_slice().utf16_units().collect::<Vec<u16>>(), u);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ impl String {
|
|||
return None
|
||||
}
|
||||
|
||||
let byte = self.as_slice()[len - 1];
|
||||
let byte = self.as_bytes()[len - 1];
|
||||
self.vec.set_len(len - 1);
|
||||
Some(byte)
|
||||
}
|
||||
|
|
|
@ -56,23 +56,11 @@ impl<K: PartialEq + Ord, V: PartialEq> PartialEq for TreeMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
// Lexicographical comparison
|
||||
fn lt<K: PartialOrd + Ord, V: PartialOrd>(a: &TreeMap<K, V>,
|
||||
b: &TreeMap<K, V>) -> bool {
|
||||
// the Zip iterator is as long as the shortest of a and b.
|
||||
for ((key_a, value_a), (key_b, value_b)) in a.iter().zip(b.iter()) {
|
||||
if *key_a < *key_b { return true; }
|
||||
if *key_a > *key_b { return false; }
|
||||
if *value_a < *value_b { return true; }
|
||||
if *value_a > *value_b { return false; }
|
||||
}
|
||||
|
||||
a.len() < b.len()
|
||||
}
|
||||
|
||||
impl<K: PartialOrd + Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
|
||||
impl<K: Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &TreeMap<K, V>) -> bool { lt(self, other) }
|
||||
fn partial_cmp(&self, other: &TreeMap<K, V>) -> Option<Ordering> {
|
||||
iter::order::partial_cmp(self.iter(), other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
|
||||
|
@ -287,7 +275,7 @@ pub struct Entries<'a, K, V> {
|
|||
// See the comment on MutEntries; this is just to allow
|
||||
// code-sharing (for this immutable-values iterator it *could* very
|
||||
// well be Option<&'a TreeNode<K,V>>).
|
||||
node: *TreeNode<K, V>,
|
||||
node: *const TreeNode<K, V>,
|
||||
remaining_min: uint,
|
||||
remaining_max: uint
|
||||
}
|
||||
|
@ -468,11 +456,11 @@ define_iterator! {
|
|||
addr_mut = mut
|
||||
}
|
||||
|
||||
fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *TreeNode<K, V> {
|
||||
fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
|
||||
match *node {
|
||||
Some(ref n) => {
|
||||
let n: &TreeNode<K, V> = *n;
|
||||
n as *TreeNode<K, V>
|
||||
n as *const TreeNode<K, V>
|
||||
}
|
||||
None => ptr::null()
|
||||
}
|
||||
|
@ -568,9 +556,11 @@ impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
|
|||
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
|
||||
}
|
||||
|
||||
impl<T: PartialOrd + Ord> PartialOrd for TreeSet<T> {
|
||||
impl<T: Ord> PartialOrd for TreeSet<T> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &TreeSet<T>) -> bool { self.map < other.map }
|
||||
fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
|
||||
self.map.partial_cmp(&other.map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord + Show> Show for TreeSet<T> {
|
||||
|
|
|
@ -189,7 +189,9 @@ macro_rules! bound {
|
|||
// We like sharing code so much that even a little unsafe won't
|
||||
// stop us.
|
||||
let this = $this;
|
||||
let mut node = addr!(& $($mut_)* this.root as * $($mut_)* TrieNode<T>);
|
||||
let mut node = unsafe {
|
||||
mem::transmute::<_, uint>(&this.root) as *mut TrieNode<T>
|
||||
};
|
||||
|
||||
let key = $key;
|
||||
|
||||
|
@ -205,7 +207,10 @@ macro_rules! bound {
|
|||
let child_id = chunk(key, it.length);
|
||||
let (slice_idx, ret) = match children[child_id] {
|
||||
Internal(ref $($mut_)* n) => {
|
||||
node = addr!(& $($mut_)* **n as * $($mut_)* TrieNode<T>);
|
||||
node = unsafe {
|
||||
mem::transmute::<_, uint>(&**n)
|
||||
as *mut TrieNode<T>
|
||||
};
|
||||
(child_id + 1, false)
|
||||
}
|
||||
External(stored, _) => {
|
||||
|
|
|
@ -389,8 +389,8 @@ impl<T: PartialEq> PartialEq for Vec<T> {
|
|||
|
||||
impl<T: PartialOrd> PartialOrd for Vec<T> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Vec<T>) -> bool {
|
||||
self.as_slice() < other.as_slice()
|
||||
fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
|
||||
self.as_slice().partial_cmp(&other.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,7 +615,7 @@ impl<T> Vec<T> {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
let end = (self.ptr as *T).offset(self.len as int) as *mut T;
|
||||
let end = (self.ptr as *const T).offset(self.len as int) as *mut T;
|
||||
ptr::write(&mut *end, value);
|
||||
self.len += 1;
|
||||
}
|
||||
|
@ -674,7 +674,10 @@ impl<T> Vec<T> {
|
|||
#[inline]
|
||||
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
|
||||
unsafe {
|
||||
mem::transmute(Slice { data: self.as_mut_ptr() as *T, len: self.len })
|
||||
mem::transmute(Slice {
|
||||
data: self.as_mut_ptr() as *const T,
|
||||
len: self.len,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -956,7 +959,8 @@ impl<T> Vec<T> {
|
|||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if `index` is out of bounds of the vector.
|
||||
/// Fails if `index` is not between `0` and the vector's length (both
|
||||
/// bounds inclusive).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -964,6 +968,8 @@ impl<T> Vec<T> {
|
|||
/// let mut vec = vec!(1i, 2, 3);
|
||||
/// vec.insert(1, 4);
|
||||
/// assert_eq!(vec, vec!(1, 4, 2, 3));
|
||||
/// vec.insert(4, 5);
|
||||
/// assert_eq!(vec, vec!(1, 4, 2, 3, 5));
|
||||
/// ```
|
||||
pub fn insert(&mut self, index: uint, element: T) {
|
||||
let len = self.len();
|
||||
|
@ -1011,7 +1017,7 @@ impl<T> Vec<T> {
|
|||
let ptr = self.as_mut_ptr().offset(index as int);
|
||||
// copy it out, unsafely having a copy of the value on
|
||||
// the stack and in the vector at the same time.
|
||||
ret = Some(ptr::read(ptr as *T));
|
||||
ret = Some(ptr::read(ptr as *const T));
|
||||
|
||||
// Shift everything down to fill in that spot.
|
||||
ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
|
||||
|
@ -1200,15 +1206,15 @@ impl<T> Vec<T> {
|
|||
/// Modifying the vector may cause its buffer to be reallocated, which
|
||||
/// would also make any pointers to it invalid.
|
||||
#[inline]
|
||||
pub fn as_ptr(&self) -> *T {
|
||||
pub fn as_ptr(&self) -> *const T {
|
||||
// If we have a 0-sized vector, then the base pointer should not be NULL
|
||||
// because an iterator over the slice will attempt to yield the base
|
||||
// pointer as the first element in the vector, but this will end up
|
||||
// being Some(NULL) which is optimized to None.
|
||||
if mem::size_of::<T>() == 0 {
|
||||
1 as *T
|
||||
1 as *const T
|
||||
} else {
|
||||
self.ptr as *T
|
||||
self.ptr as *const T
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1542,7 +1548,7 @@ pub mod raw {
|
|||
/// The elements of the buffer are copied into the vector without cloning,
|
||||
/// as if `ptr::read()` were called on them.
|
||||
#[inline]
|
||||
pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> Vec<T> {
|
||||
pub unsafe fn from_buf<T>(ptr: *const T, elts: uint) -> Vec<T> {
|
||||
let mut dst = Vec::with_capacity(elts);
|
||||
dst.set_len(elts);
|
||||
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
|
||||
|
|
|
@ -115,179 +115,3 @@ impl<'a> AnyMutRefExt<'a> for &'a mut Any {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
use realstd::owned::{Box, AnyOwnExt};
|
||||
use realstd::str::Str;
|
||||
|
||||
#[deriving(PartialEq, Show)]
|
||||
struct Test;
|
||||
|
||||
static TEST: &'static str = "Test";
|
||||
|
||||
#[test]
|
||||
fn any_referenced() {
|
||||
let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any);
|
||||
|
||||
assert!(a.is::<uint>());
|
||||
assert!(!b.is::<uint>());
|
||||
assert!(!c.is::<uint>());
|
||||
|
||||
assert!(!a.is::<&'static str>());
|
||||
assert!(b.is::<&'static str>());
|
||||
assert!(!c.is::<&'static str>());
|
||||
|
||||
assert!(!a.is::<Test>());
|
||||
assert!(!b.is::<Test>());
|
||||
assert!(c.is::<Test>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_owning() {
|
||||
let (a, b, c) = (box 5u as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
|
||||
|
||||
assert!(a.is::<uint>());
|
||||
assert!(!b.is::<uint>());
|
||||
assert!(!c.is::<uint>());
|
||||
|
||||
assert!(!a.is::<&'static str>());
|
||||
assert!(b.is::<&'static str>());
|
||||
assert!(!c.is::<&'static str>());
|
||||
|
||||
assert!(!a.is::<Test>());
|
||||
assert!(!b.is::<Test>());
|
||||
assert!(c.is::<Test>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_as_ref() {
|
||||
let a = &5u as &Any;
|
||||
|
||||
match a.as_ref::<uint>() {
|
||||
Some(&5) => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match a.as_ref::<Test>() {
|
||||
None => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_as_mut() {
|
||||
let mut a = 5u;
|
||||
let mut b = box 7u;
|
||||
|
||||
let a_r = &mut a as &mut Any;
|
||||
let tmp: &mut uint = &mut *b;
|
||||
let b_r = tmp as &mut Any;
|
||||
|
||||
match a_r.as_mut::<uint>() {
|
||||
Some(x) => {
|
||||
assert_eq!(*x, 5u);
|
||||
*x = 612;
|
||||
}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match b_r.as_mut::<uint>() {
|
||||
Some(x) => {
|
||||
assert_eq!(*x, 7u);
|
||||
*x = 413;
|
||||
}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match a_r.as_mut::<Test>() {
|
||||
None => (),
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match b_r.as_mut::<Test>() {
|
||||
None => (),
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match a_r.as_mut::<uint>() {
|
||||
Some(&612) => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match b_r.as_mut::<uint>() {
|
||||
Some(&413) => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_move() {
|
||||
use realstd::any::Any;
|
||||
use realstd::result::{Ok, Err};
|
||||
let a = box 8u as Box<Any>;
|
||||
let b = box Test as Box<Any>;
|
||||
|
||||
match a.move::<uint>() {
|
||||
Ok(a) => { assert!(a == box 8u); }
|
||||
Err(..) => fail!()
|
||||
}
|
||||
match b.move::<Test>() {
|
||||
Ok(a) => { assert!(a == box Test); }
|
||||
Err(..) => fail!()
|
||||
}
|
||||
|
||||
let a = box 8u as Box<Any>;
|
||||
let b = box Test as Box<Any>;
|
||||
|
||||
assert!(a.move::<Box<Test>>().is_err());
|
||||
assert!(b.move::<Box<uint>>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
use realstd::to_str::ToStr;
|
||||
let a = box 8u as Box<::realstd::any::Any>;
|
||||
let b = box Test as Box<::realstd::any::Any>;
|
||||
let a_str = a.to_str();
|
||||
let b_str = b.to_str();
|
||||
assert_eq!(a_str.as_slice(), "Box<Any>");
|
||||
assert_eq!(b_str.as_slice(), "Box<Any>");
|
||||
|
||||
let a = &8u as &Any;
|
||||
let b = &Test as &Any;
|
||||
let s = format!("{}", a);
|
||||
assert_eq!(s.as_slice(), "&Any");
|
||||
let s = format!("{}", b);
|
||||
assert_eq!(s.as_slice(), "&Any");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_fixed_vec() {
|
||||
let test = [0u, ..8];
|
||||
let test = &test as &Any;
|
||||
assert!(test.is::<[uint, ..8]>());
|
||||
assert!(!test.is::<[uint, ..10]>());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod bench {
|
||||
extern crate test;
|
||||
|
||||
use any::{Any, AnyRefExt};
|
||||
use option::Some;
|
||||
use self::test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn bench_as_ref(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut x = 0i;
|
||||
let mut y = &mut x as &mut Any;
|
||||
test::black_box(&mut y);
|
||||
test::black_box(y.as_ref::<int>() == Some(&0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ impl AtomicBool {
|
|||
/// Load the value
|
||||
#[inline]
|
||||
pub fn load(&self, order: Ordering) -> bool {
|
||||
unsafe { atomic_load(self.v.get() as *uint, order) > 0 }
|
||||
unsafe { atomic_load(self.v.get() as *const uint, order) > 0 }
|
||||
}
|
||||
|
||||
/// Store the value
|
||||
|
@ -295,7 +295,7 @@ impl AtomicInt {
|
|||
/// Load the value
|
||||
#[inline]
|
||||
pub fn load(&self, order: Ordering) -> int {
|
||||
unsafe { atomic_load(self.v.get() as *int, order) }
|
||||
unsafe { atomic_load(self.v.get() as *const int, order) }
|
||||
}
|
||||
|
||||
/// Store the value
|
||||
|
@ -407,7 +407,7 @@ impl AtomicUint {
|
|||
/// Load the value
|
||||
#[inline]
|
||||
pub fn load(&self, order: Ordering) -> uint {
|
||||
unsafe { atomic_load(self.v.get() as *uint, order) }
|
||||
unsafe { atomic_load(self.v.get() as *const uint, order) }
|
||||
}
|
||||
|
||||
/// Store the value
|
||||
|
@ -520,7 +520,7 @@ impl<T> AtomicPtr<T> {
|
|||
#[inline]
|
||||
pub fn load(&self, order: Ordering) -> *mut T {
|
||||
unsafe {
|
||||
atomic_load(self.p.get() as **mut T, order) as *mut T
|
||||
atomic_load(self.p.get() as *const *mut T, order) as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,7 +560,7 @@ unsafe fn atomic_store<T>(dst: *mut T, val: T, order:Ordering) {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn atomic_load<T>(dst: *T, order:Ordering) -> T {
|
||||
unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_load_acq(dst),
|
||||
Relaxed => intrinsics::atomic_load_relaxed(dst),
|
||||
|
@ -693,97 +693,3 @@ pub fn fence(order: Ordering) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bool_() {
|
||||
let a = AtomicBool::new(false);
|
||||
assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
|
||||
assert_eq!(a.compare_and_swap(false, true, SeqCst), true);
|
||||
|
||||
a.store(false, SeqCst);
|
||||
assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bool_and() {
|
||||
let a = AtomicBool::new(true);
|
||||
assert_eq!(a.fetch_and(false, SeqCst),true);
|
||||
assert_eq!(a.load(SeqCst),false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_and() {
|
||||
let x = AtomicUint::new(0xf731);
|
||||
assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_or() {
|
||||
let x = AtomicUint::new(0xf731);
|
||||
assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_xor() {
|
||||
let x = AtomicUint::new(0xf731);
|
||||
assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_and() {
|
||||
let x = AtomicInt::new(0xf731);
|
||||
assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_or() {
|
||||
let x = AtomicInt::new(0xf731);
|
||||
assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_xor() {
|
||||
let x = AtomicInt::new(0xf731);
|
||||
assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
|
||||
}
|
||||
|
||||
static mut S_BOOL : AtomicBool = INIT_ATOMIC_BOOL;
|
||||
static mut S_INT : AtomicInt = INIT_ATOMIC_INT;
|
||||
static mut S_UINT : AtomicUint = INIT_ATOMIC_UINT;
|
||||
|
||||
#[test]
|
||||
fn static_init() {
|
||||
unsafe {
|
||||
assert!(!S_BOOL.load(SeqCst));
|
||||
assert!(S_INT.load(SeqCst) == 0);
|
||||
assert!(S_UINT.load(SeqCst) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_sizes() {
|
||||
unsafe {
|
||||
let mut slot = 0u16;
|
||||
assert_eq!(super::atomic_swap(&mut slot, 1, SeqCst), 0);
|
||||
|
||||
let mut slot = 0u8;
|
||||
assert_eq!(super::atomic_compare_and_swap(&mut slot, 1, 2, SeqCst), 0);
|
||||
|
||||
let slot = 0u32;
|
||||
assert_eq!(super::atomic_load(&slot, SeqCst), 0);
|
||||
|
||||
let mut slot = 0u64;
|
||||
super::atomic_store(&mut slot, 2, SeqCst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,10 +67,10 @@
|
|||
//!
|
||||
//! fn main() {
|
||||
//! let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
|
||||
//! shared_map.borrow_mut().insert("africa", 92388);
|
||||
//! shared_map.borrow_mut().insert("kyoto", 11837);
|
||||
//! shared_map.borrow_mut().insert("piccadilly", 11826);
|
||||
//! shared_map.borrow_mut().insert("marbles", 38);
|
||||
//! shared_map.borrow_mut().insert("africa", 92388i);
|
||||
//! shared_map.borrow_mut().insert("kyoto", 11837i);
|
||||
//! shared_map.borrow_mut().insert("piccadilly", 11826i);
|
||||
//! shared_map.borrow_mut().insert("marbles", 38i);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
@ -383,132 +383,3 @@ impl<'b, T> DerefMut<T> for RefMut<'b, T> {
|
|||
unsafe { &mut *self._parent.value.get() }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use mem::drop;
|
||||
|
||||
#[test]
|
||||
fn smoketest_cell() {
|
||||
let x = Cell::new(10i);
|
||||
assert!(x == Cell::new(10));
|
||||
assert!(x.get() == 10);
|
||||
x.set(20);
|
||||
assert!(x == Cell::new(20));
|
||||
assert!(x.get() == 20);
|
||||
|
||||
let y = Cell::new((30i, 40i));
|
||||
assert!(y == Cell::new((30, 40)));
|
||||
assert!(y.get() == (30, 40));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cell_has_sensible_show() {
|
||||
use str::StrSlice;
|
||||
use realstd::str::Str;
|
||||
|
||||
let x = Cell::new("foo bar");
|
||||
assert!(format!("{}", x).as_slice().contains(x.get()));
|
||||
|
||||
x.set("baz qux");
|
||||
assert!(format!("{}", x).as_slice().contains(x.get()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ref_and_refmut_have_sensible_show() {
|
||||
use str::StrSlice;
|
||||
use realstd::str::Str;
|
||||
|
||||
let refcell = RefCell::new("foo");
|
||||
|
||||
let refcell_refmut = refcell.borrow_mut();
|
||||
assert!(format!("{}", refcell_refmut).as_slice().contains("foo"));
|
||||
drop(refcell_refmut);
|
||||
|
||||
let refcell_ref = refcell.borrow();
|
||||
assert!(format!("{}", refcell_ref).as_slice().contains("foo"));
|
||||
drop(refcell_ref);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_imm_borrow() {
|
||||
let x = RefCell::new(0);
|
||||
let _b1 = x.borrow();
|
||||
x.borrow();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_mut_then_imm_borrow() {
|
||||
let x = RefCell::new(0);
|
||||
let _b1 = x.borrow_mut();
|
||||
assert!(x.try_borrow().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_imm_then_borrow_mut() {
|
||||
let x = RefCell::new(0);
|
||||
let _b1 = x.borrow();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_double_borrow_mut() {
|
||||
let x = RefCell::new(0);
|
||||
let _b1 = x.borrow_mut();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imm_release_borrow_mut() {
|
||||
let x = RefCell::new(0);
|
||||
{
|
||||
let _b1 = x.borrow();
|
||||
}
|
||||
x.borrow_mut();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_release_borrow_mut() {
|
||||
let x = RefCell::new(0);
|
||||
{
|
||||
let _b1 = x.borrow_mut();
|
||||
}
|
||||
x.borrow();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_borrow_single_release_no_borrow_mut() {
|
||||
let x = RefCell::new(0);
|
||||
let _b1 = x.borrow();
|
||||
{
|
||||
let _b2 = x.borrow();
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn discard_doesnt_unborrow() {
|
||||
let x = RefCell::new(0);
|
||||
let _b = x.borrow();
|
||||
let _ = _b;
|
||||
let _b = x.borrow_mut();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(experimental)]
|
||||
fn clone_ref_updates_flag() {
|
||||
let x = RefCell::new(0);
|
||||
{
|
||||
let b1 = x.borrow();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
{
|
||||
let _b2 = clone_ref(&b1);
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_some());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -602,205 +602,3 @@ impl Char for char {
|
|||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{escape_unicode, escape_default};
|
||||
|
||||
use char::Char;
|
||||
use slice::ImmutableVector;
|
||||
use option::{Some, None};
|
||||
use realstd::string::String;
|
||||
use realstd::str::Str;
|
||||
|
||||
#[test]
|
||||
fn test_is_lowercase() {
|
||||
assert!('a'.is_lowercase());
|
||||
assert!('ö'.is_lowercase());
|
||||
assert!('ß'.is_lowercase());
|
||||
assert!(!'Ü'.is_lowercase());
|
||||
assert!(!'P'.is_lowercase());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_uppercase() {
|
||||
assert!(!'h'.is_uppercase());
|
||||
assert!(!'ä'.is_uppercase());
|
||||
assert!(!'ß'.is_uppercase());
|
||||
assert!('Ö'.is_uppercase());
|
||||
assert!('T'.is_uppercase());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_whitespace() {
|
||||
assert!(' '.is_whitespace());
|
||||
assert!('\u2007'.is_whitespace());
|
||||
assert!('\t'.is_whitespace());
|
||||
assert!('\n'.is_whitespace());
|
||||
assert!(!'a'.is_whitespace());
|
||||
assert!(!'_'.is_whitespace());
|
||||
assert!(!'\u0000'.is_whitespace());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_digit() {
|
||||
assert_eq!('0'.to_digit(10u), Some(0u));
|
||||
assert_eq!('1'.to_digit(2u), Some(1u));
|
||||
assert_eq!('2'.to_digit(3u), Some(2u));
|
||||
assert_eq!('9'.to_digit(10u), Some(9u));
|
||||
assert_eq!('a'.to_digit(16u), Some(10u));
|
||||
assert_eq!('A'.to_digit(16u), Some(10u));
|
||||
assert_eq!('b'.to_digit(16u), Some(11u));
|
||||
assert_eq!('B'.to_digit(16u), Some(11u));
|
||||
assert_eq!('z'.to_digit(36u), Some(35u));
|
||||
assert_eq!('Z'.to_digit(36u), Some(35u));
|
||||
assert_eq!(' '.to_digit(10u), None);
|
||||
assert_eq!('$'.to_digit(36u), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_lowercase() {
|
||||
assert_eq!('A'.to_lowercase(), 'a');
|
||||
assert_eq!('Ö'.to_lowercase(), 'ö');
|
||||
assert_eq!('ß'.to_lowercase(), 'ß');
|
||||
assert_eq!('Ü'.to_lowercase(), 'ü');
|
||||
assert_eq!('💩'.to_lowercase(), '💩');
|
||||
assert_eq!('Σ'.to_lowercase(), 'σ');
|
||||
assert_eq!('Τ'.to_lowercase(), 'τ');
|
||||
assert_eq!('Ι'.to_lowercase(), 'ι');
|
||||
assert_eq!('Γ'.to_lowercase(), 'γ');
|
||||
assert_eq!('Μ'.to_lowercase(), 'μ');
|
||||
assert_eq!('Α'.to_lowercase(), 'α');
|
||||
assert_eq!('Σ'.to_lowercase(), 'σ');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_uppercase() {
|
||||
assert_eq!('a'.to_uppercase(), 'A');
|
||||
assert_eq!('ö'.to_uppercase(), 'Ö');
|
||||
assert_eq!('ß'.to_uppercase(), 'ß'); // not ẞ: Latin capital letter sharp s
|
||||
assert_eq!('ü'.to_uppercase(), 'Ü');
|
||||
assert_eq!('💩'.to_uppercase(), '💩');
|
||||
|
||||
assert_eq!('σ'.to_uppercase(), 'Σ');
|
||||
assert_eq!('τ'.to_uppercase(), 'Τ');
|
||||
assert_eq!('ι'.to_uppercase(), 'Ι');
|
||||
assert_eq!('γ'.to_uppercase(), 'Γ');
|
||||
assert_eq!('μ'.to_uppercase(), 'Μ');
|
||||
assert_eq!('α'.to_uppercase(), 'Α');
|
||||
assert_eq!('ς'.to_uppercase(), 'Σ');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_control() {
|
||||
assert!('\u0000'.is_control());
|
||||
assert!('\u0003'.is_control());
|
||||
assert!('\u0006'.is_control());
|
||||
assert!('\u0009'.is_control());
|
||||
assert!('\u007f'.is_control());
|
||||
assert!('\u0092'.is_control());
|
||||
assert!(!'\u0020'.is_control());
|
||||
assert!(!'\u0055'.is_control());
|
||||
assert!(!'\u0068'.is_control());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_digit() {
|
||||
assert!('2'.is_digit());
|
||||
assert!('7'.is_digit());
|
||||
assert!(!'c'.is_digit());
|
||||
assert!(!'i'.is_digit());
|
||||
assert!(!'z'.is_digit());
|
||||
assert!(!'Q'.is_digit());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_default() {
|
||||
fn string(c: char) -> String {
|
||||
let mut result = String::new();
|
||||
escape_default(c, |c| { result.push_char(c); });
|
||||
return result;
|
||||
}
|
||||
let s = string('\n');
|
||||
assert_eq!(s.as_slice(), "\\n");
|
||||
let s = string('\r');
|
||||
assert_eq!(s.as_slice(), "\\r");
|
||||
let s = string('\'');
|
||||
assert_eq!(s.as_slice(), "\\'");
|
||||
let s = string('"');
|
||||
assert_eq!(s.as_slice(), "\\\"");
|
||||
let s = string(' ');
|
||||
assert_eq!(s.as_slice(), " ");
|
||||
let s = string('a');
|
||||
assert_eq!(s.as_slice(), "a");
|
||||
let s = string('~');
|
||||
assert_eq!(s.as_slice(), "~");
|
||||
let s = string('\x00');
|
||||
assert_eq!(s.as_slice(), "\\x00");
|
||||
let s = string('\x1f');
|
||||
assert_eq!(s.as_slice(), "\\x1f");
|
||||
let s = string('\x7f');
|
||||
assert_eq!(s.as_slice(), "\\x7f");
|
||||
let s = string('\xff');
|
||||
assert_eq!(s.as_slice(), "\\xff");
|
||||
let s = string('\u011b');
|
||||
assert_eq!(s.as_slice(), "\\u011b");
|
||||
let s = string('\U0001d4b6');
|
||||
assert_eq!(s.as_slice(), "\\U0001d4b6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_unicode() {
|
||||
fn string(c: char) -> String {
|
||||
let mut result = String::new();
|
||||
escape_unicode(c, |c| { result.push_char(c); });
|
||||
return result;
|
||||
}
|
||||
let s = string('\x00');
|
||||
assert_eq!(s.as_slice(), "\\x00");
|
||||
let s = string('\n');
|
||||
assert_eq!(s.as_slice(), "\\x0a");
|
||||
let s = string(' ');
|
||||
assert_eq!(s.as_slice(), "\\x20");
|
||||
let s = string('a');
|
||||
assert_eq!(s.as_slice(), "\\x61");
|
||||
let s = string('\u011b');
|
||||
assert_eq!(s.as_slice(), "\\u011b");
|
||||
let s = string('\U0001d4b6');
|
||||
assert_eq!(s.as_slice(), "\\U0001d4b6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str() {
|
||||
use realstd::to_str::ToStr;
|
||||
let s = 't'.to_str();
|
||||
assert_eq!(s.as_slice(), "t");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_utf8() {
|
||||
fn check(input: char, expect: &[u8]) {
|
||||
let mut buf = [0u8, ..4];
|
||||
let n = input.encode_utf8(buf /* as mut slice! */);
|
||||
assert_eq!(buf.slice_to(n), expect);
|
||||
}
|
||||
|
||||
check('x', [0x78]);
|
||||
check('\u00e9', [0xc3, 0xa9]);
|
||||
check('\ua66e', [0xea, 0x99, 0xae]);
|
||||
check('\U0001f4a9', [0xf0, 0x9f, 0x92, 0xa9]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_utf16() {
|
||||
fn check(input: char, expect: &[u16]) {
|
||||
let mut buf = [0u16, ..2];
|
||||
let n = input.encode_utf16(buf /* as mut slice! */);
|
||||
assert_eq!(buf.slice_to(n), expect);
|
||||
}
|
||||
|
||||
check('x', [0x0078]);
|
||||
check('\u00e9', [0x00e9]);
|
||||
check('\ua66e', [0xa66e]);
|
||||
check('\U0001f4a9', [0xd83d, 0xdca9]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,63 +110,3 @@ extern_fn_clone!(A, B, C, D, E, F)
|
|||
extern_fn_clone!(A, B, C, D, E, F, G)
|
||||
extern_fn_clone!(A, B, C, D, E, F, G, H)
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use prelude::*;
|
||||
use realstd::owned::Box;
|
||||
use realstd::gc::{Gc, GC};
|
||||
|
||||
fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
|
||||
use realstd::clone::Clone;
|
||||
t.clone()
|
||||
}
|
||||
|
||||
fn realclone_from<T: ::realstd::clone::Clone>(t1: &mut T, t2: &T) {
|
||||
use realstd::clone::Clone;
|
||||
t1.clone_from(t2)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_owned_clone() {
|
||||
let a = box 5i;
|
||||
let b: Box<int> = realclone(&a);
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_managed_clone() {
|
||||
let a = box(GC) 5i;
|
||||
let b: Gc<int> = realclone(&a);
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrowed_clone() {
|
||||
let x = 5i;
|
||||
let y: &int = &x;
|
||||
let z: &int = (&y).clone();
|
||||
assert_eq!(*z, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone_from() {
|
||||
let a = box 5i;
|
||||
let mut b = box 10i;
|
||||
realclone_from(&mut b, &a);
|
||||
assert_eq!(*b, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extern_fn_clone() {
|
||||
trait Empty {}
|
||||
impl Empty for int {}
|
||||
|
||||
fn test_fn_a() -> f64 { 1.0 }
|
||||
fn test_fn_b<T: Empty>(x: T) -> T { x }
|
||||
fn test_fn_c(_: int, _: f64, _: int, _: int, _: int) {}
|
||||
|
||||
let _ = test_fn_a.clone();
|
||||
let _ = test_fn_b::<int>.clone();
|
||||
let _ = test_fn_c.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
|
||||
//! ```
|
||||
|
||||
use option::{Option, Some};
|
||||
#[cfg(stage0)]
|
||||
use option::None;
|
||||
|
||||
/// Trait for values that can be compared for equality and inequality.
|
||||
///
|
||||
/// This trait allows for partial equality, for types that do not have an
|
||||
|
@ -86,11 +90,11 @@ pub trait Eq: PartialEq {
|
|||
#[deriving(Clone, PartialEq, Show)]
|
||||
pub enum Ordering {
|
||||
/// An ordering where a compared value is less [than another].
|
||||
Less = -1,
|
||||
Less = -1i,
|
||||
/// An ordering where a compared value is equal [to another].
|
||||
Equal = 0,
|
||||
Equal = 0i,
|
||||
/// An ordering where a compared value is greater [than another].
|
||||
Greater = 1
|
||||
Greater = 1i,
|
||||
}
|
||||
|
||||
/// Trait for types that form a [total order](
|
||||
|
@ -127,7 +131,9 @@ impl Ord for Ordering {
|
|||
|
||||
impl PartialOrd for Ordering {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
|
||||
fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
|
||||
(*self as int).partial_cmp(&(*other as int))
|
||||
}
|
||||
}
|
||||
|
||||
/// Combine orderings, lexically.
|
||||
|
@ -145,7 +151,7 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
|
|||
|
||||
/// Trait for values that can be compared for a sort-order.
|
||||
///
|
||||
/// PartialOrd only requires implementation of the `lt` method,
|
||||
/// PartialOrd only requires implementation of the `partial_cmp` method,
|
||||
/// with the others generated from default implementations.
|
||||
///
|
||||
/// However it remains possible to implement the others separately for types
|
||||
|
@ -154,20 +160,57 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
|
|||
/// 5.11).
|
||||
#[lang="ord"]
|
||||
pub trait PartialOrd: PartialEq {
|
||||
/// This method returns an ordering between `self` and `other` values
|
||||
/// if one exists.
|
||||
#[cfg(stage0)]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (!self.lt(other), !other.lt(self)) {
|
||||
(false, false) => None,
|
||||
(false, true) => Some(Less),
|
||||
(true, false) => Some(Greater),
|
||||
(true, true) => Some(Equal),
|
||||
}
|
||||
}
|
||||
|
||||
/// This method returns an ordering between `self` and `other` values
|
||||
/// if one exists.
|
||||
#[cfg(not(stage0))]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
|
||||
|
||||
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
|
||||
fn lt(&self, other: &Self) -> bool;
|
||||
fn lt(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Less) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// This method tests less than or equal to (`<=`).
|
||||
#[inline]
|
||||
fn le(&self, other: &Self) -> bool { !other.lt(self) }
|
||||
fn le(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Less) | Some(Equal) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// This method tests greater than (`>`).
|
||||
#[inline]
|
||||
fn gt(&self, other: &Self) -> bool { other.lt(self) }
|
||||
fn gt(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Greater) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// This method tests greater than or equal to (`>=`).
|
||||
#[inline]
|
||||
fn ge(&self, other: &Self) -> bool { !self.lt(other) }
|
||||
fn ge(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Greater) | Some(Equal) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The equivalence relation. Two values may be equivalent even if they are
|
||||
|
@ -192,10 +235,10 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
|||
}
|
||||
|
||||
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
|
||||
#[cfg(not(test))]
|
||||
mod impls {
|
||||
use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
|
||||
Less, Greater, Equal};
|
||||
use option::{Option, Some, None};
|
||||
|
||||
macro_rules! eq_impl(
|
||||
($($t:ty)*) => ($(
|
||||
|
@ -228,6 +271,15 @@ mod impls {
|
|||
macro_rules! ord_impl(
|
||||
($($t:ty)*) => ($(
|
||||
impl PartialOrd for $t {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
|
||||
match (self <= other, self >= other) {
|
||||
(false, false) => None,
|
||||
(false, true) => Some(Greater),
|
||||
(true, false) => Some(Less),
|
||||
(true, true) => Some(Equal),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
|
||||
#[inline]
|
||||
|
@ -242,13 +294,15 @@ mod impls {
|
|||
|
||||
impl PartialOrd for () {
|
||||
#[inline]
|
||||
fn lt(&self, _other: &()) -> bool { false }
|
||||
fn partial_cmp(&self, _: &()) -> Option<Ordering> {
|
||||
Some(Equal)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for bool {
|
||||
#[inline]
|
||||
fn lt(&self, other: &bool) -> bool {
|
||||
(*self as u8) < (*other as u8)
|
||||
fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
|
||||
(*self as u8).partial_cmp(&(*other as u8))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,6 +343,10 @@ mod impls {
|
|||
fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
impl<'a, T: PartialOrd> PartialOrd for &'a T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
|
||||
(**self).partial_cmp(*other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) }
|
||||
#[inline]
|
||||
|
@ -312,6 +370,10 @@ mod impls {
|
|||
fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
|
||||
}
|
||||
impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
|
||||
(**self).partial_cmp(*other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &&'a mut T) -> bool { **self < **other }
|
||||
#[inline]
|
||||
|
@ -327,66 +389,3 @@ mod impls {
|
|||
}
|
||||
impl<'a, T: Eq> Eq for &'a mut T {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::lexical_ordering;
|
||||
|
||||
#[test]
|
||||
fn test_int_totalord() {
|
||||
assert_eq!(5u.cmp(&10), Less);
|
||||
assert_eq!(10u.cmp(&5), Greater);
|
||||
assert_eq!(5u.cmp(&5), Equal);
|
||||
assert_eq!((-5u).cmp(&12), Less);
|
||||
assert_eq!(12u.cmp(-5), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_int_totalord() {
|
||||
assert_eq!((&mut 5u).cmp(&10), Less);
|
||||
assert_eq!((&mut 10u).cmp(&5), Greater);
|
||||
assert_eq!((&mut 5u).cmp(&5), Equal);
|
||||
assert_eq!((&mut -5u).cmp(&12), Less);
|
||||
assert_eq!((&mut 12u).cmp(-5), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ordering_order() {
|
||||
assert!(Less < Equal);
|
||||
assert_eq!(Greater.cmp(&Less), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lexical_ordering() {
|
||||
fn t(o1: Ordering, o2: Ordering, e: Ordering) {
|
||||
assert_eq!(lexical_ordering(o1, o2), e);
|
||||
}
|
||||
|
||||
let xs = [Less, Equal, Greater];
|
||||
for &o in xs.iter() {
|
||||
t(Less, o, Less);
|
||||
t(Equal, o, o);
|
||||
t(Greater, o, Greater);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_defined_eq() {
|
||||
// Our type.
|
||||
struct SketchyNum {
|
||||
num : int
|
||||
}
|
||||
|
||||
// Our implementation of `PartialEq` to support `==` and `!=`.
|
||||
impl PartialEq for SketchyNum {
|
||||
// Our custom eq allows numbers which are near each other to be equal! :D
|
||||
fn eq(&self, other: &SketchyNum) -> bool {
|
||||
(self.num - other.num).abs() < 5
|
||||
}
|
||||
}
|
||||
|
||||
// Now these binary operators will work when applied!
|
||||
assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
|
||||
assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,10 @@
|
|||
#![allow(dead_code, missing_doc)]
|
||||
|
||||
use fmt;
|
||||
#[cfg(not(test))] use intrinsics;
|
||||
use intrinsics;
|
||||
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="fail_"]
|
||||
#[cfg(not(test))]
|
||||
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
|
||||
format_args!(|args| -> () {
|
||||
begin_unwind(args, file, line);
|
||||
|
@ -46,7 +45,6 @@ fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
|
|||
|
||||
#[cold]
|
||||
#[lang="fail_bounds_check"]
|
||||
#[cfg(not(test))]
|
||||
fn fail_bounds_check(file: &'static str, line: uint,
|
||||
index: uint, len: uint) -> ! {
|
||||
format_args!(|args| -> () {
|
||||
|
|
|
@ -115,55 +115,3 @@ impl<'a,A> Drop for Finallyalizer<'a,A> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{try_finally, Finally};
|
||||
use realstd::task::failing;
|
||||
|
||||
#[test]
|
||||
fn test_success() {
|
||||
let mut i = 0i;
|
||||
try_finally(
|
||||
&mut i, (),
|
||||
|i, ()| {
|
||||
*i = 10;
|
||||
},
|
||||
|i| {
|
||||
assert!(!failing());
|
||||
assert_eq!(*i, 10);
|
||||
*i = 20;
|
||||
});
|
||||
assert_eq!(i, 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_fail() {
|
||||
let mut i = 0i;
|
||||
try_finally(
|
||||
&mut i, (),
|
||||
|i, ()| {
|
||||
*i = 10;
|
||||
fail!();
|
||||
},
|
||||
|i| {
|
||||
assert!(failing());
|
||||
assert_eq!(*i, 10);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retval() {
|
||||
let mut closure: || -> int = || 10;
|
||||
let i = closure.finally(|| { });
|
||||
assert_eq!(i, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compact() {
|
||||
fn do_some_fallible_work() {}
|
||||
fn but_always_run_this_function() { }
|
||||
let mut f = do_some_fallible_work;
|
||||
f.finally(but_always_run_this_function);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -314,11 +314,11 @@ impl<'a> Formatter<'a> {
|
|||
rt::CountImplied => { None }
|
||||
rt::CountIsParam(i) => {
|
||||
let v = self.args[i].value;
|
||||
unsafe { Some(*(v as *any::Void as *uint)) }
|
||||
unsafe { Some(*(v as *const _ as *const uint)) }
|
||||
}
|
||||
rt::CountIsNextParam => {
|
||||
let v = self.curarg.next().unwrap().value;
|
||||
unsafe { Some(*(v as *any::Void as *uint)) }
|
||||
unsafe { Some(*(v as *const _ as *const uint)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,31 +496,6 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn format(args: &Arguments) -> ::realstd::string::String {
|
||||
use str;
|
||||
use realstd::io::MemWriter;
|
||||
|
||||
fn mywrite<T: ::realstd::io::Writer>(t: &mut T, b: &[u8]) {
|
||||
use realstd::io::Writer;
|
||||
let _ = t.write(b);
|
||||
}
|
||||
|
||||
impl FormatWriter for MemWriter {
|
||||
fn write(&mut self, bytes: &[u8]) -> Result {
|
||||
mywrite(self, bytes);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let mut i = MemWriter::new();
|
||||
let _ = write(&mut i, args);
|
||||
|
||||
let mut result = ::realstd::string::String::new();
|
||||
result.push_str(str::from_utf8(i.get_ref()).unwrap());
|
||||
result
|
||||
}
|
||||
|
||||
/// When the compiler determines that the type of an argument *must* be a string
|
||||
/// (such as for select), then it invokes this method.
|
||||
#[doc(hidden)] #[inline]
|
||||
|
@ -543,6 +518,9 @@ impl<'a, T: Show> Show for &'a T {
|
|||
impl<'a, T: Show> Show for &'a mut T {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
|
||||
}
|
||||
impl<'a> Show for &'a Show {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
|
||||
}
|
||||
|
||||
impl Bool for bool {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
|
@ -565,7 +543,7 @@ impl Char for char {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Pointer for *T {
|
||||
impl<T> Pointer for *const T {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
f.flags |= 1 << (rt::FlagAlternate as uint);
|
||||
secret_lower_hex::<uint>(&(*self as uint), f)
|
||||
|
@ -573,17 +551,17 @@ impl<T> Pointer for *T {
|
|||
}
|
||||
impl<T> Pointer for *mut T {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
secret_pointer::<*T>(&(*self as *T), f)
|
||||
secret_pointer::<*const T>(&(*self as *const T), f)
|
||||
}
|
||||
}
|
||||
impl<'a, T> Pointer for &'a T {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
secret_pointer::<*T>(&(&**self as *T), f)
|
||||
secret_pointer::<*const T>(&(&**self as *const T), f)
|
||||
}
|
||||
}
|
||||
impl<'a, T> Pointer for &'a mut T {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
secret_pointer::<*T>(&(&**self as *T), f)
|
||||
secret_pointer::<*const T>(&(&**self as *const T), f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,7 +647,7 @@ delegate!(char to char)
|
|||
delegate!(f32 to float)
|
||||
delegate!(f64 to float)
|
||||
|
||||
impl<T> Show for *T {
|
||||
impl<T> Show for *const T {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
|
||||
}
|
||||
impl<T> Show for *mut T {
|
||||
|
@ -686,7 +664,7 @@ macro_rules! tuple (
|
|||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
try!(write!(f, "("));
|
||||
let ($(ref $name,)*) = *self;
|
||||
let mut n = 0;
|
||||
let mut n = 0i;
|
||||
$(
|
||||
if n > 0 {
|
||||
try!(write!(f, ", "));
|
||||
|
|
|
@ -188,283 +188,3 @@ integer!(i8, u8)
|
|||
integer!(i16, u16)
|
||||
integer!(i32, u32)
|
||||
integer!(i64, u64)
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use fmt::radix;
|
||||
use super::{Binary, Octal, Decimal, LowerHex, UpperHex};
|
||||
use super::{GenericRadix, Radix};
|
||||
use realstd::str::Str;
|
||||
|
||||
#[test]
|
||||
fn test_radix_base() {
|
||||
assert_eq!(Binary.base(), 2);
|
||||
assert_eq!(Octal.base(), 8);
|
||||
assert_eq!(Decimal.base(), 10);
|
||||
assert_eq!(LowerHex.base(), 16);
|
||||
assert_eq!(UpperHex.base(), 16);
|
||||
assert_eq!(Radix { base: 36 }.base(), 36);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_radix_prefix() {
|
||||
assert_eq!(Binary.prefix(), "0b");
|
||||
assert_eq!(Octal.prefix(), "0o");
|
||||
assert_eq!(Decimal.prefix(), "");
|
||||
assert_eq!(LowerHex.prefix(), "0x");
|
||||
assert_eq!(UpperHex.prefix(), "0x");
|
||||
assert_eq!(Radix { base: 36 }.prefix(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_radix_digit() {
|
||||
assert_eq!(Binary.digit(0), '0' as u8);
|
||||
assert_eq!(Binary.digit(2), '2' as u8);
|
||||
assert_eq!(Octal.digit(0), '0' as u8);
|
||||
assert_eq!(Octal.digit(7), '7' as u8);
|
||||
assert_eq!(Decimal.digit(0), '0' as u8);
|
||||
assert_eq!(Decimal.digit(9), '9' as u8);
|
||||
assert_eq!(LowerHex.digit(0), '0' as u8);
|
||||
assert_eq!(LowerHex.digit(10), 'a' as u8);
|
||||
assert_eq!(LowerHex.digit(15), 'f' as u8);
|
||||
assert_eq!(UpperHex.digit(0), '0' as u8);
|
||||
assert_eq!(UpperHex.digit(10), 'A' as u8);
|
||||
assert_eq!(UpperHex.digit(15), 'F' as u8);
|
||||
assert_eq!(Radix { base: 36 }.digit(0), '0' as u8);
|
||||
assert_eq!(Radix { base: 36 }.digit(15), 'f' as u8);
|
||||
assert_eq!(Radix { base: 36 }.digit(35), 'z' as u8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_hex_radix_digit_overflow() {
|
||||
let _ = LowerHex.digit(16);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int() {
|
||||
// Formatting integers should select the right implementation based off
|
||||
// the type of the argument. Also, hex/octal/binary should be defined
|
||||
// for integers, but they shouldn't emit the negative sign.
|
||||
assert!(format!("{}", 1i).as_slice() == "1");
|
||||
assert!(format!("{}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:d}", -1i).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i8).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i16).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i32).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i64).as_slice() == "-1");
|
||||
assert!(format!("{:t}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i64).as_slice() == "1");
|
||||
|
||||
assert!(format!("{}", 1u).as_slice() == "1");
|
||||
assert!(format!("{}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u64).as_slice() == "1");
|
||||
|
||||
// Test a larger number
|
||||
assert!(format!("{:t}", 55i).as_slice() == "110111");
|
||||
assert!(format!("{:o}", 55i).as_slice() == "67");
|
||||
assert!(format!("{:d}", 55i).as_slice() == "55");
|
||||
assert!(format!("{:x}", 55i).as_slice() == "37");
|
||||
assert!(format!("{:X}", 55i).as_slice() == "37");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_zero() {
|
||||
assert!(format!("{}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:d}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:t}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:o}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:x}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:X}", 0i).as_slice() == "0");
|
||||
|
||||
assert!(format!("{}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:u}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:t}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:o}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:x}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:X}", 0u).as_slice() == "0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_flags() {
|
||||
assert!(format!("{:3d}", 1i).as_slice() == " 1");
|
||||
assert!(format!("{:>3d}", 1i).as_slice() == " 1");
|
||||
assert!(format!("{:>+3d}", 1i).as_slice() == " +1");
|
||||
assert!(format!("{:<3d}", 1i).as_slice() == "1 ");
|
||||
assert!(format!("{:#d}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:#x}", 10i).as_slice() == "0xa");
|
||||
assert!(format!("{:#X}", 10i).as_slice() == "0xA");
|
||||
assert!(format!("{:#5x}", 10i).as_slice() == " 0xa");
|
||||
assert!(format!("{:#o}", 10i).as_slice() == "0o12");
|
||||
assert!(format!("{:08x}", 10i).as_slice() == "0000000a");
|
||||
assert!(format!("{:8x}", 10i).as_slice() == " a");
|
||||
assert!(format!("{:<8x}", 10i).as_slice() == "a ");
|
||||
assert!(format!("{:>8x}", 10i).as_slice() == " a");
|
||||
assert!(format!("{:#08x}", 10i).as_slice() == "0x00000a");
|
||||
assert!(format!("{:08d}", -10i).as_slice() == "-0000010");
|
||||
assert!(format!("{:x}", -1u8).as_slice() == "ff");
|
||||
assert!(format!("{:X}", -1u8).as_slice() == "FF");
|
||||
assert!(format!("{:t}", -1u8).as_slice() == "11111111");
|
||||
assert!(format!("{:o}", -1u8).as_slice() == "377");
|
||||
assert!(format!("{:#x}", -1u8).as_slice() == "0xff");
|
||||
assert!(format!("{:#X}", -1u8).as_slice() == "0xFF");
|
||||
assert!(format!("{:#t}", -1u8).as_slice() == "0b11111111");
|
||||
assert!(format!("{:#o}", -1u8).as_slice() == "0o377");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_sign_padding() {
|
||||
assert!(format!("{:+5d}", 1i).as_slice() == " +1");
|
||||
assert!(format!("{:+5d}", -1i).as_slice() == " -1");
|
||||
assert!(format!("{:05d}", 1i).as_slice() == "00001");
|
||||
assert!(format!("{:05d}", -1i).as_slice() == "-0001");
|
||||
assert!(format!("{:+05d}", 1i).as_slice() == "+0001");
|
||||
assert!(format!("{:+05d}", -1i).as_slice() == "-0001");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_twos_complement() {
|
||||
use {i8, i16, i32, i64};
|
||||
assert!(format!("{}", i8::MIN).as_slice() == "-128");
|
||||
assert!(format!("{}", i16::MIN).as_slice() == "-32768");
|
||||
assert!(format!("{}", i32::MIN).as_slice() == "-2147483648");
|
||||
assert!(format!("{}", i64::MIN).as_slice() == "-9223372036854775808");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_radix() {
|
||||
assert!(format!("{:04}", radix(3i, 2)).as_slice() == "0011");
|
||||
assert!(format!("{}", radix(55i, 36)).as_slice() == "1j");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_radix_base_too_large() {
|
||||
let _ = radix(55, 37);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod bench {
|
||||
extern crate test;
|
||||
|
||||
mod uint {
|
||||
use super::test::Bencher;
|
||||
use fmt::radix;
|
||||
use realstd::rand::{weak_rng, Rng};
|
||||
|
||||
#[bench]
|
||||
fn format_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:t}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:o}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:u}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:x}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{}", radix(rng.gen::<uint>(), 36)); })
|
||||
}
|
||||
}
|
||||
|
||||
mod int {
|
||||
use super::test::Bencher;
|
||||
use fmt::radix;
|
||||
use realstd::rand::{weak_rng, Rng};
|
||||
|
||||
#[bench]
|
||||
fn format_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:t}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:o}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:d}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:x}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{}", radix(rng.gen::<int>(), 36)); })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,14 +44,9 @@ A quick refresher on memory ordering:
|
|||
#![experimental]
|
||||
#![allow(missing_doc)]
|
||||
|
||||
// This is needed to prevent duplicate lang item definitions.
|
||||
#[cfg(test)]
|
||||
pub use realcore::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId};
|
||||
|
||||
pub type GlueFn = extern "Rust" fn(*i8);
|
||||
pub type GlueFn = extern "Rust" fn(*const i8);
|
||||
|
||||
#[lang="ty_desc"]
|
||||
#[cfg(not(test))]
|
||||
pub struct TyDesc {
|
||||
// sizeof(T)
|
||||
pub size: uint,
|
||||
|
@ -70,13 +65,11 @@ pub struct TyDesc {
|
|||
}
|
||||
|
||||
#[lang="opaque"]
|
||||
#[cfg(not(test))]
|
||||
pub enum Opaque { }
|
||||
|
||||
pub type Disr = u64;
|
||||
|
||||
#[lang="ty_visitor"]
|
||||
#[cfg(not(test))]
|
||||
pub trait TyVisitor {
|
||||
fn visit_bot(&mut self) -> bool;
|
||||
fn visit_nil(&mut self) -> bool;
|
||||
|
@ -102,55 +95,58 @@ pub trait TyVisitor {
|
|||
fn visit_estr_slice(&mut self) -> bool;
|
||||
fn visit_estr_fixed(&mut self, n: uint, sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_ptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_uniq(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_ptr(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
|
||||
mtbl: uint, inner: *TyDesc) -> bool;
|
||||
mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
|
||||
fn visit_enter_rec(&mut self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_rec_field(&mut self, i: uint, name: &str,
|
||||
mtbl: uint, inner: *TyDesc) -> bool;
|
||||
mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_leave_rec(&mut self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
|
||||
mtbl: uint, inner: *TyDesc) -> bool;
|
||||
mtbl: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_leave_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_tup(&mut self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *const TyDesc) -> bool;
|
||||
fn visit_leave_tup(&mut self, n_fields: uint,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_enum(&mut self, n_variants: uint,
|
||||
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
|
||||
get_disr: unsafe extern fn(ptr: *const Opaque) -> Disr,
|
||||
sz: uint, align: uint) -> bool;
|
||||
fn visit_enter_enum_variant(&mut self, variant: uint,
|
||||
disr_val: Disr,
|
||||
n_fields: uint,
|
||||
name: &str) -> bool;
|
||||
fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_enum_variant_field(&mut self, i: uint, offset: uint,
|
||||
inner: *const TyDesc) -> bool;
|
||||
fn visit_leave_enum_variant(&mut self, variant: uint,
|
||||
disr_val: Disr,
|
||||
n_fields: uint,
|
||||
name: &str) -> bool;
|
||||
fn visit_leave_enum(&mut self, n_variants: uint,
|
||||
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
|
||||
get_disr: unsafe extern fn(ptr: *const Opaque) -> Disr,
|
||||
sz: uint, align: uint) -> bool;
|
||||
|
||||
fn visit_enter_fn(&mut self, purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool;
|
||||
fn visit_fn_input(&mut self, i: uint, mode: uint, inner: *TyDesc) -> bool;
|
||||
fn visit_fn_output(&mut self, retstyle: uint, variadic: bool, inner: *TyDesc) -> bool;
|
||||
fn visit_fn_input(&mut self, i: uint, mode: uint,
|
||||
inner: *const TyDesc) -> bool;
|
||||
fn visit_fn_output(&mut self, retstyle: uint, variadic: bool,
|
||||
inner: *const TyDesc) -> bool;
|
||||
fn visit_leave_fn(&mut self, purity: uint, proto: uint,
|
||||
n_inputs: uint, retstyle: uint) -> bool;
|
||||
|
||||
|
@ -170,9 +166,9 @@ extern "rust-intrinsic" {
|
|||
pub fn atomic_cxchg_acqrel<T>(dst: *mut T, old: T, src: T) -> T;
|
||||
pub fn atomic_cxchg_relaxed<T>(dst: *mut T, old: T, src: T) -> T;
|
||||
|
||||
pub fn atomic_load<T>(src: *T) -> T;
|
||||
pub fn atomic_load_acq<T>(src: *T) -> T;
|
||||
pub fn atomic_load_relaxed<T>(src: *T) -> T;
|
||||
pub fn atomic_load<T>(src: *const T) -> T;
|
||||
pub fn atomic_load_acq<T>(src: *const T) -> T;
|
||||
pub fn atomic_load_relaxed<T>(src: *const T) -> T;
|
||||
|
||||
pub fn atomic_store<T>(dst: *mut T, val: T);
|
||||
pub fn atomic_store_rel<T>(dst: *mut T, val: T);
|
||||
|
@ -276,7 +272,7 @@ extern "rust-intrinsic" {
|
|||
pub fn pref_align_of<T>() -> uint;
|
||||
|
||||
/// Get a static pointer to a type descriptor.
|
||||
pub fn get_tydesc<T>() -> *TyDesc;
|
||||
pub fn get_tydesc<T>() -> *const TyDesc;
|
||||
|
||||
/// Gets an identifier which is globally unique to the specified type. This
|
||||
/// function will return the same value for a type regardless of whichever
|
||||
|
@ -320,7 +316,7 @@ extern "rust-intrinsic" {
|
|||
/// Returns `true` if a type is managed (will be allocated on the local heap)
|
||||
pub fn owns_managed<T>() -> bool;
|
||||
|
||||
pub fn visit_tydesc(td: *TyDesc, tv: &mut TyVisitor);
|
||||
pub fn visit_tydesc(td: *const TyDesc, tv: &mut TyVisitor);
|
||||
|
||||
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
|
||||
/// the object, or one-byte-past-the-end. An arithmetic overflow is also
|
||||
|
@ -328,17 +324,17 @@ extern "rust-intrinsic" {
|
|||
///
|
||||
/// This is implemented as an intrinsic to avoid converting to and from an
|
||||
/// integer, since the conversion would throw away aliasing information.
|
||||
pub fn offset<T>(dst: *T, offset: int) -> *T;
|
||||
pub fn offset<T>(dst: *const T, offset: int) -> *const T;
|
||||
|
||||
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
|
||||
/// a size of `count` * `size_of::<T>()` and an alignment of
|
||||
/// `min_align_of::<T>()`
|
||||
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *T, count: uint);
|
||||
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
|
||||
|
||||
/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
|
||||
/// a size of `count` * `size_of::<T>()` and an alignment of
|
||||
/// `min_align_of::<T>()`
|
||||
pub fn copy_memory<T>(dst: *mut T, src: *T, count: uint);
|
||||
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);
|
||||
|
||||
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
|
||||
/// size of `count` * `size_of::<T>()` and an alignment of
|
||||
|
@ -350,13 +346,14 @@ extern "rust-intrinsic" {
|
|||
/// `min_align_of::<T>()`
|
||||
///
|
||||
/// The volatile parameter parameter is set to `true`, so it will not be optimized out.
|
||||
pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *T, count: uint);
|
||||
pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
|
||||
count: uint);
|
||||
/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
|
||||
/// a size of `count` * `size_of::<T>()` and an alignment of
|
||||
/// `min_align_of::<T>()`
|
||||
///
|
||||
/// The volatile parameter parameter is set to `true`, so it will not be optimized out.
|
||||
pub fn volatile_copy_memory<T>(dst: *mut T, src: *T, count: uint);
|
||||
pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: uint);
|
||||
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
|
||||
/// size of `count` * `size_of::<T>()` and an alignment of
|
||||
/// `min_align_of::<T>()`.
|
||||
|
@ -365,7 +362,7 @@ extern "rust-intrinsic" {
|
|||
pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: uint);
|
||||
|
||||
/// Perform a volatile load from the `src` pointer.
|
||||
pub fn volatile_load<T>(src: *T) -> T;
|
||||
pub fn volatile_load<T>(src: *const T) -> T;
|
||||
/// Perform a volatile store to the `dst` pointer.
|
||||
pub fn volatile_store<T>(dst: *mut T, val: T);
|
||||
|
||||
|
@ -560,12 +557,10 @@ extern "rust-intrinsic" {
|
|||
#[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and
|
||||
// middle/lang_items.rs
|
||||
#[deriving(PartialEq, Eq, Show)]
|
||||
#[cfg(not(test))]
|
||||
pub struct TypeId {
|
||||
t: u64,
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl TypeId {
|
||||
/// Returns the `TypeId` of the type this generic function has been instantiated with
|
||||
pub fn of<T: 'static>() -> TypeId {
|
||||
|
|
|
@ -135,7 +135,8 @@ pub trait Iterator<A> {
|
|||
/// let a = [0i];
|
||||
/// let b = [1i];
|
||||
/// let mut it = a.iter().zip(b.iter());
|
||||
/// assert_eq!(it.next().unwrap(), (&0, &1));
|
||||
/// let (x0, x1) = (0i, 1i);
|
||||
/// assert_eq!(it.next().unwrap(), (&x0, &x1));
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -202,8 +203,9 @@ pub trait Iterator<A> {
|
|||
/// ```rust
|
||||
/// let a = [100i, 200];
|
||||
/// let mut it = a.iter().enumerate();
|
||||
/// assert_eq!(it.next().unwrap(), (0, &100));
|
||||
/// assert_eq!(it.next().unwrap(), (1, &200));
|
||||
/// let (x100, x200) = (100i, 200i);
|
||||
/// assert_eq!(it.next().unwrap(), (0, &x100));
|
||||
/// assert_eq!(it.next().unwrap(), (1, &x200));
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
@ -220,11 +222,11 @@ pub trait Iterator<A> {
|
|||
/// ```rust
|
||||
/// let xs = [100i, 200, 300];
|
||||
/// let mut it = xs.iter().map(|x| *x).peekable();
|
||||
/// assert_eq!(it.peek().unwrap(), &100);
|
||||
/// assert_eq!(*it.peek().unwrap(), 100);
|
||||
/// assert_eq!(it.next().unwrap(), 100);
|
||||
/// assert_eq!(it.next().unwrap(), 200);
|
||||
/// assert_eq!(it.peek().unwrap(), &300);
|
||||
/// assert_eq!(it.peek().unwrap(), &300);
|
||||
/// assert_eq!(*it.peek().unwrap(), 300);
|
||||
/// assert_eq!(*it.peek().unwrap(), 300);
|
||||
/// assert_eq!(it.next().unwrap(), 300);
|
||||
/// assert!(it.peek().is_none());
|
||||
/// assert!(it.next().is_none());
|
||||
|
@ -2181,7 +2183,7 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
|
|||
pub mod order {
|
||||
use cmp;
|
||||
use cmp::{Eq, Ord, PartialOrd, PartialEq};
|
||||
use option::{Some, None};
|
||||
use option::{Option, Some, None};
|
||||
use super::Iterator;
|
||||
|
||||
/// Compare `a` and `b` for equality using `Eq`
|
||||
|
@ -2210,6 +2212,22 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
|
||||
/// Order `a` and `b` lexicographically using `PartialOrd`
|
||||
pub fn partial_cmp<A: PartialOrd, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S)
|
||||
-> Option<cmp::Ordering> {
|
||||
loop {
|
||||
match (a.next(), b.next()) {
|
||||
(None, None) => return Some(cmp::Equal),
|
||||
(None, _ ) => return Some(cmp::Less),
|
||||
(_ , None) => return Some(cmp::Greater),
|
||||
(Some(x), Some(y)) => match x.partial_cmp(&y) {
|
||||
Some(cmp::Equal) => (),
|
||||
non_eq => return non_eq,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Compare `a` and `b` for equality (Using partial equality, `PartialEq`)
|
||||
pub fn eq<A: PartialEq, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S) -> bool {
|
||||
loop {
|
||||
|
@ -2279,868 +2297,5 @@ pub mod order {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lt() {
|
||||
use slice::ImmutableVector;
|
||||
|
||||
let empty: [int, ..0] = [];
|
||||
let xs = [1i,2,3];
|
||||
let ys = [1i,2,0];
|
||||
|
||||
assert!(!lt(xs.iter(), ys.iter()));
|
||||
assert!(!le(xs.iter(), ys.iter()));
|
||||
assert!( gt(xs.iter(), ys.iter()));
|
||||
assert!( ge(xs.iter(), ys.iter()));
|
||||
|
||||
assert!( lt(ys.iter(), xs.iter()));
|
||||
assert!( le(ys.iter(), xs.iter()));
|
||||
assert!(!gt(ys.iter(), xs.iter()));
|
||||
assert!(!ge(ys.iter(), xs.iter()));
|
||||
|
||||
assert!( lt(empty.iter(), xs.iter()));
|
||||
assert!( le(empty.iter(), xs.iter()));
|
||||
assert!(!gt(empty.iter(), xs.iter()));
|
||||
assert!(!ge(empty.iter(), xs.iter()));
|
||||
|
||||
// Sequence with NaN
|
||||
let u = [1.0f64, 2.0];
|
||||
let v = [0.0f64/0.0, 3.0];
|
||||
|
||||
assert!(!lt(u.iter(), v.iter()));
|
||||
assert!(!le(u.iter(), v.iter()));
|
||||
assert!(!gt(u.iter(), v.iter()));
|
||||
assert!(!ge(u.iter(), v.iter()));
|
||||
|
||||
let a = [0.0f64/0.0];
|
||||
let b = [1.0f64];
|
||||
let c = [2.0f64];
|
||||
|
||||
assert!(lt(a.iter(), b.iter()) == (a[0] < b[0]));
|
||||
assert!(le(a.iter(), b.iter()) == (a[0] <= b[0]));
|
||||
assert!(gt(a.iter(), b.iter()) == (a[0] > b[0]));
|
||||
assert!(ge(a.iter(), b.iter()) == (a[0] >= b[0]));
|
||||
|
||||
assert!(lt(c.iter(), b.iter()) == (c[0] < b[0]));
|
||||
assert!(le(c.iter(), b.iter()) == (c[0] <= b[0]));
|
||||
assert!(gt(c.iter(), b.iter()) == (c[0] > b[0]));
|
||||
assert!(ge(c.iter(), b.iter()) == (c[0] >= b[0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_iter() {
|
||||
use slice::ImmutableVector;
|
||||
use iter::DoubleEndedIterator;
|
||||
let xs = [1i,2,3,4];
|
||||
let ys = [4i,3,2,1];
|
||||
assert!(eq(xs.iter(), ys.iter().rev()));
|
||||
assert!(lt(xs.iter(), xs.iter().skip(2)));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
use iter::*;
|
||||
use num;
|
||||
use realstd::vec::Vec;
|
||||
use realstd::slice::Vector;
|
||||
use realstd::gc::GC;
|
||||
|
||||
use cmp;
|
||||
use realstd::owned::Box;
|
||||
use uint;
|
||||
|
||||
impl<T> FromIterator<T> for Vec<T> {
|
||||
fn from_iter<I: Iterator<T>>(mut iterator: I) -> Vec<T> {
|
||||
let mut v = Vec::new();
|
||||
for e in iterator {
|
||||
v.push(e);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator<&'a T> for ::realcore::slice::Items<'a, T> {
|
||||
fn next(&mut self) -> Option<&'a T> {
|
||||
use RealSome = realcore::option::Some;
|
||||
use RealNone = realcore::option::None;
|
||||
fn mynext<T, I: ::realcore::iter::Iterator<T>>(i: &mut I)
|
||||
-> ::realcore::option::Option<T>
|
||||
{
|
||||
use realcore::iter::Iterator;
|
||||
i.next()
|
||||
}
|
||||
match mynext(self) {
|
||||
RealSome(t) => Some(t),
|
||||
RealNone => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_counter_from_iter() {
|
||||
let it = count(0i, 5).take(10);
|
||||
let xs: Vec<int> = FromIterator::from_iter(it);
|
||||
assert!(xs == vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_chain() {
|
||||
let xs = [0u, 1, 2, 3, 4, 5];
|
||||
let ys = [30u, 40, 50, 60];
|
||||
let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
|
||||
let mut it = xs.iter().chain(ys.iter());
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, expected[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
||||
let ys = count(30u, 10).take(4);
|
||||
let mut it = xs.iter().map(|&x| x).chain(ys);
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, expected[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_map() {
|
||||
let mut it = count(0u, 1u).take(10)
|
||||
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
|
||||
assert!(it.collect::<Vec<uint>>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_enumerate() {
|
||||
let xs = [0u, 1, 2, 3, 4, 5];
|
||||
let mut it = xs.iter().enumerate();
|
||||
for (i, &x) in it {
|
||||
assert_eq!(i, x);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_peekable() {
|
||||
let xs = vec![0u, 1, 2, 3, 4, 5];
|
||||
let mut it = xs.iter().map(|&x|x).peekable();
|
||||
assert_eq!(it.peek().unwrap(), &0);
|
||||
assert_eq!(it.next().unwrap(), 0);
|
||||
assert_eq!(it.next().unwrap(), 1);
|
||||
assert_eq!(it.next().unwrap(), 2);
|
||||
assert_eq!(it.peek().unwrap(), &3);
|
||||
assert_eq!(it.peek().unwrap(), &3);
|
||||
assert_eq!(it.next().unwrap(), 3);
|
||||
assert_eq!(it.next().unwrap(), 4);
|
||||
assert_eq!(it.peek().unwrap(), &5);
|
||||
assert_eq!(it.next().unwrap(), 5);
|
||||
assert!(it.peek().is_none());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_take_while() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
|
||||
let ys = [0u, 1, 2, 3, 5, 13];
|
||||
let mut it = xs.iter().take_while(|&x| *x < 15u);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_skip_while() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
|
||||
let ys = [15, 16, 17, 19];
|
||||
let mut it = xs.iter().skip_while(|&x| *x < 15u);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_skip() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
|
||||
let ys = [13, 15, 16, 17, 19, 20, 30];
|
||||
let mut it = xs.iter().skip(5);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_take() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
|
||||
let ys = [0u, 1, 2, 3, 5];
|
||||
let mut it = xs.iter().take(5);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_scan() {
|
||||
// test the type inference
|
||||
fn add(old: &mut int, new: &uint) -> Option<f64> {
|
||||
*old += *new as int;
|
||||
Some(*old as f64)
|
||||
}
|
||||
let xs = [0u, 1, 2, 3, 4];
|
||||
let ys = [0f64, 1.0, 3.0, 6.0, 10.0];
|
||||
|
||||
let mut it = xs.iter().scan(0, add);
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_flat_map() {
|
||||
let xs = [0u, 3, 6];
|
||||
let ys = [0u, 1, 2, 3, 4, 5, 6, 7, 8];
|
||||
let mut it = xs.iter().flat_map(|&x| count(x, 1).take(3));
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inspect() {
|
||||
let xs = [1u, 2, 3, 4];
|
||||
let mut n = 0;
|
||||
|
||||
let ys = xs.iter()
|
||||
.map(|&x| x)
|
||||
.inspect(|_| n += 1)
|
||||
.collect::<Vec<uint>>();
|
||||
|
||||
assert_eq!(n, xs.len());
|
||||
assert_eq!(xs.as_slice(), ys.as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unfoldr() {
|
||||
fn count(st: &mut uint) -> Option<uint> {
|
||||
if *st < 10 {
|
||||
let ret = Some(*st);
|
||||
*st += 1;
|
||||
ret
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mut it = Unfold::new(0, count);
|
||||
let mut i = 0;
|
||||
for counted in it {
|
||||
assert_eq!(counted, i);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cycle() {
|
||||
let cycle_len = 3;
|
||||
let it = count(0u, 1).take(cycle_len).cycle();
|
||||
assert_eq!(it.size_hint(), (uint::MAX, None));
|
||||
for (i, x) in it.take(100).enumerate() {
|
||||
assert_eq!(i % cycle_len, x);
|
||||
}
|
||||
|
||||
let mut it = count(0u, 1).take(0).cycle();
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_nth() {
|
||||
let v = &[0i, 1, 2, 3, 4];
|
||||
for i in range(0u, v.len()) {
|
||||
assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_last() {
|
||||
let v = &[0i, 1, 2, 3, 4];
|
||||
assert_eq!(v.iter().last().unwrap(), &4);
|
||||
assert_eq!(v.slice(0, 1).iter().last().unwrap(), &0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_len() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().count(), 4);
|
||||
assert_eq!(v.slice(0, 10).iter().count(), 10);
|
||||
assert_eq!(v.slice(0, 0).iter().count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_sum() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).sum(), 6);
|
||||
assert_eq!(v.iter().map(|&x| x).sum(), 55);
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).sum(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_product() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).product(), 0);
|
||||
assert_eq!(v.slice(1, 5).iter().map(|&x| x).product(), 24);
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).product(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_max() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).max(), Some(3));
|
||||
assert_eq!(v.iter().map(|&x| x).max(), Some(10));
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).max(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_min() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).min(), Some(0));
|
||||
assert_eq!(v.iter().map(|&x| x).min(), Some(0));
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).min(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_size_hint() {
|
||||
let c = count(0i, 1);
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
let v2 = &[10i, 11, 12];
|
||||
let vi = v.iter();
|
||||
|
||||
assert_eq!(c.size_hint(), (uint::MAX, None));
|
||||
assert_eq!(vi.size_hint(), (10, Some(10)));
|
||||
|
||||
assert_eq!(c.take(5).size_hint(), (5, Some(5)));
|
||||
assert_eq!(c.skip(5).size_hint().val1(), None);
|
||||
assert_eq!(c.take_while(|_| false).size_hint(), (0, None));
|
||||
assert_eq!(c.skip_while(|_| false).size_hint(), (0, None));
|
||||
assert_eq!(c.enumerate().size_hint(), (uint::MAX, None));
|
||||
assert_eq!(c.chain(vi.map(|&i| i)).size_hint(), (uint::MAX, None));
|
||||
assert_eq!(c.zip(vi).size_hint(), (10, Some(10)));
|
||||
assert_eq!(c.scan(0, |_,_| Some(0)).size_hint(), (0, None));
|
||||
assert_eq!(c.filter(|_| false).size_hint(), (0, None));
|
||||
assert_eq!(c.map(|_| 0).size_hint(), (uint::MAX, None));
|
||||
assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
|
||||
|
||||
assert_eq!(vi.take(5).size_hint(), (5, Some(5)));
|
||||
assert_eq!(vi.take(12).size_hint(), (10, Some(10)));
|
||||
assert_eq!(vi.skip(3).size_hint(), (7, Some(7)));
|
||||
assert_eq!(vi.skip(12).size_hint(), (0, Some(0)));
|
||||
assert_eq!(vi.take_while(|_| false).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.skip_while(|_| false).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.enumerate().size_hint(), (10, Some(10)));
|
||||
assert_eq!(vi.chain(v2.iter()).size_hint(), (13, Some(13)));
|
||||
assert_eq!(vi.zip(v2.iter()).size_hint(), (3, Some(3)));
|
||||
assert_eq!(vi.scan(0, |_,_| Some(0)).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.filter(|_| false).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.map(|i| i+1).size_hint(), (10, Some(10)));
|
||||
assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let a = vec![1i, 2, 3, 4, 5];
|
||||
let b: Vec<int> = a.iter().map(|&x| x).collect();
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
let v: Box<&[int]> = box &[1i, 2, 3, 4, 5];
|
||||
assert!(v.iter().all(|&x| x < 10));
|
||||
assert!(!v.iter().all(|&x| x % 2 == 0));
|
||||
assert!(!v.iter().all(|&x| x > 100));
|
||||
assert!(v.slice(0, 0).iter().all(|_| fail!()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_any() {
|
||||
let v: Box<&[int]> = box &[1i, 2, 3, 4, 5];
|
||||
assert!(v.iter().any(|&x| x < 10));
|
||||
assert!(v.iter().any(|&x| x % 2 == 0));
|
||||
assert!(!v.iter().any(|&x| x > 100));
|
||||
assert!(!v.slice(0, 0).iter().any(|_| fail!()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find() {
|
||||
let v: &[int] = &[1i, 3, 9, 27, 103, 14, 11];
|
||||
assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14);
|
||||
assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3);
|
||||
assert!(v.iter().find(|x| *x % 12 == 0).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position() {
|
||||
let v = &[1i, 3, 9, 27, 103, 14, 11];
|
||||
assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
|
||||
assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1);
|
||||
assert!(v.iter().position(|x| *x % 12 == 0).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count() {
|
||||
let xs = &[1i, 2, 2, 1, 5, 9, 0, 2];
|
||||
assert_eq!(xs.iter().filter(|x| **x == 2).count(), 3);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 5).count(), 1);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 95).count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_by() {
|
||||
let xs: &[int] = &[-3i, 0, 1, 5, -10];
|
||||
assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_by() {
|
||||
let xs: &[int] = &[-3i, 0, 1, 5, -10];
|
||||
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_by_ref() {
|
||||
let mut xs = range(0i, 10);
|
||||
// sum the first five values
|
||||
let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
|
||||
assert_eq!(partial_sum, 10);
|
||||
assert_eq!(xs.next(), Some(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev() {
|
||||
let xs = [2i, 4, 6, 8, 10, 12, 14, 16];
|
||||
let mut it = xs.iter();
|
||||
it.next();
|
||||
it.next();
|
||||
assert!(it.rev().map(|&x| x).collect::<Vec<int>>() ==
|
||||
vec![16, 14, 12, 10, 8, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_map() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().map(|&x| x * -1);
|
||||
assert_eq!(it.next(), Some(-1));
|
||||
assert_eq!(it.next(), Some(-2));
|
||||
assert_eq!(it.next_back(), Some(-6));
|
||||
assert_eq!(it.next_back(), Some(-5));
|
||||
assert_eq!(it.next(), Some(-3));
|
||||
assert_eq!(it.next_back(), Some(-4));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_enumerate() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().map(|&x| x).enumerate();
|
||||
assert_eq!(it.next(), Some((0, 1)));
|
||||
assert_eq!(it.next(), Some((1, 2)));
|
||||
assert_eq!(it.next_back(), Some((5, 6)));
|
||||
assert_eq!(it.next_back(), Some((4, 5)));
|
||||
assert_eq!(it.next_back(), Some((3, 4)));
|
||||
assert_eq!(it.next_back(), Some((2, 3)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_zip() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let ys = [1i, 2, 3, 7];
|
||||
let a = xs.iter().map(|&x| x);
|
||||
let b = ys.iter().map(|&x| x);
|
||||
let mut it = a.zip(b);
|
||||
assert_eq!(it.next(), Some((1, 1)));
|
||||
assert_eq!(it.next(), Some((2, 2)));
|
||||
assert_eq!(it.next_back(), Some((4, 7)));
|
||||
assert_eq!(it.next_back(), Some((3, 3)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter(|&x| *x & 1 == 0);
|
||||
assert_eq!(it.next_back().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &4);
|
||||
assert_eq!(it.next().unwrap(), &2);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter_map() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
|
||||
assert_eq!(it.next_back().unwrap(), 12);
|
||||
assert_eq!(it.next_back().unwrap(), 8);
|
||||
assert_eq!(it.next().unwrap(), 4);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_chain() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let ys = [7i, 9, 11];
|
||||
let mut it = xs.iter().chain(ys.iter()).rev();
|
||||
assert_eq!(it.next().unwrap(), &11)
|
||||
assert_eq!(it.next().unwrap(), &9)
|
||||
assert_eq!(it.next_back().unwrap(), &1)
|
||||
assert_eq!(it.next_back().unwrap(), &2)
|
||||
assert_eq!(it.next_back().unwrap(), &3)
|
||||
assert_eq!(it.next_back().unwrap(), &4)
|
||||
assert_eq!(it.next_back().unwrap(), &5)
|
||||
assert_eq!(it.next_back().unwrap(), &7)
|
||||
assert_eq!(it.next_back(), None)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rposition() {
|
||||
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
||||
fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
|
||||
let v = [(0i, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
||||
|
||||
assert_eq!(v.iter().rposition(f), Some(3u));
|
||||
assert!(v.iter().rposition(g).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_rposition_fail() {
|
||||
let v = [(box 0i, box(GC) 0i), (box 0i, box(GC) 0i),
|
||||
(box 0i, box(GC) 0i), (box 0i, box(GC) 0i)];
|
||||
let mut i = 0i;
|
||||
v.iter().rposition(|_elt| {
|
||||
if i == 2 {
|
||||
fail!()
|
||||
}
|
||||
i += 1;
|
||||
false
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
fn check_randacc_iter<A: PartialEq, T: Clone + RandomAccessIterator<A>>(a: T, len: uint)
|
||||
{
|
||||
let mut b = a.clone();
|
||||
assert_eq!(len, b.indexable());
|
||||
let mut n = 0u;
|
||||
for (i, elt) in a.enumerate() {
|
||||
assert!(Some(elt) == b.idx(i));
|
||||
n += 1;
|
||||
}
|
||||
assert_eq!(n, len);
|
||||
assert!(None == b.idx(n));
|
||||
// call recursively to check after picking off an element
|
||||
if len > 0 {
|
||||
b.next();
|
||||
check_randacc_iter(b, len-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_flat_map() {
|
||||
let u = [0u,1];
|
||||
let v = [5u,6,7,8];
|
||||
let mut it = u.iter().flat_map(|x| v.slice(*x, v.len()).iter());
|
||||
assert_eq!(it.next_back().unwrap(), &8);
|
||||
assert_eq!(it.next().unwrap(), &5);
|
||||
assert_eq!(it.next_back().unwrap(), &7);
|
||||
assert_eq!(it.next_back().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &8);
|
||||
assert_eq!(it.next().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &7);
|
||||
assert_eq!(it.next_back(), None);
|
||||
assert_eq!(it.next(), None);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_chain() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let ys = [7i, 9, 11];
|
||||
let mut it = xs.iter().chain(ys.iter());
|
||||
assert_eq!(it.idx(0).unwrap(), &1);
|
||||
assert_eq!(it.idx(5).unwrap(), &7);
|
||||
assert_eq!(it.idx(7).unwrap(), &11);
|
||||
assert!(it.idx(8).is_none());
|
||||
|
||||
it.next();
|
||||
it.next();
|
||||
it.next_back();
|
||||
|
||||
assert_eq!(it.idx(0).unwrap(), &3);
|
||||
assert_eq!(it.idx(4).unwrap(), &9);
|
||||
assert!(it.idx(6).is_none());
|
||||
|
||||
check_randacc_iter(it, xs.len() + ys.len() - 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_enumerate() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
check_randacc_iter(xs.iter().enumerate(), xs.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_rev() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
check_randacc_iter(xs.iter().rev(), xs.len());
|
||||
let mut it = xs.iter().rev();
|
||||
it.next();
|
||||
it.next_back();
|
||||
it.next();
|
||||
check_randacc_iter(it, xs.len() - 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_zip() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let ys = [7i, 9, 11];
|
||||
check_randacc_iter(xs.iter().zip(ys.iter()), cmp::min(xs.len(), ys.len()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_take() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let empty: &[int] = [];
|
||||
check_randacc_iter(xs.iter().take(3), 3);
|
||||
check_randacc_iter(xs.iter().take(20), xs.len());
|
||||
check_randacc_iter(xs.iter().take(0), 0);
|
||||
check_randacc_iter(empty.iter().take(2), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_skip() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let empty: &[int] = [];
|
||||
check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
|
||||
check_randacc_iter(empty.iter().skip(2), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_inspect() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
|
||||
// test .map and .inspect that don't implement Clone
|
||||
let mut it = xs.iter().inspect(|_| {});
|
||||
assert_eq!(xs.len(), it.indexable());
|
||||
for (i, elt) in xs.iter().enumerate() {
|
||||
assert_eq!(Some(elt), it.idx(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_map() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
|
||||
let mut it = xs.iter().map(|x| *x);
|
||||
assert_eq!(xs.len(), it.indexable());
|
||||
for (i, elt) in xs.iter().enumerate() {
|
||||
assert_eq!(Some(*elt), it.idx(i));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_cycle() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let empty: &[int] = [];
|
||||
check_randacc_iter(xs.iter().cycle().take(27), 27);
|
||||
check_randacc_iter(empty.iter().cycle(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_range() {
|
||||
assert!(range(11i, 14).rev().collect::<Vec<int>>() == vec![13i, 12, 11]);
|
||||
for _ in range(10i, 0).rev() {
|
||||
fail!("unreachable");
|
||||
}
|
||||
|
||||
assert!(range(11u, 14).rev().collect::<Vec<uint>>() == vec![13u, 12, 11]);
|
||||
for _ in range(10u, 0).rev() {
|
||||
fail!("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range() {
|
||||
/// A mock type to check Range when ToPrimitive returns None
|
||||
struct Foo;
|
||||
|
||||
impl ToPrimitive for Foo {
|
||||
fn to_i64(&self) -> Option<i64> { None }
|
||||
fn to_u64(&self) -> Option<u64> { None }
|
||||
}
|
||||
|
||||
impl Add<Foo, Foo> for Foo {
|
||||
fn add(&self, _: &Foo) -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Foo {
|
||||
fn eq(&self, _: &Foo) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Foo {
|
||||
fn lt(&self, _: &Foo) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Foo {
|
||||
fn clone(&self) -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Foo, Foo> for Foo {
|
||||
fn mul(&self, _: &Foo) -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl num::One for Foo {
|
||||
fn one() -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
assert!(range(0i, 5).collect::<Vec<int>>() == vec![0i, 1, 2, 3, 4]);
|
||||
assert!(range(-10i, -1).collect::<Vec<int>>() ==
|
||||
vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
|
||||
assert!(range(0i, 5).rev().collect::<Vec<int>>() == vec![4, 3, 2, 1, 0]);
|
||||
assert_eq!(range(200i, -5).count(), 0);
|
||||
assert_eq!(range(200i, -5).rev().count(), 0);
|
||||
assert_eq!(range(200i, 200).count(), 0);
|
||||
assert_eq!(range(200i, 200).rev().count(), 0);
|
||||
|
||||
assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
|
||||
// this test is only meaningful when sizeof uint < sizeof u64
|
||||
assert_eq!(range(uint::MAX - 1, uint::MAX).size_hint(), (1, Some(1)));
|
||||
assert_eq!(range(-10i, -1).size_hint(), (9, Some(9)));
|
||||
assert_eq!(range(Foo, Foo).size_hint(), (0, None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_inclusive() {
|
||||
assert!(range_inclusive(0i, 5).collect::<Vec<int>>() ==
|
||||
vec![0i, 1, 2, 3, 4, 5]);
|
||||
assert!(range_inclusive(0i, 5).rev().collect::<Vec<int>>() ==
|
||||
vec![5i, 4, 3, 2, 1, 0]);
|
||||
assert_eq!(range_inclusive(200i, -5).count(), 0);
|
||||
assert_eq!(range_inclusive(200i, -5).rev().count(), 0);
|
||||
assert!(range_inclusive(200i, 200).collect::<Vec<int>>() == vec![200]);
|
||||
assert!(range_inclusive(200i, 200).rev().collect::<Vec<int>>() == vec![200]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_step() {
|
||||
assert!(range_step(0i, 20, 5).collect::<Vec<int>>() ==
|
||||
vec![0, 5, 10, 15]);
|
||||
assert!(range_step(20i, 0, -5).collect::<Vec<int>>() ==
|
||||
vec![20, 15, 10, 5]);
|
||||
assert!(range_step(20i, 0, -6).collect::<Vec<int>>() ==
|
||||
vec![20, 14, 8, 2]);
|
||||
assert!(range_step(200u8, 255, 50).collect::<Vec<u8>>() ==
|
||||
vec![200u8, 250]);
|
||||
assert!(range_step(200i, -5, 1).collect::<Vec<int>>() == vec![]);
|
||||
assert!(range_step(200i, 200, 1).collect::<Vec<int>>() == vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_step_inclusive() {
|
||||
assert!(range_step_inclusive(0i, 20, 5).collect::<Vec<int>>() ==
|
||||
vec![0, 5, 10, 15, 20]);
|
||||
assert!(range_step_inclusive(20i, 0, -5).collect::<Vec<int>>() ==
|
||||
vec![20, 15, 10, 5, 0]);
|
||||
assert!(range_step_inclusive(20i, 0, -6).collect::<Vec<int>>() ==
|
||||
vec![20, 14, 8, 2]);
|
||||
assert!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>() ==
|
||||
vec![200u8, 250]);
|
||||
assert!(range_step_inclusive(200i, -5, 1).collect::<Vec<int>>() ==
|
||||
vec![]);
|
||||
assert!(range_step_inclusive(200i, 200, 1).collect::<Vec<int>>() ==
|
||||
vec![200]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse() {
|
||||
let mut ys = [1i, 2, 3, 4, 5];
|
||||
ys.mut_iter().reverse_();
|
||||
assert!(ys == [5, 4, 3, 2, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peekable_is_empty() {
|
||||
let a = [1i];
|
||||
let mut it = a.iter().peekable();
|
||||
assert!( !it.is_empty() );
|
||||
it.next();
|
||||
assert!( it.is_empty() );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max() {
|
||||
let v: [int, ..0] = [];
|
||||
assert_eq!(v.iter().min_max(), NoElements);
|
||||
|
||||
let v = [1i];
|
||||
assert!(v.iter().min_max() == OneElement(&1));
|
||||
|
||||
let v = [1i, 2, 3, 4, 5];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &5));
|
||||
|
||||
let v = [1i, 2, 3, 4, 5, 6];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &6));
|
||||
|
||||
let v = [1i, 1, 1, 1];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max_result() {
|
||||
let r: MinMaxResult<int> = NoElements;
|
||||
assert_eq!(r.into_option(), None)
|
||||
|
||||
let r = OneElement(1i);
|
||||
assert_eq!(r.into_option(), Some((1,1)));
|
||||
|
||||
let r = MinMax(1i,2);
|
||||
assert_eq!(r.into_option(), Some((1,2)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ pub mod marker {
|
|||
/// ```
|
||||
/// use std::mem;
|
||||
///
|
||||
/// struct S<T> { x: *() }
|
||||
/// struct S<T> { x: *const () }
|
||||
/// fn get<T>(s: &S<T>, v: T) {
|
||||
/// unsafe {
|
||||
/// let x: fn(T) = mem::transmute(s.x);
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
//! the failure message, the file at which failure was invoked, and the line.
|
||||
//! It is up to consumers of this core library to define this failure
|
||||
//! function; it is only required to never return.
|
||||
//!
|
||||
|
||||
// Since libcore defines many fundamental lang items, all tests live in a
|
||||
// separate crate, libcoretest, to avoid bizarre issues.
|
||||
|
||||
#![crate_id = "core#0.11.0"]
|
||||
#![experimental]
|
||||
|
@ -58,17 +60,6 @@
|
|||
#![feature(globs, intrinsics, lang_items, macro_rules, managed_boxes, phase)]
|
||||
#![feature(simd, unsafe_destructor)]
|
||||
#![deny(missing_doc)]
|
||||
#![allow(unknown_features)] // NOTE: remove after stage0 snapshot
|
||||
|
||||
#[cfg(test)] extern crate realcore = "core";
|
||||
#[cfg(test)] extern crate libc;
|
||||
#[cfg(test)] extern crate native;
|
||||
#[cfg(test)] extern crate realstd = "std";
|
||||
|
||||
#[cfg(test)] pub use cmp = realcore::cmp;
|
||||
#[cfg(test)] pub use kinds = realcore::kinds;
|
||||
#[cfg(test)] pub use ops = realcore::ops;
|
||||
#[cfg(test)] pub use ty = realcore::ty;
|
||||
|
||||
mod macros;
|
||||
|
||||
|
@ -105,10 +96,10 @@ pub mod ptr;
|
|||
|
||||
/* Core language traits */
|
||||
|
||||
#[cfg(not(test))] pub mod kinds;
|
||||
#[cfg(not(test))] pub mod ops;
|
||||
#[cfg(not(test))] pub mod ty;
|
||||
#[cfg(not(test))] pub mod cmp;
|
||||
pub mod kinds;
|
||||
pub mod ops;
|
||||
pub mod ty;
|
||||
pub mod cmp;
|
||||
pub mod clone;
|
||||
pub mod default;
|
||||
pub mod collections;
|
||||
|
@ -145,11 +136,4 @@ mod std {
|
|||
pub use kinds;
|
||||
pub use option;
|
||||
pub use fmt;
|
||||
|
||||
#[cfg(test)] pub use realstd::rt; // needed for fail!()
|
||||
// #[cfg(test)] pub use realstd::option; // needed for fail!()
|
||||
// #[cfg(test)] pub use realstd::fmt; // needed for fail!()
|
||||
#[cfg(test)] pub use realstd::os; // needed for tests
|
||||
#[cfg(test)] pub use realstd::slice; // needed for tests
|
||||
#[cfg(test)] pub use realstd::vec; // needed for vec![]
|
||||
}
|
||||
|
|
|
@ -112,16 +112,6 @@ macro_rules! writeln(
|
|||
)
|
||||
)
|
||||
|
||||
#[cfg(test)]
|
||||
macro_rules! vec( ($($e:expr),*) => ({
|
||||
let mut _v = ::std::vec::Vec::new();
|
||||
$(_v.push($e);)*
|
||||
_v
|
||||
}) )
|
||||
|
||||
#[cfg(test)]
|
||||
macro_rules! format( ($($arg:tt)*) => (format_args!(::fmt::format, $($arg)*)) )
|
||||
|
||||
/// Write some formatted data into a stream.
|
||||
///
|
||||
/// Identical to the macro in `std::macros`
|
||||
|
|
|
@ -363,7 +363,7 @@ pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing) }
|
|||
#[inline]
|
||||
#[stable]
|
||||
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
|
||||
ptr::read(src as *T as *U)
|
||||
ptr::read(src as *const T as *const U)
|
||||
}
|
||||
|
||||
/// Transforms lifetime of the second pointer to match the first.
|
||||
|
@ -382,182 +382,3 @@ pub unsafe fn copy_mut_lifetime<'a, S, T>(_ptr: &'a mut S,
|
|||
ptr: &mut T) -> &'a mut T {
|
||||
transmute(ptr)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use mem::*;
|
||||
use option::{Some,None};
|
||||
use realstd::str::StrAllocating;
|
||||
use realstd::owned::Box;
|
||||
use realstd::vec::Vec;
|
||||
use raw;
|
||||
|
||||
#[test]
|
||||
fn size_of_basic() {
|
||||
assert_eq!(size_of::<u8>(), 1u);
|
||||
assert_eq!(size_of::<u16>(), 2u);
|
||||
assert_eq!(size_of::<u32>(), 4u);
|
||||
assert_eq!(size_of::<u64>(), 8u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
fn size_of_32() {
|
||||
assert_eq!(size_of::<uint>(), 4u);
|
||||
assert_eq!(size_of::<*uint>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn size_of_64() {
|
||||
assert_eq!(size_of::<uint>(), 8u);
|
||||
assert_eq!(size_of::<*uint>(), 8u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn size_of_val_basic() {
|
||||
assert_eq!(size_of_val(&1u8), 1);
|
||||
assert_eq!(size_of_val(&1u16), 2);
|
||||
assert_eq!(size_of_val(&1u32), 4);
|
||||
assert_eq!(size_of_val(&1u64), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn align_of_basic() {
|
||||
assert_eq!(align_of::<u8>(), 1u);
|
||||
assert_eq!(align_of::<u16>(), 2u);
|
||||
assert_eq!(align_of::<u32>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
fn align_of_32() {
|
||||
assert_eq!(align_of::<uint>(), 4u);
|
||||
assert_eq!(align_of::<*uint>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn align_of_64() {
|
||||
assert_eq!(align_of::<uint>(), 8u);
|
||||
assert_eq!(align_of::<*uint>(), 8u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn align_of_val_basic() {
|
||||
assert_eq!(align_of_val(&1u8), 1u);
|
||||
assert_eq!(align_of_val(&1u16), 2u);
|
||||
assert_eq!(align_of_val(&1u32), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_swap() {
|
||||
let mut x = 31337i;
|
||||
let mut y = 42i;
|
||||
swap(&mut x, &mut y);
|
||||
assert_eq!(x, 42);
|
||||
assert_eq!(y, 31337);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_replace() {
|
||||
let mut x = Some("test".to_string());
|
||||
let y = replace(&mut x, None);
|
||||
assert!(x.is_none());
|
||||
assert!(y.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transmute_copy() {
|
||||
assert_eq!(1u, unsafe { ::mem::transmute_copy(&1) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transmute() {
|
||||
trait Foo {}
|
||||
impl Foo for int {}
|
||||
|
||||
let a = box 100i as Box<Foo>;
|
||||
unsafe {
|
||||
let x: raw::TraitObject = transmute(a);
|
||||
assert!(*(x.data as *int) == 100);
|
||||
let _x: Box<Foo> = transmute(x);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
assert!(Vec::from_slice([76u8]) == transmute("L".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME #13642 (these benchmarks should be in another place)
|
||||
/// Completely miscellaneous language-construct benchmarks.
|
||||
#[cfg(test)]
|
||||
mod bench {
|
||||
extern crate test;
|
||||
use self::test::Bencher;
|
||||
use option::{Some,None};
|
||||
|
||||
// Static/dynamic method dispatch
|
||||
|
||||
struct Struct {
|
||||
field: int
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn method(&self) -> int;
|
||||
}
|
||||
|
||||
impl Trait for Struct {
|
||||
fn method(&self) -> int {
|
||||
self.field
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn trait_vtable_method_call(b: &mut Bencher) {
|
||||
let s = Struct { field: 10 };
|
||||
let t = &s as &Trait;
|
||||
b.iter(|| {
|
||||
t.method()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn trait_static_method_call(b: &mut Bencher) {
|
||||
let s = Struct { field: 10 };
|
||||
b.iter(|| {
|
||||
s.method()
|
||||
});
|
||||
}
|
||||
|
||||
// Overhead of various match forms
|
||||
|
||||
#[bench]
|
||||
fn match_option_some(b: &mut Bencher) {
|
||||
let x = Some(10);
|
||||
b.iter(|| {
|
||||
match x {
|
||||
Some(y) => y,
|
||||
None => 11
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn match_vec_pattern(b: &mut Bencher) {
|
||||
let x = [1,2,3,4,5,6];
|
||||
b.iter(|| {
|
||||
match x {
|
||||
[1,2,3,..] => 10,
|
||||
_ => 11
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,152 +32,4 @@ pub static MIN: $T = (-1 as $T) << (BITS - 1);
|
|||
#[unstable]
|
||||
pub static MAX: $T = !MIN;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
|
||||
use int;
|
||||
use num;
|
||||
use num::CheckedDiv;
|
||||
|
||||
#[test]
|
||||
fn test_overflows() {
|
||||
assert!(MAX > 0);
|
||||
assert!(MIN <= 0);
|
||||
assert!(MIN + MAX + 1 == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10 as $T, 2 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_abs() {
|
||||
assert!((1 as $T).abs() == 1 as $T);
|
||||
assert!((0 as $T).abs() == 0 as $T);
|
||||
assert!((-1 as $T).abs() == 1 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_abs_sub() {
|
||||
assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
|
||||
assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
|
||||
assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T);
|
||||
assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signum() {
|
||||
assert!((1 as $T).signum() == 1 as $T);
|
||||
assert!((0 as $T).signum() == 0 as $T);
|
||||
assert!((-0 as $T).signum() == 0 as $T);
|
||||
assert!((-1 as $T).signum() == -1 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_positive() {
|
||||
assert!((1 as $T).is_positive());
|
||||
assert!(!(0 as $T).is_positive());
|
||||
assert!(!(-0 as $T).is_positive());
|
||||
assert!(!(-1 as $T).is_positive());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_negative() {
|
||||
assert!(!(1 as $T).is_negative());
|
||||
assert!(!(0 as $T).is_negative());
|
||||
assert!(!(-0 as $T).is_negative());
|
||||
assert!((-1 as $T).is_negative());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwise_operators() {
|
||||
assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
|
||||
assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
|
||||
assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
|
||||
assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
|
||||
assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
|
||||
assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
|
||||
}
|
||||
|
||||
static A: $T = 0b0101100;
|
||||
static B: $T = 0b0100001;
|
||||
static C: $T = 0b1111001;
|
||||
|
||||
static _0: $T = 0;
|
||||
static _1: $T = !0;
|
||||
|
||||
#[test]
|
||||
fn test_count_ones() {
|
||||
assert!(A.count_ones() == 3);
|
||||
assert!(B.count_ones() == 2);
|
||||
assert!(C.count_ones() == 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_zeros() {
|
||||
assert!(A.count_zeros() == BITS as $T - 3);
|
||||
assert!(B.count_zeros() == BITS as $T - 2);
|
||||
assert!(C.count_zeros() == BITS as $T - 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate() {
|
||||
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
|
||||
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
|
||||
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
|
||||
|
||||
// Rotating these should make no difference
|
||||
//
|
||||
// We test using 124 bits because to ensure that overlong bit shifts do
|
||||
// not cause undefined behaviour. See #10183.
|
||||
assert_eq!(_0.rotate_left(124), _0);
|
||||
assert_eq!(_1.rotate_left(124), _1);
|
||||
assert_eq!(_0.rotate_right(124), _0);
|
||||
assert_eq!(_1.rotate_right(124), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_swap_bytes() {
|
||||
assert_eq!(A.swap_bytes().swap_bytes(), A);
|
||||
assert_eq!(B.swap_bytes().swap_bytes(), B);
|
||||
assert_eq!(C.swap_bytes().swap_bytes(), C);
|
||||
|
||||
// Swapping these should make no difference
|
||||
assert_eq!(_0.swap_bytes(), _0);
|
||||
assert_eq!(_1.swap_bytes(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_le() {
|
||||
assert_eq!(Int::from_le(A.to_le()), A);
|
||||
assert_eq!(Int::from_le(B.to_le()), B);
|
||||
assert_eq!(Int::from_le(C.to_le()), C);
|
||||
assert_eq!(Int::from_le(_0), _0);
|
||||
assert_eq!(Int::from_le(_1), _1);
|
||||
assert_eq!(_0.to_le(), _0);
|
||||
assert_eq!(_1.to_le(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_be() {
|
||||
assert_eq!(Int::from_be(A.to_be()), A);
|
||||
assert_eq!(Int::from_be(B.to_be()), B);
|
||||
assert_eq!(Int::from_be(C.to_be()), C);
|
||||
assert_eq!(Int::from_be(_0), _0);
|
||||
assert_eq!(Int::from_be(_1), _1);
|
||||
assert_eq!(_0.to_be(), _0);
|
||||
assert_eq!(_1.to_be(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signed_checked_div() {
|
||||
assert!(10i.checked_div(&2) == Some(5));
|
||||
assert!(5i.checked_div(&0) == None);
|
||||
assert!(int::MIN.checked_div(&-1) == None);
|
||||
}
|
||||
}
|
||||
|
||||
))
|
||||
|
|
|
@ -1375,22 +1375,6 @@ macro_rules! checkeddiv_uint_impl(
|
|||
|
||||
checkeddiv_uint_impl!(uint u8 u16 u32 u64)
|
||||
|
||||
/// Helper function for testing numeric operations
|
||||
#[cfg(test)]
|
||||
pub fn test_num<T:Num + NumCast + ::std::fmt::Show>(ten: T, two: T) {
|
||||
assert_eq!(ten.add(&two), cast(12i).unwrap());
|
||||
assert_eq!(ten.sub(&two), cast(8i).unwrap());
|
||||
assert_eq!(ten.mul(&two), cast(20i).unwrap());
|
||||
assert_eq!(ten.div(&two), cast(5i).unwrap());
|
||||
assert_eq!(ten.rem(&two), cast(0i).unwrap());
|
||||
|
||||
assert_eq!(ten.add(&two), ten + two);
|
||||
assert_eq!(ten.sub(&two), ten - two);
|
||||
assert_eq!(ten.mul(&two), ten * two);
|
||||
assert_eq!(ten.div(&two), ten / two);
|
||||
assert_eq!(ten.rem(&two), ten % two);
|
||||
}
|
||||
|
||||
/// Used for representing the classification of floating point numbers
|
||||
#[deriving(PartialEq, Show)]
|
||||
pub enum FPCategory {
|
||||
|
|
|
@ -23,111 +23,4 @@ pub static MIN: $T = 0 as $T;
|
|||
#[unstable]
|
||||
pub static MAX: $T = 0 as $T - 1 as $T;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
use super::*;
|
||||
|
||||
use num;
|
||||
use num::CheckedDiv;
|
||||
|
||||
#[test]
|
||||
fn test_overflows() {
|
||||
assert!(MAX > 0);
|
||||
assert!(MIN <= 0);
|
||||
assert!(MIN + MAX + 1 == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10 as $T, 2 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwise_operators() {
|
||||
assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
|
||||
assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
|
||||
assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
|
||||
assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
|
||||
assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
|
||||
assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
|
||||
}
|
||||
|
||||
static A: $T = 0b0101100;
|
||||
static B: $T = 0b0100001;
|
||||
static C: $T = 0b1111001;
|
||||
|
||||
static _0: $T = 0;
|
||||
static _1: $T = !0;
|
||||
|
||||
#[test]
|
||||
fn test_count_ones() {
|
||||
assert!(A.count_ones() == 3);
|
||||
assert!(B.count_ones() == 2);
|
||||
assert!(C.count_ones() == 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_zeros() {
|
||||
assert!(A.count_zeros() == BITS as $T - 3);
|
||||
assert!(B.count_zeros() == BITS as $T - 2);
|
||||
assert!(C.count_zeros() == BITS as $T - 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate() {
|
||||
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
|
||||
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
|
||||
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
|
||||
|
||||
// Rotating these should make no difference
|
||||
//
|
||||
// We test using 124 bits because to ensure that overlong bit shifts do
|
||||
// not cause undefined behaviour. See #10183.
|
||||
assert_eq!(_0.rotate_left(124), _0);
|
||||
assert_eq!(_1.rotate_left(124), _1);
|
||||
assert_eq!(_0.rotate_right(124), _0);
|
||||
assert_eq!(_1.rotate_right(124), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_swap_bytes() {
|
||||
assert_eq!(A.swap_bytes().swap_bytes(), A);
|
||||
assert_eq!(B.swap_bytes().swap_bytes(), B);
|
||||
assert_eq!(C.swap_bytes().swap_bytes(), C);
|
||||
|
||||
// Swapping these should make no difference
|
||||
assert_eq!(_0.swap_bytes(), _0);
|
||||
assert_eq!(_1.swap_bytes(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_le() {
|
||||
assert_eq!(Int::from_le(A.to_le()), A);
|
||||
assert_eq!(Int::from_le(B.to_le()), B);
|
||||
assert_eq!(Int::from_le(C.to_le()), C);
|
||||
assert_eq!(Int::from_le(_0), _0);
|
||||
assert_eq!(Int::from_le(_1), _1);
|
||||
assert_eq!(_0.to_le(), _0);
|
||||
assert_eq!(_1.to_le(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_be() {
|
||||
assert_eq!(Int::from_be(A.to_be()), A);
|
||||
assert_eq!(Int::from_be(B.to_be()), B);
|
||||
assert_eq!(Int::from_be(C.to_be()), C);
|
||||
assert_eq!(Int::from_be(_0), _0);
|
||||
assert_eq!(Int::from_be(_1), _1);
|
||||
assert_eq!(_0.to_be(), _0);
|
||||
assert_eq!(_1.to_be(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsigned_checked_div() {
|
||||
assert!(10u.checked_div(&2) == Some(5));
|
||||
assert!(5u.checked_div(&0) == None);
|
||||
}
|
||||
}
|
||||
|
||||
))
|
||||
|
|
|
@ -117,7 +117,6 @@ pub trait Add<RHS,Result> {
|
|||
|
||||
macro_rules! add_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Add<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn add(&self, other: &$t) -> $t { (*self) + (*other) }
|
||||
|
@ -159,7 +158,6 @@ pub trait Sub<RHS,Result> {
|
|||
|
||||
macro_rules! sub_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Sub<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn sub(&self, other: &$t) -> $t { (*self) - (*other) }
|
||||
|
@ -201,7 +199,6 @@ pub trait Mul<RHS,Result> {
|
|||
|
||||
macro_rules! mul_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Mul<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn mul(&self, other: &$t) -> $t { (*self) * (*other) }
|
||||
|
@ -243,7 +240,6 @@ pub trait Div<RHS,Result> {
|
|||
|
||||
macro_rules! div_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Div<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn div(&self, other: &$t) -> $t { (*self) / (*other) }
|
||||
|
@ -285,7 +281,6 @@ pub trait Rem<RHS,Result> {
|
|||
|
||||
macro_rules! rem_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Rem<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn rem(&self, other: &$t) -> $t { (*self) % (*other) }
|
||||
|
@ -295,7 +290,6 @@ macro_rules! rem_impl(
|
|||
|
||||
macro_rules! rem_float_impl(
|
||||
($t:ty, $fmod:ident) => {
|
||||
#[cfg(not(test))]
|
||||
impl Rem<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn rem(&self, other: &$t) -> $t {
|
||||
|
@ -342,7 +336,6 @@ pub trait Neg<Result> {
|
|||
|
||||
macro_rules! neg_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Neg<$t> for $t {
|
||||
#[inline]
|
||||
fn neg(&self) -> $t { -*self }
|
||||
|
@ -352,7 +345,6 @@ macro_rules! neg_impl(
|
|||
|
||||
macro_rules! neg_uint_impl(
|
||||
($t:ty, $t_signed:ty) => {
|
||||
#[cfg(not(test))]
|
||||
impl Neg<$t> for $t {
|
||||
#[inline]
|
||||
fn neg(&self) -> $t { -(*self as $t_signed) as $t }
|
||||
|
@ -402,7 +394,6 @@ pub trait Not<Result> {
|
|||
|
||||
macro_rules! not_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl Not<$t> for $t {
|
||||
#[inline]
|
||||
fn not(&self) -> $t { !*self }
|
||||
|
@ -444,7 +435,6 @@ pub trait BitAnd<RHS,Result> {
|
|||
|
||||
macro_rules! bitand_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl BitAnd<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn bitand(&self, rhs: &$t) -> $t { (*self) & (*rhs) }
|
||||
|
@ -486,7 +476,6 @@ pub trait BitOr<RHS,Result> {
|
|||
|
||||
macro_rules! bitor_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl BitOr<$t,$t> for $t {
|
||||
#[inline]
|
||||
fn bitor(&self, rhs: &$t) -> $t { (*self) | (*rhs) }
|
||||
|
@ -528,7 +517,6 @@ pub trait BitXor<RHS,Result> {
|
|||
|
||||
macro_rules! bitxor_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(not(test))]
|
||||
impl BitXor<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn bitxor(&self, other: &$t) -> $t { (*self) ^ (*other) }
|
||||
|
@ -570,12 +558,6 @@ pub trait Shl<RHS,Result> {
|
|||
|
||||
macro_rules! shl_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(stage0)]
|
||||
impl Shl<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn shl(&self, other: &$t) -> $t { (*self) << (*other) }
|
||||
}
|
||||
#[cfg(not(stage0), not(test))]
|
||||
impl Shl<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn shl(&self, other: &$t) -> $t {
|
||||
|
@ -619,12 +601,6 @@ pub trait Shr<RHS,Result> {
|
|||
|
||||
macro_rules! shr_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[cfg(stage0, not(test))]
|
||||
impl Shr<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn shr(&self, other: &$t) -> $t { (*self) >> (*other) }
|
||||
}
|
||||
#[cfg(not(stage0), not(test))]
|
||||
impl Shr<$t, $t> for $t {
|
||||
#[inline]
|
||||
fn shr(&self, other: &$t) -> $t { (*self) >> (*other as uint) }
|
||||
|
@ -758,28 +734,3 @@ pub trait FnOnce<Args,Result> {
|
|||
/// This is called when the call operator is used.
|
||||
fn call_once(self, args: Args) -> Result;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod bench {
|
||||
extern crate test;
|
||||
use self::test::Bencher;
|
||||
use ops::Drop;
|
||||
|
||||
// Overhead of dtors
|
||||
|
||||
struct HasDtor {
|
||||
x: int
|
||||
}
|
||||
|
||||
impl Drop for HasDtor {
|
||||
fn drop(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_obj_with_dtor(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
HasDtor { x : 10 };
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -587,310 +587,34 @@ impl<A> ExactSize<A> for Item<A> {}
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn collect<T, Iter: Iterator<Option<T>>, V: FromIterator<T>>(iter: Iter) -> Option<V> {
|
||||
// FIXME(#11084): This should be twice as fast once this bug is closed.
|
||||
let mut iter = iter.scan(false, |state, x| {
|
||||
match x {
|
||||
Some(x) => Some(x),
|
||||
None => {
|
||||
*state = true;
|
||||
// FIXME(#11084): This could be replaced with Iterator::scan when this
|
||||
// performance bug is closed.
|
||||
|
||||
struct Adapter<Iter> {
|
||||
iter: Iter,
|
||||
found_none: bool,
|
||||
}
|
||||
|
||||
impl<T, Iter: Iterator<Option<T>>> Iterator<T> for Adapter<Iter> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<T> {
|
||||
match self.iter.next() {
|
||||
Some(Some(value)) => Some(value),
|
||||
Some(None) => {
|
||||
self.found_none = true;
|
||||
None
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let v: V = FromIterator::from_iter(iter.by_ref());
|
||||
let mut adapter = Adapter { iter: iter, found_none: false };
|
||||
let v: V = FromIterator::from_iter(adapter.by_ref());
|
||||
|
||||
if iter.state {
|
||||
if adapter.found_none {
|
||||
None
|
||||
} else {
|
||||
Some(v)
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use realstd::vec::Vec;
|
||||
use realstd::string::String;
|
||||
use option::collect;
|
||||
use prelude::*;
|
||||
use realstd::str::{Str, StrAllocating};
|
||||
use iter::range;
|
||||
|
||||
use str::StrSlice;
|
||||
use kinds::marker;
|
||||
use slice::ImmutableVector;
|
||||
|
||||
#[test]
|
||||
fn test_get_ptr() {
|
||||
unsafe {
|
||||
let x = box 0;
|
||||
let addr_x: *int = ::mem::transmute(&*x);
|
||||
let opt = Some(x);
|
||||
let y = opt.unwrap();
|
||||
let addr_y: *int = ::mem::transmute(&*y);
|
||||
assert_eq!(addr_x, addr_y);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_str() {
|
||||
let x = "test".to_string();
|
||||
let addr_x = x.as_slice().as_ptr();
|
||||
let opt = Some(x);
|
||||
let y = opt.unwrap();
|
||||
let addr_y = y.as_slice().as_ptr();
|
||||
assert_eq!(addr_x, addr_y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_resource() {
|
||||
use realstd::rc::Rc;
|
||||
use cell::RefCell;
|
||||
|
||||
struct R {
|
||||
i: Rc<RefCell<int>>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl ::ops::Drop for R {
|
||||
fn drop(&mut self) {
|
||||
let ii = &*self.i;
|
||||
let i = *ii.borrow();
|
||||
*ii.borrow_mut() = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn r(i: Rc<RefCell<int>>) -> R {
|
||||
R {
|
||||
i: i
|
||||
}
|
||||
}
|
||||
|
||||
fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
|
||||
use realstd::clone::Clone;
|
||||
t.clone()
|
||||
}
|
||||
|
||||
let i = Rc::new(RefCell::new(0i));
|
||||
{
|
||||
let x = r(realclone(&i));
|
||||
let opt = Some(x);
|
||||
let _y = opt.unwrap();
|
||||
}
|
||||
assert_eq!(*i.borrow(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_dance() {
|
||||
let x = Some(());
|
||||
let mut y = Some(5i);
|
||||
let mut y2 = 0;
|
||||
for _x in x.iter() {
|
||||
y2 = y.take_unwrap();
|
||||
}
|
||||
assert_eq!(y2, 5);
|
||||
assert!(y.is_none());
|
||||
}
|
||||
|
||||
#[test] #[should_fail]
|
||||
fn test_option_too_much_dance() {
|
||||
let mut y = Some(marker::NoCopy);
|
||||
let _y2 = y.take_unwrap();
|
||||
let _y3 = y.take_unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
let x: Option<int> = Some(1i);
|
||||
assert_eq!(x.and(Some(2i)), Some(2));
|
||||
assert_eq!(x.and(None::<int>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.and(Some(2i)), None);
|
||||
assert_eq!(x.and(None::<int>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and_then() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), None);
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.or(Some(2)), Some(1));
|
||||
assert_eq!(x.or(None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.or(Some(2)), Some(2));
|
||||
assert_eq!(x.or(None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(1));
|
||||
assert_eq!(x.or_else(|| None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(2));
|
||||
assert_eq!(x.or_else(|| None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_while_some() {
|
||||
let mut i = 0i;
|
||||
Some(10).while_some(|j| {
|
||||
i += 1;
|
||||
if j > 0 {
|
||||
Some(j-1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
assert_eq!(i, 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap() {
|
||||
assert_eq!(Some(1i).unwrap(), 1);
|
||||
let s = Some("hello".to_string()).unwrap();
|
||||
assert_eq!(s.as_slice(), "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_unwrap_fail1() {
|
||||
let x: Option<int> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_unwrap_fail2() {
|
||||
let x: Option<String> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.unwrap_or(2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.unwrap_or(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filtered() {
|
||||
let some_stuff = Some(42i);
|
||||
let modified_stuff = some_stuff.filtered(|&x| {x < 10});
|
||||
assert_eq!(some_stuff.unwrap(), 42);
|
||||
assert!(modified_stuff.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let val = 5i;
|
||||
|
||||
let x = Some(val);
|
||||
let mut it = x.iter();
|
||||
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next(), Some(&val));
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_iter() {
|
||||
let val = 5i;
|
||||
let new_val = 11i;
|
||||
|
||||
let mut x = Some(val);
|
||||
{
|
||||
let mut it = x.mut_iter();
|
||||
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
|
||||
match it.next() {
|
||||
Some(interior) => {
|
||||
assert_eq!(*interior, val);
|
||||
*interior = new_val;
|
||||
}
|
||||
None => assert!(false),
|
||||
}
|
||||
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
assert_eq!(x, Some(new_val));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let small = Some(1.0f64);
|
||||
let big = Some(5.0f64);
|
||||
let nan = Some(0.0f64/0.0);
|
||||
assert!(!(nan < big));
|
||||
assert!(!(nan > big));
|
||||
assert!(small < big);
|
||||
assert!(None < big);
|
||||
assert!(big > None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate() {
|
||||
let mut x = Some(3i);
|
||||
assert!(x.mutate(|i| i+1));
|
||||
assert_eq!(x, Some(4i));
|
||||
assert!(x.mutate_or_set(0, |i| i+1));
|
||||
assert_eq!(x, Some(5i));
|
||||
x = None;
|
||||
assert!(!x.mutate(|i| i+1));
|
||||
assert_eq!(x, None);
|
||||
assert!(!x.mutate_or_set(0i, |i| i+1));
|
||||
assert_eq!(x, Some(0i));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let v: Option<Vec<int>> = collect(range(0i, 0)
|
||||
.map(|_| Some(0i)));
|
||||
assert!(v == Some(vec![]));
|
||||
|
||||
let v: Option<Vec<int>> = collect(range(0i, 3)
|
||||
.map(|x| Some(x)));
|
||||
assert!(v == Some(vec![0, 1, 2]));
|
||||
|
||||
let v: Option<Vec<int>> = collect(range(0i, 3)
|
||||
.map(|x| if x > 1 { None } else { Some(x) }));
|
||||
assert!(v == None);
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions = [|| Some(()), || None, || fail!()];
|
||||
|
||||
let v: Option<Vec<()>> = collect(functions.mut_iter().map(|f| (*f)()));
|
||||
|
||||
assert!(v == None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -10,7 +10,7 @@
|
|||
|
||||
// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
|
||||
|
||||
//! Operations on unsafe pointers, `*T`, and `*mut T`.
|
||||
//! Operations on unsafe pointers, `*const T`, and `*mut T`.
|
||||
//!
|
||||
//! Working with unsafe pointers in Rust is uncommon,
|
||||
//! typically limited to a few patterns.
|
||||
|
@ -29,7 +29,7 @@
|
|||
//!
|
||||
//! ```
|
||||
//! let my_num: int = 10;
|
||||
//! let my_num_ptr: *int = &my_num;
|
||||
//! let my_num_ptr: *const int = &my_num;
|
||||
//! let mut my_speed: int = 88;
|
||||
//! let my_speed_ptr: *mut int = &mut my_speed;
|
||||
//! ```
|
||||
|
@ -42,7 +42,7 @@
|
|||
//!
|
||||
//! The `transmute` function takes, by value, whatever it's given
|
||||
//! and returns it as whatever type is requested, as long as the
|
||||
//! types are the same size. Because `Box<T>` and `*T` have the same
|
||||
//! types are the same size. Because `Box<T>` and `*mut T` have the same
|
||||
//! representation they can be trivially,
|
||||
//! though unsafely, transformed from one type to the other.
|
||||
//!
|
||||
|
@ -51,7 +51,7 @@
|
|||
//!
|
||||
//! unsafe {
|
||||
//! let my_num: Box<int> = box 10;
|
||||
//! let my_num: *int = mem::transmute(my_num);
|
||||
//! let my_num: *const int = mem::transmute(my_num);
|
||||
//! let my_speed: Box<int> = box 88;
|
||||
//! let my_speed: *mut int = mem::transmute(my_speed);
|
||||
//!
|
||||
|
@ -93,7 +93,7 @@ use intrinsics;
|
|||
use iter::{range, Iterator};
|
||||
use option::{Some, None, Option};
|
||||
|
||||
#[cfg(not(test))] use cmp::{PartialEq, Eq, PartialOrd, Equiv};
|
||||
use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
|
||||
|
||||
/// Create a null pointer.
|
||||
///
|
||||
|
@ -102,12 +102,12 @@ use option::{Some, None, Option};
|
|||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let p: *int = ptr::null();
|
||||
/// let p: *const int = ptr::null();
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "may need a different name after pending changes to pointer types"]
|
||||
pub fn null<T>() -> *T { 0 as *T }
|
||||
pub fn null<T>() -> *const T { 0 as *const T }
|
||||
|
||||
/// Create an unsafe mutable null pointer.
|
||||
///
|
||||
|
@ -137,7 +137,7 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
|||
/// ```
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> Vec<T> {
|
||||
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
|
||||
/// let mut dst = Vec::with_capacity(elts);
|
||||
/// dst.set_len(elts);
|
||||
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
|
||||
|
@ -147,7 +147,7 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
|||
///
|
||||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
intrinsics::copy_memory(dst, src, count)
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
|||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
||||
src: *T,
|
||||
src: *const T,
|
||||
count: uint) {
|
||||
intrinsics::copy_nonoverlapping_memory(dst, src, count)
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
|||
/// Reads the value from `*src` and returns it.
|
||||
#[inline(always)]
|
||||
#[unstable]
|
||||
pub unsafe fn read<T>(src: *T) -> T {
|
||||
pub unsafe fn read<T>(src: *const T) -> T {
|
||||
let mut tmp: T = mem::uninitialized();
|
||||
copy_nonoverlapping_memory(&mut tmp, src, 1);
|
||||
tmp
|
||||
|
@ -275,11 +275,12 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
|
|||
intrinsics::move_val_init(&mut *dst, src)
|
||||
}
|
||||
|
||||
/// Given a **T (pointer to an array of pointers),
|
||||
/// iterate through each *T, up to the provided `len`,
|
||||
/// Given a *const *const T (pointer to an array of pointers),
|
||||
/// iterate through each *const T, up to the provided `len`,
|
||||
/// passing to the provided callback function
|
||||
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||
pub unsafe fn array_each_with_len<T>(arr: *const *const T, len: uint,
|
||||
cb: |*const T|) {
|
||||
if arr.is_null() {
|
||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||
}
|
||||
|
@ -290,8 +291,8 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Given a null-pointer-terminated **T (pointer to
|
||||
/// an array of pointers), iterate through each *T,
|
||||
/// Given a null-pointer-terminated *const *const T (pointer to
|
||||
/// an array of pointers), iterate through each *const T,
|
||||
/// passing to the provided callback function
|
||||
///
|
||||
/// # Safety Note
|
||||
|
@ -300,7 +301,7 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
|||
/// pointer array.
|
||||
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||
#[allow(deprecated)]
|
||||
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
||||
pub unsafe fn array_each<T>(arr: *const *const T, cb: |*const T|) {
|
||||
if arr.is_null() {
|
||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||
}
|
||||
|
@ -312,14 +313,14 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
|||
#[inline]
|
||||
#[deprecated = "use a loop and RawPtr::offset"]
|
||||
#[allow(deprecated)]
|
||||
pub unsafe fn buf_len<T>(buf: **T) -> uint {
|
||||
pub unsafe fn buf_len<T>(buf: *const *const T) -> uint {
|
||||
position(buf, |i| *i == null())
|
||||
}
|
||||
|
||||
/// Return the first offset `i` such that `f(buf[i]) == true`.
|
||||
#[inline]
|
||||
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
|
||||
pub unsafe fn position<T>(buf: *const T, f: |&T| -> bool) -> uint {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if f(&(*buf.offset(i as int))) { return i; }
|
||||
|
@ -352,9 +353,9 @@ pub trait RawPtr<T> {
|
|||
unsafe fn offset(self, count: int) -> Self;
|
||||
}
|
||||
|
||||
impl<T> RawPtr<T> for *T {
|
||||
impl<T> RawPtr<T> for *const T {
|
||||
#[inline]
|
||||
fn null() -> *T { null() }
|
||||
fn null() -> *const T { null() }
|
||||
|
||||
#[inline]
|
||||
fn is_null(&self) -> bool { *self == RawPtr::null() }
|
||||
|
@ -363,7 +364,9 @@ impl<T> RawPtr<T> for *T {
|
|||
fn to_uint(&self) -> uint { *self as uint }
|
||||
|
||||
#[inline]
|
||||
unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
|
||||
unsafe fn offset(self, count: int) -> *const T {
|
||||
intrinsics::offset(self, count)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn to_option(&self) -> Option<&T> {
|
||||
|
@ -387,7 +390,7 @@ impl<T> RawPtr<T> for *mut T {
|
|||
|
||||
#[inline]
|
||||
unsafe fn offset(self, count: int) -> *mut T {
|
||||
intrinsics::offset(self as *T, count) as *mut T
|
||||
intrinsics::offset(self as *const T, count) as *mut T
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -401,20 +404,17 @@ impl<T> RawPtr<T> for *mut T {
|
|||
}
|
||||
|
||||
// Equality for pointers
|
||||
#[cfg(not(test))]
|
||||
impl<T> PartialEq for *T {
|
||||
impl<T> PartialEq for *const T {
|
||||
#[inline]
|
||||
fn eq(&self, other: &*T) -> bool {
|
||||
fn eq(&self, other: &*const T) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
#[inline]
|
||||
fn ne(&self, other: &*T) -> bool { !self.eq(other) }
|
||||
fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> Eq for *T {}
|
||||
impl<T> Eq for *const T {}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> PartialEq for *mut T {
|
||||
#[inline]
|
||||
fn eq(&self, other: &*mut T) -> bool {
|
||||
|
@ -424,27 +424,24 @@ impl<T> PartialEq for *mut T {
|
|||
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> Eq for *mut T {}
|
||||
|
||||
// Equivalence for pointers
|
||||
#[cfg(not(test))]
|
||||
impl<T> Equiv<*mut T> for *T {
|
||||
impl<T> Equiv<*mut T> for *const T {
|
||||
fn equiv(&self, other: &*mut T) -> bool {
|
||||
self.to_uint() == other.to_uint()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> Equiv<*T> for *mut T {
|
||||
fn equiv(&self, other: &*T) -> bool {
|
||||
impl<T> Equiv<*const T> for *mut T {
|
||||
fn equiv(&self, other: &*const T) -> bool {
|
||||
self.to_uint() == other.to_uint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for *T {
|
||||
impl<T> Clone for *const T {
|
||||
#[inline]
|
||||
fn clone(&self) -> *T {
|
||||
fn clone(&self) -> *const T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +454,6 @@ impl<T> Clone for *mut T {
|
|||
}
|
||||
|
||||
// Equality for extern "C" fn pointers
|
||||
#[cfg(not(test))]
|
||||
mod externfnpointers {
|
||||
use mem;
|
||||
use cmp::PartialEq;
|
||||
|
@ -465,8 +461,8 @@ mod externfnpointers {
|
|||
impl<_R> PartialEq for extern "C" fn() -> _R {
|
||||
#[inline]
|
||||
fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
|
||||
let self_: *() = unsafe { mem::transmute(*self) };
|
||||
let other_: *() = unsafe { mem::transmute(*other) };
|
||||
let self_: *const () = unsafe { mem::transmute(*self) };
|
||||
let other_: *const () = unsafe { mem::transmute(*other) };
|
||||
self_ == other_
|
||||
}
|
||||
}
|
||||
|
@ -475,8 +471,9 @@ mod externfnpointers {
|
|||
impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
|
||||
#[inline]
|
||||
fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
|
||||
let self_: *() = unsafe { mem::transmute(*self) };
|
||||
let other_: *() = unsafe { mem::transmute(*other) };
|
||||
let self_: *const () = unsafe { mem::transmute(*self) };
|
||||
|
||||
let other_: *const () = unsafe { mem::transmute(*other) };
|
||||
self_ == other_
|
||||
}
|
||||
}
|
||||
|
@ -490,274 +487,52 @@ mod externfnpointers {
|
|||
}
|
||||
|
||||
// Comparison for pointers
|
||||
#[cfg(not(test))]
|
||||
impl<T> PartialOrd for *T {
|
||||
impl<T> PartialOrd for *const T {
|
||||
#[inline]
|
||||
fn lt(&self, other: &*T) -> bool { *self < *other }
|
||||
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
|
||||
if self < other {
|
||||
Some(Less)
|
||||
} else if self == other {
|
||||
Some(Equal)
|
||||
} else {
|
||||
Some(Greater)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lt(&self, other: &*const T) -> bool { *self < *other }
|
||||
|
||||
#[inline]
|
||||
fn le(&self, other: &*const T) -> bool { *self <= *other }
|
||||
|
||||
#[inline]
|
||||
fn gt(&self, other: &*const T) -> bool { *self > *other }
|
||||
|
||||
#[inline]
|
||||
fn ge(&self, other: &*const T) -> bool { *self >= *other }
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<T> PartialOrd for *mut T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
|
||||
if self < other {
|
||||
Some(Less)
|
||||
} else if self == other {
|
||||
Some(Equal)
|
||||
} else {
|
||||
Some(Greater)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lt(&self, other: &*mut T) -> bool { *self < *other }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(deprecated, experimental)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
use prelude::*;
|
||||
|
||||
use realstd::c_str::ToCStr;
|
||||
use mem;
|
||||
use libc;
|
||||
use realstd::str;
|
||||
use realstd::str::Str;
|
||||
use realstd::vec::Vec;
|
||||
use realstd::collections::Collection;
|
||||
use slice::{ImmutableVector, MutableVector};
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
unsafe {
|
||||
struct Pair {
|
||||
fst: int,
|
||||
snd: int
|
||||
};
|
||||
let mut p = Pair {fst: 10, snd: 20};
|
||||
let pptr: *mut Pair = &mut p;
|
||||
let iptr: *mut int = mem::transmute(pptr);
|
||||
assert_eq!(*iptr, 10);
|
||||
*iptr = 30;
|
||||
assert_eq!(*iptr, 30);
|
||||
assert_eq!(p.fst, 30);
|
||||
|
||||
*pptr = Pair {fst: 50, snd: 60};
|
||||
assert_eq!(*iptr, 50);
|
||||
assert_eq!(p.fst, 50);
|
||||
assert_eq!(p.snd, 60);
|
||||
|
||||
let v0 = vec![32000u16, 32001u16, 32002u16];
|
||||
let mut v1 = vec![0u16, 0u16, 0u16];
|
||||
|
||||
copy_memory(v1.as_mut_ptr().offset(1),
|
||||
v0.as_ptr().offset(1), 1);
|
||||
assert!((*v1.get(0) == 0u16 &&
|
||||
*v1.get(1) == 32001u16 &&
|
||||
*v1.get(2) == 0u16));
|
||||
copy_memory(v1.as_mut_ptr(),
|
||||
v0.as_ptr().offset(2), 1);
|
||||
assert!((*v1.get(0) == 32002u16 &&
|
||||
*v1.get(1) == 32001u16 &&
|
||||
*v1.get(2) == 0u16));
|
||||
copy_memory(v1.as_mut_ptr().offset(2),
|
||||
v0.as_ptr(), 1u);
|
||||
assert!((*v1.get(0) == 32002u16 &&
|
||||
*v1.get(1) == 32001u16 &&
|
||||
*v1.get(2) == 32000u16));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position() {
|
||||
use libc::c_char;
|
||||
|
||||
"hello".with_c_str(|p| {
|
||||
unsafe {
|
||||
assert!(2u == position(p, |c| *c == 'l' as c_char));
|
||||
assert!(4u == position(p, |c| *c == 'o' as c_char));
|
||||
assert!(5u == position(p, |c| *c == 0 as c_char));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buf_len() {
|
||||
"hello".with_c_str(|p0| {
|
||||
"there".with_c_str(|p1| {
|
||||
"thing".with_c_str(|p2| {
|
||||
let v = vec![p0, p1, p2, null()];
|
||||
unsafe {
|
||||
assert_eq!(buf_len(v.as_ptr()), 3u);
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_null() {
|
||||
let p: *int = null();
|
||||
assert!(p.is_null());
|
||||
assert!(!p.is_not_null());
|
||||
|
||||
let q = unsafe { p.offset(1) };
|
||||
assert!(!q.is_null());
|
||||
assert!(q.is_not_null());
|
||||
|
||||
let mp: *mut int = mut_null();
|
||||
assert!(mp.is_null());
|
||||
assert!(!mp.is_not_null());
|
||||
|
||||
let mq = unsafe { mp.offset(1) };
|
||||
assert!(!mq.is_null());
|
||||
assert!(mq.is_not_null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_option() {
|
||||
unsafe {
|
||||
let p: *int = null();
|
||||
assert_eq!(p.to_option(), None);
|
||||
|
||||
let q: *int = &2;
|
||||
assert_eq!(q.to_option().unwrap(), &2);
|
||||
|
||||
let p: *mut int = mut_null();
|
||||
assert_eq!(p.to_option(), None);
|
||||
|
||||
let q: *mut int = &mut 2;
|
||||
assert_eq!(q.to_option().unwrap(), &2);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_addition() {
|
||||
unsafe {
|
||||
let xs = Vec::from_elem(16, 5i);
|
||||
let mut ptr = xs.as_ptr();
|
||||
let end = ptr.offset(16);
|
||||
|
||||
while ptr < end {
|
||||
assert_eq!(*ptr, 5);
|
||||
ptr = ptr.offset(1);
|
||||
}
|
||||
|
||||
let mut xs_mut = xs;
|
||||
let mut m_ptr = xs_mut.as_mut_ptr();
|
||||
let m_end = m_ptr.offset(16);
|
||||
|
||||
while m_ptr < m_end {
|
||||
*m_ptr += 5;
|
||||
m_ptr = m_ptr.offset(1);
|
||||
}
|
||||
|
||||
assert!(xs_mut == Vec::from_elem(16, 10i));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_subtraction() {
|
||||
unsafe {
|
||||
let xs = vec![0,1,2,3,4,5,6,7,8,9];
|
||||
let mut idx = 9i8;
|
||||
let ptr = xs.as_ptr();
|
||||
|
||||
while idx >= 0i8 {
|
||||
assert_eq!(*(ptr.offset(idx as int)), idx as int);
|
||||
idx = idx - 1i8;
|
||||
}
|
||||
|
||||
let mut xs_mut = xs;
|
||||
let m_start = xs_mut.as_mut_ptr();
|
||||
let mut m_ptr = m_start.offset(9);
|
||||
|
||||
while m_ptr >= m_start {
|
||||
*m_ptr += *m_ptr;
|
||||
m_ptr = m_ptr.offset(-1);
|
||||
}
|
||||
|
||||
assert!(xs_mut == vec![0,2,4,6,8,10,12,14,16,18]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_array_each_with_len() {
|
||||
unsafe {
|
||||
let one = "oneOne".to_c_str();
|
||||
let two = "twoTwo".to_c_str();
|
||||
let three = "threeThree".to_c_str();
|
||||
let arr = vec![
|
||||
one.with_ref(|buf| buf),
|
||||
two.with_ref(|buf| buf),
|
||||
three.with_ref(|buf| buf)
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
];
|
||||
|
||||
let mut ctr = 0;
|
||||
let mut iteration_count = 0;
|
||||
array_each_with_len(arr.as_ptr(), arr.len(), |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = expected_arr[ctr].with_ref(|buf| {
|
||||
str::raw::from_c_str(buf)
|
||||
});
|
||||
assert_eq!(actual.as_slice(), expected.as_slice());
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
});
|
||||
assert_eq!(iteration_count, 3u);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_array_each() {
|
||||
unsafe {
|
||||
let one = "oneOne".to_c_str();
|
||||
let two = "twoTwo".to_c_str();
|
||||
let three = "threeThree".to_c_str();
|
||||
let arr = vec![
|
||||
one.with_ref(|buf| buf),
|
||||
two.with_ref(|buf| buf),
|
||||
three.with_ref(|buf| buf),
|
||||
// fake a null terminator
|
||||
null()
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
];
|
||||
|
||||
let arr_ptr = arr.as_ptr();
|
||||
let mut ctr = 0u;
|
||||
let mut iteration_count = 0u;
|
||||
array_each(arr_ptr, |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = expected_arr[ctr].with_ref(|buf| {
|
||||
str::raw::from_c_str(buf)
|
||||
});
|
||||
assert_eq!(actual.as_slice(), expected.as_slice());
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
});
|
||||
assert_eq!(iteration_count, 3);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_ptr_array_each_with_len_null_ptr() {
|
||||
unsafe {
|
||||
array_each_with_len(0 as **libc::c_char, 1, |e| {
|
||||
str::raw::from_c_str(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_ptr_array_each_null_ptr() {
|
||||
unsafe {
|
||||
array_each(0 as **libc::c_char, |e| {
|
||||
str::raw::from_c_str(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_memory() {
|
||||
let mut xs = [0u8, ..20];
|
||||
let ptr = xs.as_mut_ptr();
|
||||
unsafe { set_memory(ptr, 5u8, xs.len()); }
|
||||
assert!(xs == [5u8, ..20]);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn le(&self, other: &*mut T) -> bool { *self <= *other }
|
||||
|
||||
#[inline]
|
||||
fn gt(&self, other: &*mut T) -> bool { *self > *other }
|
||||
|
||||
#[inline]
|
||||
fn ge(&self, other: &*mut T) -> bool { *self >= *other }
|
||||
}
|
||||
|
|
|
@ -31,20 +31,20 @@ pub struct Box<T> {
|
|||
|
||||
/// The representation of a Rust slice
|
||||
pub struct Slice<T> {
|
||||
pub data: *T,
|
||||
pub data: *const T,
|
||||
pub len: uint,
|
||||
}
|
||||
|
||||
/// The representation of a Rust closure
|
||||
pub struct Closure {
|
||||
pub code: *(),
|
||||
pub env: *(),
|
||||
pub code: *mut (),
|
||||
pub env: *mut (),
|
||||
}
|
||||
|
||||
/// The representation of a Rust procedure (`proc()`)
|
||||
pub struct Procedure {
|
||||
pub code: *(),
|
||||
pub env: *(),
|
||||
pub code: *mut (),
|
||||
pub env: *mut (),
|
||||
}
|
||||
|
||||
/// The representation of a Rust trait object.
|
||||
|
@ -52,8 +52,8 @@ pub struct Procedure {
|
|||
/// This struct does not have a `Repr` implementation
|
||||
/// because there is no way to refer to all trait objects generically.
|
||||
pub struct TraitObject {
|
||||
pub vtable: *(),
|
||||
pub data: *(),
|
||||
pub vtable: *mut (),
|
||||
pub data: *mut (),
|
||||
}
|
||||
|
||||
/// This trait is meant to map equivalences between raw structs and their
|
||||
|
@ -70,32 +70,3 @@ pub trait Repr<T> {
|
|||
impl<'a, T> Repr<Slice<T>> for &'a [T] {}
|
||||
impl<'a> Repr<Slice<u8>> for &'a str {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use mem;
|
||||
|
||||
#[test]
|
||||
fn synthesize_closure() {
|
||||
unsafe {
|
||||
let x = 10;
|
||||
let f: |int| -> int = |y| x + y;
|
||||
|
||||
assert_eq!(f(20), 30);
|
||||
|
||||
let original_closure: Closure = mem::transmute(f);
|
||||
|
||||
let actual_function_pointer = original_closure.code;
|
||||
let environment = original_closure.env;
|
||||
|
||||
let new_closure = Closure {
|
||||
code: actual_function_pointer,
|
||||
env: environment
|
||||
};
|
||||
|
||||
let new_f: |int| -> int = mem::transmute(new_closure);
|
||||
assert_eq!(new_f(20), 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -585,20 +585,32 @@ impl<T: Show, E> Result<T, E> {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> {
|
||||
// FIXME(#11084): This should be twice as fast once this bug is closed.
|
||||
let mut iter = iter.scan(None, |state, x| {
|
||||
match x {
|
||||
Ok(x) => Some(x),
|
||||
Err(err) => {
|
||||
*state = Some(err);
|
||||
// FIXME(#11084): This could be replaced with Iterator::scan when this
|
||||
// performance bug is closed.
|
||||
|
||||
struct Adapter<Iter, E> {
|
||||
iter: Iter,
|
||||
err: Option<E>,
|
||||
}
|
||||
|
||||
impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<T> {
|
||||
match self.iter.next() {
|
||||
Some(Ok(value)) => Some(value),
|
||||
Some(Err(err)) => {
|
||||
self.err = Some(err);
|
||||
None
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let v: V = FromIterator::from_iter(iter.by_ref());
|
||||
let mut adapter = Adapter { iter: iter, err: None };
|
||||
let v: V = FromIterator::from_iter(adapter.by_ref());
|
||||
|
||||
match iter.state {
|
||||
match adapter.err {
|
||||
Some(err) => Err(err),
|
||||
None => Ok(v),
|
||||
}
|
||||
|
@ -635,166 +647,3 @@ pub fn fold<T,
|
|||
pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
|
||||
fold(iterator, (), |_, _| ())
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use realstd::vec::Vec;
|
||||
|
||||
use result::{collect, fold, fold_};
|
||||
use prelude::*;
|
||||
use realstd::str::Str;
|
||||
use iter::range;
|
||||
|
||||
pub fn op1() -> Result<int, &'static str> { Ok(666) }
|
||||
pub fn op2() -> Result<int, &'static str> { Err("sadface") }
|
||||
|
||||
#[test]
|
||||
pub fn test_and() {
|
||||
assert_eq!(op1().and(Ok(667i)).unwrap(), 667);
|
||||
assert_eq!(op1().and(Err::<(), &'static str>("bad")).unwrap_err(),
|
||||
"bad");
|
||||
|
||||
assert_eq!(op2().and(Ok(667i)).unwrap_err(), "sadface");
|
||||
assert_eq!(op2().and(Err::<(),&'static str>("bad")).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_and_then() {
|
||||
assert_eq!(op1().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap(), 667);
|
||||
assert_eq!(op1().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
|
||||
"bad");
|
||||
|
||||
assert_eq!(op2().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap_err(),
|
||||
"sadface");
|
||||
assert_eq!(op2().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_or() {
|
||||
assert_eq!(op1().or(Ok(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or(Err("bad")).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or(Ok(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_or_else() {
|
||||
assert_eq!(op1().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or_else(|e| Err::<int, &'static str>(e)).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or_else(|e| Err::<int, &'static str>(e)).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_impl_map() {
|
||||
assert!(Ok::<int, int>(1).map(|x| x + 1) == Ok(2));
|
||||
assert!(Err::<int, int>(1).map(|x| x + 1) == Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_impl_map_err() {
|
||||
assert!(Ok::<int, int>(1).map_err(|x| x + 1) == Ok(1));
|
||||
assert!(Err::<int, int>(1).map_err(|x| x + 1) == Err(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let v: Result<Vec<int>, ()> = collect(range(0i, 0).map(|_| Ok::<int, ()>(0)));
|
||||
assert!(v == Ok(vec![]));
|
||||
|
||||
let v: Result<Vec<int>, ()> = collect(range(0i, 3).map(|x| Ok::<int, ()>(x)));
|
||||
assert!(v == Ok(vec![0, 1, 2]));
|
||||
|
||||
let v: Result<Vec<int>, int> = collect(range(0i, 3)
|
||||
.map(|x| if x > 1 { Err(x) } else { Ok(x) }));
|
||||
assert!(v == Err(2));
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions = [|| Ok(()), || Err(1i), || fail!()];
|
||||
|
||||
let v: Result<Vec<()>, int> = collect(functions.mut_iter().map(|f| (*f)()));
|
||||
assert!(v == Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold() {
|
||||
assert_eq!(fold_(range(0i, 0)
|
||||
.map(|_| Ok::<(), ()>(()))),
|
||||
Ok(()));
|
||||
assert_eq!(fold(range(0i, 3)
|
||||
.map(|x| Ok::<int, ()>(x)),
|
||||
0, |a, b| a + b),
|
||||
Ok(3));
|
||||
assert_eq!(fold_(range(0i, 3)
|
||||
.map(|x| if x > 1 { Err(x) } else { Ok(()) })),
|
||||
Err(2));
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions = [|| Ok(()), || Err(1i), || fail!()];
|
||||
|
||||
assert_eq!(fold_(functions.mut_iter()
|
||||
.map(|f| (*f)())),
|
||||
Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_fmt_default() {
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let err: Result<int, &'static str> = Err("Err");
|
||||
|
||||
let s = format!("{}", ok);
|
||||
assert_eq!(s.as_slice(), "Ok(100)");
|
||||
let s = format!("{}", err);
|
||||
assert_eq!(s.as_slice(), "Err(Err)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_unwrap_or() {
|
||||
let ok: Result<int, &'static str> = Ok(100i);
|
||||
let ok_err: Result<int, &'static str> = Err("Err");
|
||||
|
||||
assert_eq!(ok.unwrap_or(50), 100);
|
||||
assert_eq!(ok_err.unwrap_or(50), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_unwrap_or_else() {
|
||||
fn handler(msg: &'static str) -> int {
|
||||
if msg == "I got this." {
|
||||
50i
|
||||
} else {
|
||||
fail!("BadBad")
|
||||
}
|
||||
}
|
||||
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let ok_err: Result<int, &'static str> = Err("I got this.");
|
||||
|
||||
assert_eq!(ok.unwrap_or_else(handler), 100);
|
||||
assert_eq!(ok_err.unwrap_or_else(handler), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
pub fn test_unwrap_or_else_failure() {
|
||||
fn handler(msg: &'static str) -> int {
|
||||
if msg == "I got this." {
|
||||
50i
|
||||
} else {
|
||||
fail!("BadBad")
|
||||
}
|
||||
}
|
||||
|
||||
let bad_err: Result<int, &'static str> = Err("Unrecoverable mess.");
|
||||
let _ : int = bad_err.unwrap_or_else(handler);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,7 @@
|
|||
|
||||
use mem;
|
||||
use char;
|
||||
use char::Char;
|
||||
use clone::Clone;
|
||||
use cmp;
|
||||
use cmp::{PartialEq, Eq};
|
||||
|
@ -24,7 +25,7 @@ use default::Default;
|
|||
use iter::{Filter, Map, Iterator};
|
||||
use iter::{DoubleEndedIterator, ExactSize};
|
||||
use iter::range;
|
||||
use num::Saturating;
|
||||
use num::{CheckedMul, Saturating};
|
||||
use option::{None, Option, Some};
|
||||
use raw::Repr;
|
||||
use slice::ImmutableVector;
|
||||
|
@ -557,6 +558,41 @@ impl<'a> Iterator<&'a str> for StrSplits<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// External iterator for a string's UTF16 codeunits.
|
||||
/// Use with the `std::iter` module.
|
||||
#[deriving(Clone)]
|
||||
pub struct Utf16CodeUnits<'a> {
|
||||
chars: Chars<'a>,
|
||||
extra: u16
|
||||
}
|
||||
|
||||
impl<'a> Iterator<u16> for Utf16CodeUnits<'a> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<u16> {
|
||||
if self.extra != 0 {
|
||||
let tmp = self.extra;
|
||||
self.extra = 0;
|
||||
return Some(tmp);
|
||||
}
|
||||
|
||||
let mut buf = [0u16, ..2];
|
||||
self.chars.next().map(|ch| {
|
||||
let n = ch.encode_utf16(buf /* as mut slice! */);
|
||||
if n == 2 { self.extra = buf[1]; }
|
||||
buf[0]
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
let (low, high) = self.chars.size_hint();
|
||||
// every char gets either one u16 or two u16,
|
||||
// so this iterator is between 1 or 2 times as
|
||||
// long as the underlying iterator.
|
||||
(low, high.and_then(|n| n.checked_mul(&2)))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Comparing strings
|
||||
*/
|
||||
|
@ -568,10 +604,10 @@ Section: Comparing strings
|
|||
#[inline]
|
||||
fn eq_slice_(a: &str, b: &str) -> bool {
|
||||
#[allow(ctypes)]
|
||||
extern { fn memcmp(s1: *i8, s2: *i8, n: uint) -> i32; }
|
||||
extern { fn memcmp(s1: *const i8, s2: *const i8, n: uint) -> i32; }
|
||||
a.len() == b.len() && unsafe {
|
||||
memcmp(a.as_ptr() as *i8,
|
||||
b.as_ptr() as *i8,
|
||||
memcmp(a.as_ptr() as *const i8,
|
||||
b.as_ptr() as *const i8,
|
||||
a.len()) == 0
|
||||
}
|
||||
}
|
||||
|
@ -579,20 +615,12 @@ fn eq_slice_(a: &str, b: &str) -> bool {
|
|||
/// Bytewise slice equality
|
||||
/// NOTE: This function is (ab)used in rustc::middle::trans::_match
|
||||
/// to compare &[u8] byte slices that are not necessarily valid UTF-8.
|
||||
#[cfg(not(test))]
|
||||
#[lang="str_eq"]
|
||||
#[inline]
|
||||
pub fn eq_slice(a: &str, b: &str) -> bool {
|
||||
eq_slice_(a, b)
|
||||
}
|
||||
|
||||
/// Bytewise slice equality
|
||||
#[cfg(test)]
|
||||
#[inline]
|
||||
pub fn eq_slice(a: &str, b: &str) -> bool {
|
||||
eq_slice_(a, b)
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Misc
|
||||
*/
|
||||
|
@ -888,8 +916,8 @@ pub mod raw {
|
|||
/// Form a slice from a C string. Unsafe because the caller must ensure the
|
||||
/// C string has the static lifetime, or else the return value may be
|
||||
/// invalidated later.
|
||||
pub unsafe fn c_str_to_static_slice(s: *i8) -> &'static str {
|
||||
let s = s as *u8;
|
||||
pub unsafe fn c_str_to_static_slice(s: *const i8) -> &'static str {
|
||||
let s = s as *const u8;
|
||||
let mut curr = s;
|
||||
let mut len = 0u;
|
||||
while *curr != 0u8 {
|
||||
|
@ -934,13 +962,12 @@ pub mod raw {
|
|||
Section: Trait implementations
|
||||
*/
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[allow(missing_doc)]
|
||||
pub mod traits {
|
||||
use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
|
||||
use collections::Collection;
|
||||
use iter::Iterator;
|
||||
use option::{Some, None};
|
||||
use option::{Option, Some, None};
|
||||
use str::{Str, StrSlice, eq_slice};
|
||||
|
||||
impl<'a> Ord for &'a str {
|
||||
|
@ -971,7 +998,9 @@ pub mod traits {
|
|||
|
||||
impl<'a> PartialOrd for &'a str {
|
||||
#[inline]
|
||||
fn lt(&self, other: & &'a str) -> bool { self.cmp(other) == Less }
|
||||
fn partial_cmp(&self, other: &&'a str) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: Str> Equiv<S> for &'a str {
|
||||
|
@ -980,9 +1009,6 @@ pub mod traits {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod traits {}
|
||||
|
||||
/// Any string that can be represented as a slice
|
||||
pub trait Str {
|
||||
/// Work with `self` as a slice.
|
||||
|
@ -1618,7 +1644,10 @@ pub trait StrSlice<'a> {
|
|||
/// The caller must ensure that the string outlives this pointer,
|
||||
/// and that it is not reallocated (e.g. by pushing to the
|
||||
/// string).
|
||||
fn as_ptr(&self) -> *u8;
|
||||
fn as_ptr(&self) -> *const u8;
|
||||
|
||||
/// Return an iterator of `u16` over the string encoded as UTF-16.
|
||||
fn utf16_units(&self) -> Utf16CodeUnits<'a>;
|
||||
}
|
||||
|
||||
impl<'a> StrSlice<'a> for &'a str {
|
||||
|
@ -1714,7 +1743,7 @@ impl<'a> StrSlice<'a> for &'a str {
|
|||
fn lines_any(&self) -> AnyLines<'a> {
|
||||
self.lines().map(|line| {
|
||||
let l = line.len();
|
||||
if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
|
||||
if l > 0 && line.as_bytes()[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
|
||||
else { line }
|
||||
})
|
||||
}
|
||||
|
@ -1838,26 +1867,26 @@ impl<'a> StrSlice<'a> for &'a str {
|
|||
fn is_char_boundary(&self, index: uint) -> bool {
|
||||
if index == self.len() { return true; }
|
||||
if index > self.len() { return false; }
|
||||
let b = self[index];
|
||||
let b = self.as_bytes()[index];
|
||||
return b < 128u8 || b >= 192u8;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn char_range_at(&self, i: uint) -> CharRange {
|
||||
if self[i] < 128u8 {
|
||||
return CharRange {ch: self[i] as char, next: i + 1 };
|
||||
if self.as_bytes()[i] < 128u8 {
|
||||
return CharRange {ch: self.as_bytes()[i] as char, next: i + 1 };
|
||||
}
|
||||
|
||||
// Multibyte case is a fn to allow char_range_at to inline cleanly
|
||||
fn multibyte_char_range_at(s: &str, i: uint) -> CharRange {
|
||||
let mut val = s[i] as u32;
|
||||
let mut val = s.as_bytes()[i] as u32;
|
||||
let w = UTF8_CHAR_WIDTH[val as uint] as uint;
|
||||
assert!((w != 0));
|
||||
|
||||
val = utf8_first_byte!(val, w);
|
||||
val = utf8_acc_cont_byte!(val, s[i + 1]);
|
||||
if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
|
||||
if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
|
||||
val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]);
|
||||
if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); }
|
||||
if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); }
|
||||
|
||||
return CharRange {ch: unsafe { mem::transmute(val) }, next: i + w};
|
||||
}
|
||||
|
@ -1870,23 +1899,25 @@ impl<'a> StrSlice<'a> for &'a str {
|
|||
let mut prev = start;
|
||||
|
||||
prev = prev.saturating_sub(1);
|
||||
if self[prev] < 128 { return CharRange{ch: self[prev] as char, next: prev} }
|
||||
if self.as_bytes()[prev] < 128 {
|
||||
return CharRange{ch: self.as_bytes()[prev] as char, next: prev}
|
||||
}
|
||||
|
||||
// Multibyte case is a fn to allow char_range_at_reverse to inline cleanly
|
||||
fn multibyte_char_range_at_reverse(s: &str, mut i: uint) -> CharRange {
|
||||
// while there is a previous byte == 10......
|
||||
while i > 0 && s[i] & 192u8 == TAG_CONT_U8 {
|
||||
while i > 0 && s.as_bytes()[i] & 192u8 == TAG_CONT_U8 {
|
||||
i -= 1u;
|
||||
}
|
||||
|
||||
let mut val = s[i] as u32;
|
||||
let mut val = s.as_bytes()[i] as u32;
|
||||
let w = UTF8_CHAR_WIDTH[val as uint] as uint;
|
||||
assert!((w != 0));
|
||||
|
||||
val = utf8_first_byte!(val, w);
|
||||
val = utf8_acc_cont_byte!(val, s[i + 1]);
|
||||
if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
|
||||
if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
|
||||
val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]);
|
||||
if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); }
|
||||
if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); }
|
||||
|
||||
return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
|
||||
}
|
||||
|
@ -1964,9 +1995,14 @@ impl<'a> StrSlice<'a> for &'a str {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *u8 {
|
||||
fn as_ptr(&self) -> *const u8 {
|
||||
self.repr().data
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn utf16_units(&self) -> Utf16CodeUnits<'a> {
|
||||
Utf16CodeUnits{ chars: self.chars(), extra: 0}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Default for &'a str {
|
||||
|
|
|
@ -62,8 +62,9 @@
|
|||
#![doc(primitive = "tuple")]
|
||||
|
||||
use clone::Clone;
|
||||
#[cfg(not(test))] use cmp::*;
|
||||
#[cfg(not(test))] use default::Default;
|
||||
use cmp::*;
|
||||
use default::Default;
|
||||
use option::{Option, Some};
|
||||
|
||||
// macro for implementing n-ary tuple functions and operations
|
||||
macro_rules! tuple_impls {
|
||||
|
@ -111,7 +112,6 @@ macro_rules! tuple_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
|
||||
#[inline]
|
||||
fn eq(&self, other: &($($T,)+)) -> bool {
|
||||
|
@ -123,11 +123,13 @@ macro_rules! tuple_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:Eq),+> Eq for ($($T,)+) {}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
|
||||
lexical_partial_cmp!($(self.$refN(), other.$refN()),+)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &($($T,)+)) -> bool {
|
||||
lexical_ord!(lt, $(self.$refN(), other.$refN()),+)
|
||||
|
@ -146,7 +148,6 @@ macro_rules! tuple_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:Ord),+> Ord for ($($T,)+) {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &($($T,)+)) -> Ordering {
|
||||
|
@ -154,7 +155,6 @@ macro_rules! tuple_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl<$($T:Default),+> Default for ($($T,)+) {
|
||||
#[inline]
|
||||
fn default() -> ($($T,)+) {
|
||||
|
@ -177,6 +177,16 @@ macro_rules! lexical_ord {
|
|||
($rel: ident, $a:expr, $b:expr) => { (*$a) . $rel ($b) };
|
||||
}
|
||||
|
||||
macro_rules! lexical_partial_cmp {
|
||||
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
|
||||
match ($a).partial_cmp($b) {
|
||||
Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
|
||||
ordering => ordering
|
||||
}
|
||||
};
|
||||
($a:expr, $b:expr) => { ($a).partial_cmp($b) };
|
||||
}
|
||||
|
||||
macro_rules! lexical_cmp {
|
||||
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
|
||||
match ($a).cmp($b) {
|
||||
|
@ -292,93 +302,3 @@ tuple_impls! {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use clone::Clone;
|
||||
use cmp::*;
|
||||
use realstd::str::Str;
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let a = (1i, "2");
|
||||
let b = a.clone();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_getters() {
|
||||
macro_rules! test_getter(
|
||||
($x:expr, $valN:ident, $refN:ident, $mutN:ident,
|
||||
$init:expr, $incr:expr, $result:expr) => ({
|
||||
assert_eq!($x.$valN(), $init);
|
||||
assert_eq!(*$x.$refN(), $init);
|
||||
*$x.$mutN() += $incr;
|
||||
assert_eq!(*$x.$refN(), $result);
|
||||
})
|
||||
)
|
||||
let mut x = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64);
|
||||
test_getter!(x, val0, ref0, mut0, 0, 1, 1);
|
||||
test_getter!(x, val1, ref1, mut1, 1, 1, 2);
|
||||
test_getter!(x, val2, ref2, mut2, 2, 1, 3);
|
||||
test_getter!(x, val3, ref3, mut3, 3, 1, 4);
|
||||
test_getter!(x, val4, ref4, mut4, 4, 1, 5);
|
||||
test_getter!(x, val5, ref5, mut5, 5, 1, 6);
|
||||
test_getter!(x, val6, ref6, mut6, 6, 1, 7);
|
||||
test_getter!(x, val7, ref7, mut7, 7, 1, 8);
|
||||
test_getter!(x, val8, ref8, mut8, 8, 1, 9);
|
||||
test_getter!(x, val9, ref9, mut9, 9, 1, 10);
|
||||
test_getter!(x, val10, ref10, mut10, 10.0, 1.0, 11.0);
|
||||
test_getter!(x, val11, ref11, mut11, 11.0, 1.0, 12.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_cmp() {
|
||||
let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
|
||||
|
||||
let nan = 0.0f64/0.0;
|
||||
|
||||
// PartialEq
|
||||
assert_eq!(small, small);
|
||||
assert_eq!(big, big);
|
||||
assert!(small != big);
|
||||
assert!(big != small);
|
||||
|
||||
// PartialOrd
|
||||
assert!(small < big);
|
||||
assert!(!(small < small));
|
||||
assert!(!(big < small));
|
||||
assert!(!(big < big));
|
||||
|
||||
assert!(small <= small);
|
||||
assert!(big <= big);
|
||||
|
||||
assert!(big > small);
|
||||
assert!(small >= small);
|
||||
assert!(big >= small);
|
||||
assert!(big >= big);
|
||||
|
||||
assert!(!((1.0f64, 2.0f64) < (nan, 3.0)));
|
||||
assert!(!((1.0f64, 2.0f64) <= (nan, 3.0)));
|
||||
assert!(!((1.0f64, 2.0f64) > (nan, 3.0)));
|
||||
assert!(!((1.0f64, 2.0f64) >= (nan, 3.0)));
|
||||
assert!(((1.0f64, 2.0f64) < (2.0, nan)));
|
||||
assert!(!((2.0f64, 2.0f64) < (2.0, nan)));
|
||||
|
||||
// Ord
|
||||
assert!(small.cmp(&small) == Equal);
|
||||
assert!(big.cmp(&big) == Equal);
|
||||
assert!(small.cmp(&big) == Less);
|
||||
assert!(big.cmp(&small) == Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let s = format!("{}", (1i,));
|
||||
assert_eq!(s.as_slice(), "(1,)");
|
||||
let s = format!("{}", (1i, true));
|
||||
assert_eq!(s.as_slice(), "(1, true)");
|
||||
let s = format!("{}", (1i, "hi", true));
|
||||
assert_eq!(s.as_slice(), "(1, hi, true)");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ impl<T> Unsafe<T> {
|
|||
|
||||
/// Gets a mutable pointer to the wrapped value
|
||||
#[inline]
|
||||
pub unsafe fn get(&self) -> *mut T { &self.value as *T as *mut T }
|
||||
pub unsafe fn get(&self) -> *mut T { &self.value as *const T as *mut T }
|
||||
|
||||
/// Unwraps the value
|
||||
#[inline]
|
||||
|
|
131
src/libcoretest/any.rs
Normal file
131
src/libcoretest/any.rs
Normal file
|
@ -0,0 +1,131 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
use core::any::*;
|
||||
use test::Bencher;
|
||||
use test;
|
||||
|
||||
#[deriving(PartialEq, Show)]
|
||||
struct Test;
|
||||
|
||||
static TEST: &'static str = "Test";
|
||||
|
||||
#[test]
|
||||
fn any_referenced() {
|
||||
let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any);
|
||||
|
||||
assert!(a.is::<uint>());
|
||||
assert!(!b.is::<uint>());
|
||||
assert!(!c.is::<uint>());
|
||||
|
||||
assert!(!a.is::<&'static str>());
|
||||
assert!(b.is::<&'static str>());
|
||||
assert!(!c.is::<&'static str>());
|
||||
|
||||
assert!(!a.is::<Test>());
|
||||
assert!(!b.is::<Test>());
|
||||
assert!(c.is::<Test>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_owning() {
|
||||
let (a, b, c) = (box 5u as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
|
||||
|
||||
assert!(a.is::<uint>());
|
||||
assert!(!b.is::<uint>());
|
||||
assert!(!c.is::<uint>());
|
||||
|
||||
assert!(!a.is::<&'static str>());
|
||||
assert!(b.is::<&'static str>());
|
||||
assert!(!c.is::<&'static str>());
|
||||
|
||||
assert!(!a.is::<Test>());
|
||||
assert!(!b.is::<Test>());
|
||||
assert!(c.is::<Test>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_as_ref() {
|
||||
let a = &5u as &Any;
|
||||
|
||||
match a.as_ref::<uint>() {
|
||||
Some(&5) => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match a.as_ref::<Test>() {
|
||||
None => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_as_mut() {
|
||||
let mut a = 5u;
|
||||
let mut b = box 7u;
|
||||
|
||||
let a_r = &mut a as &mut Any;
|
||||
let tmp: &mut uint = &mut *b;
|
||||
let b_r = tmp as &mut Any;
|
||||
|
||||
match a_r.as_mut::<uint>() {
|
||||
Some(x) => {
|
||||
assert_eq!(*x, 5u);
|
||||
*x = 612;
|
||||
}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match b_r.as_mut::<uint>() {
|
||||
Some(x) => {
|
||||
assert_eq!(*x, 7u);
|
||||
*x = 413;
|
||||
}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match a_r.as_mut::<Test>() {
|
||||
None => (),
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match b_r.as_mut::<Test>() {
|
||||
None => (),
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match a_r.as_mut::<uint>() {
|
||||
Some(&612) => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
|
||||
match b_r.as_mut::<uint>() {
|
||||
Some(&413) => {}
|
||||
x => fail!("Unexpected value {}", x)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_fixed_vec() {
|
||||
let test = [0u, ..8];
|
||||
let test = &test as &Any;
|
||||
assert!(test.is::<[uint, ..8]>());
|
||||
assert!(!test.is::<[uint, ..10]>());
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn bench_as_ref(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut x = 0i;
|
||||
let mut y = &mut x as &mut Any;
|
||||
test::black_box(&mut y);
|
||||
test::black_box(y.as_ref::<int>() == Some(&0));
|
||||
});
|
||||
}
|
83
src/libcoretest/atomics.rs
Normal file
83
src/libcoretest/atomics.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::atomics::*;
|
||||
|
||||
#[test]
|
||||
fn bool_() {
|
||||
let a = AtomicBool::new(false);
|
||||
assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
|
||||
assert_eq!(a.compare_and_swap(false, true, SeqCst), true);
|
||||
|
||||
a.store(false, SeqCst);
|
||||
assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bool_and() {
|
||||
let a = AtomicBool::new(true);
|
||||
assert_eq!(a.fetch_and(false, SeqCst),true);
|
||||
assert_eq!(a.load(SeqCst),false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_and() {
|
||||
let x = AtomicUint::new(0xf731);
|
||||
assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_or() {
|
||||
let x = AtomicUint::new(0xf731);
|
||||
assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_xor() {
|
||||
let x = AtomicUint::new(0xf731);
|
||||
assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_and() {
|
||||
let x = AtomicInt::new(0xf731);
|
||||
assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_or() {
|
||||
let x = AtomicInt::new(0xf731);
|
||||
assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn int_xor() {
|
||||
let x = AtomicInt::new(0xf731);
|
||||
assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
|
||||
assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
|
||||
}
|
||||
|
||||
static mut S_BOOL : AtomicBool = INIT_ATOMIC_BOOL;
|
||||
static mut S_INT : AtomicInt = INIT_ATOMIC_INT;
|
||||
static mut S_UINT : AtomicUint = INIT_ATOMIC_UINT;
|
||||
|
||||
#[test]
|
||||
fn static_init() {
|
||||
unsafe {
|
||||
assert!(!S_BOOL.load(SeqCst));
|
||||
assert!(S_INT.load(SeqCst) == 0);
|
||||
assert!(S_UINT.load(SeqCst) == 0);
|
||||
}
|
||||
}
|
129
src/libcoretest/cell.rs
Normal file
129
src/libcoretest/cell.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::cell::*;
|
||||
use std::mem::drop;
|
||||
|
||||
#[test]
|
||||
fn smoketest_cell() {
|
||||
let x = Cell::new(10i);
|
||||
assert!(x == Cell::new(10));
|
||||
assert!(x.get() == 10);
|
||||
x.set(20);
|
||||
assert!(x == Cell::new(20));
|
||||
assert!(x.get() == 20);
|
||||
|
||||
let y = Cell::new((30i, 40i));
|
||||
assert!(y == Cell::new((30, 40)));
|
||||
assert!(y.get() == (30, 40));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cell_has_sensible_show() {
|
||||
let x = Cell::new("foo bar");
|
||||
assert!(format!("{}", x).as_slice().contains(x.get()));
|
||||
|
||||
x.set("baz qux");
|
||||
assert!(format!("{}", x).as_slice().contains(x.get()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ref_and_refmut_have_sensible_show() {
|
||||
let refcell = RefCell::new("foo");
|
||||
|
||||
let refcell_refmut = refcell.borrow_mut();
|
||||
assert!(format!("{}", refcell_refmut).as_slice().contains("foo"));
|
||||
drop(refcell_refmut);
|
||||
|
||||
let refcell_ref = refcell.borrow();
|
||||
assert!(format!("{}", refcell_ref).as_slice().contains("foo"));
|
||||
drop(refcell_ref);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_imm_borrow() {
|
||||
let x = RefCell::new(0i);
|
||||
let _b1 = x.borrow();
|
||||
x.borrow();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_mut_then_imm_borrow() {
|
||||
let x = RefCell::new(0i);
|
||||
let _b1 = x.borrow_mut();
|
||||
assert!(x.try_borrow().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_imm_then_borrow_mut() {
|
||||
let x = RefCell::new(0i);
|
||||
let _b1 = x.borrow();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_double_borrow_mut() {
|
||||
let x = RefCell::new(0i);
|
||||
let _b1 = x.borrow_mut();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imm_release_borrow_mut() {
|
||||
let x = RefCell::new(0i);
|
||||
{
|
||||
let _b1 = x.borrow();
|
||||
}
|
||||
x.borrow_mut();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_release_borrow_mut() {
|
||||
let x = RefCell::new(0i);
|
||||
{
|
||||
let _b1 = x.borrow_mut();
|
||||
}
|
||||
x.borrow();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_borrow_single_release_no_borrow_mut() {
|
||||
let x = RefCell::new(0i);
|
||||
let _b1 = x.borrow();
|
||||
{
|
||||
let _b2 = x.borrow();
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn discard_doesnt_unborrow() {
|
||||
let x = RefCell::new(0i);
|
||||
let _b = x.borrow();
|
||||
let _ = _b;
|
||||
let _b = x.borrow_mut();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(experimental)]
|
||||
fn clone_ref_updates_flag() {
|
||||
let x = RefCell::new(0i);
|
||||
{
|
||||
let b1 = x.borrow();
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
{
|
||||
let _b2 = clone_ref(&b1);
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_none());
|
||||
}
|
||||
assert!(x.try_borrow_mut().is_some());
|
||||
}
|
202
src/libcoretest/char.rs
Normal file
202
src/libcoretest/char.rs
Normal file
|
@ -0,0 +1,202 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::char::{escape_unicode, escape_default};
|
||||
|
||||
#[test]
|
||||
fn test_is_lowercase() {
|
||||
assert!('a'.is_lowercase());
|
||||
assert!('ö'.is_lowercase());
|
||||
assert!('ß'.is_lowercase());
|
||||
assert!(!'Ü'.is_lowercase());
|
||||
assert!(!'P'.is_lowercase());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_uppercase() {
|
||||
assert!(!'h'.is_uppercase());
|
||||
assert!(!'ä'.is_uppercase());
|
||||
assert!(!'ß'.is_uppercase());
|
||||
assert!('Ö'.is_uppercase());
|
||||
assert!('T'.is_uppercase());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_whitespace() {
|
||||
assert!(' '.is_whitespace());
|
||||
assert!('\u2007'.is_whitespace());
|
||||
assert!('\t'.is_whitespace());
|
||||
assert!('\n'.is_whitespace());
|
||||
assert!(!'a'.is_whitespace());
|
||||
assert!(!'_'.is_whitespace());
|
||||
assert!(!'\u0000'.is_whitespace());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_digit() {
|
||||
assert_eq!('0'.to_digit(10u), Some(0u));
|
||||
assert_eq!('1'.to_digit(2u), Some(1u));
|
||||
assert_eq!('2'.to_digit(3u), Some(2u));
|
||||
assert_eq!('9'.to_digit(10u), Some(9u));
|
||||
assert_eq!('a'.to_digit(16u), Some(10u));
|
||||
assert_eq!('A'.to_digit(16u), Some(10u));
|
||||
assert_eq!('b'.to_digit(16u), Some(11u));
|
||||
assert_eq!('B'.to_digit(16u), Some(11u));
|
||||
assert_eq!('z'.to_digit(36u), Some(35u));
|
||||
assert_eq!('Z'.to_digit(36u), Some(35u));
|
||||
assert_eq!(' '.to_digit(10u), None);
|
||||
assert_eq!('$'.to_digit(36u), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_lowercase() {
|
||||
assert_eq!('A'.to_lowercase(), 'a');
|
||||
assert_eq!('Ö'.to_lowercase(), 'ö');
|
||||
assert_eq!('ß'.to_lowercase(), 'ß');
|
||||
assert_eq!('Ü'.to_lowercase(), 'ü');
|
||||
assert_eq!('💩'.to_lowercase(), '💩');
|
||||
assert_eq!('Σ'.to_lowercase(), 'σ');
|
||||
assert_eq!('Τ'.to_lowercase(), 'τ');
|
||||
assert_eq!('Ι'.to_lowercase(), 'ι');
|
||||
assert_eq!('Γ'.to_lowercase(), 'γ');
|
||||
assert_eq!('Μ'.to_lowercase(), 'μ');
|
||||
assert_eq!('Α'.to_lowercase(), 'α');
|
||||
assert_eq!('Σ'.to_lowercase(), 'σ');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_uppercase() {
|
||||
assert_eq!('a'.to_uppercase(), 'A');
|
||||
assert_eq!('ö'.to_uppercase(), 'Ö');
|
||||
assert_eq!('ß'.to_uppercase(), 'ß'); // not ẞ: Latin capital letter sharp s
|
||||
assert_eq!('ü'.to_uppercase(), 'Ü');
|
||||
assert_eq!('💩'.to_uppercase(), '💩');
|
||||
|
||||
assert_eq!('σ'.to_uppercase(), 'Σ');
|
||||
assert_eq!('τ'.to_uppercase(), 'Τ');
|
||||
assert_eq!('ι'.to_uppercase(), 'Ι');
|
||||
assert_eq!('γ'.to_uppercase(), 'Γ');
|
||||
assert_eq!('μ'.to_uppercase(), 'Μ');
|
||||
assert_eq!('α'.to_uppercase(), 'Α');
|
||||
assert_eq!('ς'.to_uppercase(), 'Σ');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_control() {
|
||||
assert!('\u0000'.is_control());
|
||||
assert!('\u0003'.is_control());
|
||||
assert!('\u0006'.is_control());
|
||||
assert!('\u0009'.is_control());
|
||||
assert!('\u007f'.is_control());
|
||||
assert!('\u0092'.is_control());
|
||||
assert!(!'\u0020'.is_control());
|
||||
assert!(!'\u0055'.is_control());
|
||||
assert!(!'\u0068'.is_control());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_digit() {
|
||||
assert!('2'.is_digit());
|
||||
assert!('7'.is_digit());
|
||||
assert!(!'c'.is_digit());
|
||||
assert!(!'i'.is_digit());
|
||||
assert!(!'z'.is_digit());
|
||||
assert!(!'Q'.is_digit());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_default() {
|
||||
fn string(c: char) -> String {
|
||||
let mut result = String::new();
|
||||
escape_default(c, |c| { result.push_char(c); });
|
||||
return result;
|
||||
}
|
||||
let s = string('\n');
|
||||
assert_eq!(s.as_slice(), "\\n");
|
||||
let s = string('\r');
|
||||
assert_eq!(s.as_slice(), "\\r");
|
||||
let s = string('\'');
|
||||
assert_eq!(s.as_slice(), "\\'");
|
||||
let s = string('"');
|
||||
assert_eq!(s.as_slice(), "\\\"");
|
||||
let s = string(' ');
|
||||
assert_eq!(s.as_slice(), " ");
|
||||
let s = string('a');
|
||||
assert_eq!(s.as_slice(), "a");
|
||||
let s = string('~');
|
||||
assert_eq!(s.as_slice(), "~");
|
||||
let s = string('\x00');
|
||||
assert_eq!(s.as_slice(), "\\x00");
|
||||
let s = string('\x1f');
|
||||
assert_eq!(s.as_slice(), "\\x1f");
|
||||
let s = string('\x7f');
|
||||
assert_eq!(s.as_slice(), "\\x7f");
|
||||
let s = string('\xff');
|
||||
assert_eq!(s.as_slice(), "\\xff");
|
||||
let s = string('\u011b');
|
||||
assert_eq!(s.as_slice(), "\\u011b");
|
||||
let s = string('\U0001d4b6');
|
||||
assert_eq!(s.as_slice(), "\\U0001d4b6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_unicode() {
|
||||
fn string(c: char) -> String {
|
||||
let mut result = String::new();
|
||||
escape_unicode(c, |c| { result.push_char(c); });
|
||||
return result;
|
||||
}
|
||||
let s = string('\x00');
|
||||
assert_eq!(s.as_slice(), "\\x00");
|
||||
let s = string('\n');
|
||||
assert_eq!(s.as_slice(), "\\x0a");
|
||||
let s = string(' ');
|
||||
assert_eq!(s.as_slice(), "\\x20");
|
||||
let s = string('a');
|
||||
assert_eq!(s.as_slice(), "\\x61");
|
||||
let s = string('\u011b');
|
||||
assert_eq!(s.as_slice(), "\\u011b");
|
||||
let s = string('\U0001d4b6');
|
||||
assert_eq!(s.as_slice(), "\\U0001d4b6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str() {
|
||||
let s = 't'.to_str();
|
||||
assert_eq!(s.as_slice(), "t");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_utf8() {
|
||||
fn check(input: char, expect: &[u8]) {
|
||||
let mut buf = [0u8, ..4];
|
||||
let n = input.encode_utf8(buf /* as mut slice! */);
|
||||
assert_eq!(buf.slice_to(n), expect);
|
||||
}
|
||||
|
||||
check('x', [0x78]);
|
||||
check('\u00e9', [0xc3, 0xa9]);
|
||||
check('\ua66e', [0xea, 0x99, 0xae]);
|
||||
check('\U0001f4a9', [0xf0, 0x9f, 0x92, 0xa9]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_utf16() {
|
||||
fn check(input: char, expect: &[u16]) {
|
||||
let mut buf = [0u16, ..2];
|
||||
let n = input.encode_utf16(buf /* as mut slice! */);
|
||||
assert_eq!(buf.slice_to(n), expect);
|
||||
}
|
||||
|
||||
check('x', [0x0078]);
|
||||
check('\u00e9', [0x00e9]);
|
||||
check('\ua66e', [0xa66e]);
|
||||
check('\U0001f4a9', [0xd83d, 0xdca9]);
|
||||
}
|
39
src/libcoretest/clone.rs
Normal file
39
src/libcoretest/clone.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[test]
|
||||
fn test_borrowed_clone() {
|
||||
let x = 5i;
|
||||
let y: &int = &x;
|
||||
let z: &int = (&y).clone();
|
||||
assert_eq!(*z, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone_from() {
|
||||
let a = box 5i;
|
||||
let mut b = box 10i;
|
||||
b.clone_from(&a);
|
||||
assert_eq!(*b, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extern_fn_clone() {
|
||||
trait Empty {}
|
||||
impl Empty for int {}
|
||||
|
||||
fn test_fn_a() -> f64 { 1.0 }
|
||||
fn test_fn_b<T: Empty>(x: T) -> T { x }
|
||||
fn test_fn_c(_: int, _: f64, _: int, _: int, _: int) {}
|
||||
|
||||
let _ = test_fn_a.clone();
|
||||
let _ = test_fn_b::<int>.clone();
|
||||
let _ = test_fn_c.clone();
|
||||
}
|
69
src/libcoretest/cmp.rs
Normal file
69
src/libcoretest/cmp.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::cmp::lexical_ordering;
|
||||
|
||||
#[test]
|
||||
fn test_int_totalord() {
|
||||
assert_eq!(5i.cmp(&10), Less);
|
||||
assert_eq!(10i.cmp(&5), Greater);
|
||||
assert_eq!(5i.cmp(&5), Equal);
|
||||
assert_eq!((-5i).cmp(&12), Less);
|
||||
assert_eq!(12i.cmp(&-5), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_int_totalord() {
|
||||
assert_eq!((&mut 5i).cmp(&&mut 10), Less);
|
||||
assert_eq!((&mut 10i).cmp(&&mut 5), Greater);
|
||||
assert_eq!((&mut 5i).cmp(&&mut 5), Equal);
|
||||
assert_eq!((&mut -5i).cmp(&&mut 12), Less);
|
||||
assert_eq!((&mut 12i).cmp(&&mut -5), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ordering_order() {
|
||||
assert!(Less < Equal);
|
||||
assert_eq!(Greater.cmp(&Less), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lexical_ordering() {
|
||||
fn t(o1: Ordering, o2: Ordering, e: Ordering) {
|
||||
assert_eq!(lexical_ordering(o1, o2), e);
|
||||
}
|
||||
|
||||
let xs = [Less, Equal, Greater];
|
||||
for &o in xs.iter() {
|
||||
t(Less, o, Less);
|
||||
t(Equal, o, o);
|
||||
t(Greater, o, Greater);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_defined_eq() {
|
||||
// Our type.
|
||||
struct SketchyNum {
|
||||
num : int
|
||||
}
|
||||
|
||||
// Our implementation of `PartialEq` to support `==` and `!=`.
|
||||
impl PartialEq for SketchyNum {
|
||||
// Our custom eq allows numbers which are near each other to be equal! :D
|
||||
fn eq(&self, other: &SketchyNum) -> bool {
|
||||
(self.num - other.num).abs() < 5
|
||||
}
|
||||
}
|
||||
|
||||
// Now these binary operators will work when applied!
|
||||
assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
|
||||
assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
|
||||
}
|
59
src/libcoretest/finally.rs
Normal file
59
src/libcoretest/finally.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::finally::{try_finally, Finally};
|
||||
use std::task::failing;
|
||||
|
||||
#[test]
|
||||
fn test_success() {
|
||||
let mut i = 0i;
|
||||
try_finally(
|
||||
&mut i, (),
|
||||
|i, ()| {
|
||||
*i = 10;
|
||||
},
|
||||
|i| {
|
||||
assert!(!failing());
|
||||
assert_eq!(*i, 10);
|
||||
*i = 20;
|
||||
});
|
||||
assert_eq!(i, 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_fail() {
|
||||
let mut i = 0i;
|
||||
try_finally(
|
||||
&mut i, (),
|
||||
|i, ()| {
|
||||
*i = 10;
|
||||
fail!();
|
||||
},
|
||||
|i| {
|
||||
assert!(failing());
|
||||
assert_eq!(*i, 10);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retval() {
|
||||
let mut closure: || -> int = || 10;
|
||||
let i = closure.finally(|| { });
|
||||
assert_eq!(i, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compact() {
|
||||
fn do_some_fallible_work() {}
|
||||
fn but_always_run_this_function() { }
|
||||
let mut f = do_some_fallible_work;
|
||||
f.finally(but_always_run_this_function);
|
||||
}
|
11
src/libcoretest/fmt/mod.rs
Normal file
11
src/libcoretest/fmt/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod num;
|
234
src/libcoretest/fmt/num.rs
Normal file
234
src/libcoretest/fmt/num.rs
Normal file
|
@ -0,0 +1,234 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![allow(unsigned_negate)]
|
||||
|
||||
use core::fmt::radix;
|
||||
|
||||
#[test]
|
||||
fn test_format_int() {
|
||||
// Formatting integers should select the right implementation based off
|
||||
// the type of the argument. Also, hex/octal/binary should be defined
|
||||
// for integers, but they shouldn't emit the negative sign.
|
||||
assert!(format!("{}", 1i).as_slice() == "1");
|
||||
assert!(format!("{}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:d}", -1i).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i8).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i16).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i32).as_slice() == "-1");
|
||||
assert!(format!("{:d}", -1i64).as_slice() == "-1");
|
||||
assert!(format!("{:t}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1i64).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i8).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i16).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i32).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1i64).as_slice() == "1");
|
||||
|
||||
assert!(format!("{}", 1u).as_slice() == "1");
|
||||
assert!(format!("{}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:u}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:t}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:x}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:X}", 1u64).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u8).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u16).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u32).as_slice() == "1");
|
||||
assert!(format!("{:o}", 1u64).as_slice() == "1");
|
||||
|
||||
// Test a larger number
|
||||
assert!(format!("{:t}", 55i).as_slice() == "110111");
|
||||
assert!(format!("{:o}", 55i).as_slice() == "67");
|
||||
assert!(format!("{:d}", 55i).as_slice() == "55");
|
||||
assert!(format!("{:x}", 55i).as_slice() == "37");
|
||||
assert!(format!("{:X}", 55i).as_slice() == "37");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_zero() {
|
||||
assert!(format!("{}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:d}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:t}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:o}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:x}", 0i).as_slice() == "0");
|
||||
assert!(format!("{:X}", 0i).as_slice() == "0");
|
||||
|
||||
assert!(format!("{}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:u}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:t}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:o}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:x}", 0u).as_slice() == "0");
|
||||
assert!(format!("{:X}", 0u).as_slice() == "0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_flags() {
|
||||
assert!(format!("{:3d}", 1i).as_slice() == " 1");
|
||||
assert!(format!("{:>3d}", 1i).as_slice() == " 1");
|
||||
assert!(format!("{:>+3d}", 1i).as_slice() == " +1");
|
||||
assert!(format!("{:<3d}", 1i).as_slice() == "1 ");
|
||||
assert!(format!("{:#d}", 1i).as_slice() == "1");
|
||||
assert!(format!("{:#x}", 10i).as_slice() == "0xa");
|
||||
assert!(format!("{:#X}", 10i).as_slice() == "0xA");
|
||||
assert!(format!("{:#5x}", 10i).as_slice() == " 0xa");
|
||||
assert!(format!("{:#o}", 10i).as_slice() == "0o12");
|
||||
assert!(format!("{:08x}", 10i).as_slice() == "0000000a");
|
||||
assert!(format!("{:8x}", 10i).as_slice() == " a");
|
||||
assert!(format!("{:<8x}", 10i).as_slice() == "a ");
|
||||
assert!(format!("{:>8x}", 10i).as_slice() == " a");
|
||||
assert!(format!("{:#08x}", 10i).as_slice() == "0x00000a");
|
||||
assert!(format!("{:08d}", -10i).as_slice() == "-0000010");
|
||||
assert!(format!("{:x}", -1u8).as_slice() == "ff");
|
||||
assert!(format!("{:X}", -1u8).as_slice() == "FF");
|
||||
assert!(format!("{:t}", -1u8).as_slice() == "11111111");
|
||||
assert!(format!("{:o}", -1u8).as_slice() == "377");
|
||||
assert!(format!("{:#x}", -1u8).as_slice() == "0xff");
|
||||
assert!(format!("{:#X}", -1u8).as_slice() == "0xFF");
|
||||
assert!(format!("{:#t}", -1u8).as_slice() == "0b11111111");
|
||||
assert!(format!("{:#o}", -1u8).as_slice() == "0o377");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_sign_padding() {
|
||||
assert!(format!("{:+5d}", 1i).as_slice() == " +1");
|
||||
assert!(format!("{:+5d}", -1i).as_slice() == " -1");
|
||||
assert!(format!("{:05d}", 1i).as_slice() == "00001");
|
||||
assert!(format!("{:05d}", -1i).as_slice() == "-0001");
|
||||
assert!(format!("{:+05d}", 1i).as_slice() == "+0001");
|
||||
assert!(format!("{:+05d}", -1i).as_slice() == "-0001");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_int_twos_complement() {
|
||||
use core::{i8, i16, i32, i64};
|
||||
assert!(format!("{}", i8::MIN).as_slice() == "-128");
|
||||
assert!(format!("{}", i16::MIN).as_slice() == "-32768");
|
||||
assert!(format!("{}", i32::MIN).as_slice() == "-2147483648");
|
||||
assert!(format!("{}", i64::MIN).as_slice() == "-9223372036854775808");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_radix() {
|
||||
assert!(format!("{:04}", radix(3i, 2)).as_slice() == "0011");
|
||||
assert!(format!("{}", radix(55i, 36)).as_slice() == "1j");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_radix_base_too_large() {
|
||||
let _ = radix(55i, 37);
|
||||
}
|
||||
|
||||
mod uint {
|
||||
use test::Bencher;
|
||||
use core::fmt::radix;
|
||||
use std::rand::{weak_rng, Rng};
|
||||
|
||||
#[bench]
|
||||
fn format_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:t}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:o}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:u}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:x}", rng.gen::<uint>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{}", radix(rng.gen::<uint>(), 36)); })
|
||||
}
|
||||
}
|
||||
|
||||
mod int {
|
||||
use test::Bencher;
|
||||
use core::fmt::radix;
|
||||
use std::rand::{weak_rng, Rng};
|
||||
|
||||
#[bench]
|
||||
fn format_bin(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:t}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_oct(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:o}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_dec(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:d}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_hex(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{:x}", rng.gen::<int>()); })
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn format_base_36(b: &mut Bencher) {
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| { format!("{}", radix(rng.gen::<int>(), 36)); })
|
||||
}
|
||||
}
|
835
src/libcoretest/iter.rs
Normal file
835
src/libcoretest/iter.rs
Normal file
|
@ -0,0 +1,835 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::iter::*;
|
||||
use core::iter::order::*;
|
||||
use core::uint;
|
||||
use core::cmp;
|
||||
use core::num;
|
||||
|
||||
#[test]
|
||||
fn test_lt() {
|
||||
let empty: [int, ..0] = [];
|
||||
let xs = [1i,2,3];
|
||||
let ys = [1i,2,0];
|
||||
|
||||
assert!(!lt(xs.iter(), ys.iter()));
|
||||
assert!(!le(xs.iter(), ys.iter()));
|
||||
assert!( gt(xs.iter(), ys.iter()));
|
||||
assert!( ge(xs.iter(), ys.iter()));
|
||||
|
||||
assert!( lt(ys.iter(), xs.iter()));
|
||||
assert!( le(ys.iter(), xs.iter()));
|
||||
assert!(!gt(ys.iter(), xs.iter()));
|
||||
assert!(!ge(ys.iter(), xs.iter()));
|
||||
|
||||
assert!( lt(empty.iter(), xs.iter()));
|
||||
assert!( le(empty.iter(), xs.iter()));
|
||||
assert!(!gt(empty.iter(), xs.iter()));
|
||||
assert!(!ge(empty.iter(), xs.iter()));
|
||||
|
||||
// Sequence with NaN
|
||||
let u = [1.0f64, 2.0];
|
||||
let v = [0.0f64/0.0, 3.0];
|
||||
|
||||
assert!(!lt(u.iter(), v.iter()));
|
||||
assert!(!le(u.iter(), v.iter()));
|
||||
assert!(!gt(u.iter(), v.iter()));
|
||||
assert!(!ge(u.iter(), v.iter()));
|
||||
|
||||
let a = [0.0f64/0.0];
|
||||
let b = [1.0f64];
|
||||
let c = [2.0f64];
|
||||
|
||||
assert!(lt(a.iter(), b.iter()) == (a[0] < b[0]));
|
||||
assert!(le(a.iter(), b.iter()) == (a[0] <= b[0]));
|
||||
assert!(gt(a.iter(), b.iter()) == (a[0] > b[0]));
|
||||
assert!(ge(a.iter(), b.iter()) == (a[0] >= b[0]));
|
||||
|
||||
assert!(lt(c.iter(), b.iter()) == (c[0] < b[0]));
|
||||
assert!(le(c.iter(), b.iter()) == (c[0] <= b[0]));
|
||||
assert!(gt(c.iter(), b.iter()) == (c[0] > b[0]));
|
||||
assert!(ge(c.iter(), b.iter()) == (c[0] >= b[0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_iter() {
|
||||
let xs = [1i,2,3,4];
|
||||
let ys = [4i,3,2,1];
|
||||
assert!(eq(xs.iter(), ys.iter().rev()));
|
||||
assert!(lt(xs.iter(), xs.iter().skip(2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_counter_from_iter() {
|
||||
let it = count(0i, 5).take(10);
|
||||
let xs: Vec<int> = FromIterator::from_iter(it);
|
||||
assert!(xs == vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_chain() {
|
||||
let xs = [0u, 1, 2, 3, 4, 5];
|
||||
let ys = [30u, 40, 50, 60];
|
||||
let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
|
||||
let mut it = xs.iter().chain(ys.iter());
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, expected[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
|
||||
let ys = count(30u, 10).take(4);
|
||||
let mut it = xs.iter().map(|&x| x).chain(ys);
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, expected[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_map() {
|
||||
let mut it = count(0u, 1u).take(10)
|
||||
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
|
||||
assert!(it.collect::<Vec<uint>>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_enumerate() {
|
||||
let xs = [0u, 1, 2, 3, 4, 5];
|
||||
let mut it = xs.iter().enumerate();
|
||||
for (i, &x) in it {
|
||||
assert_eq!(i, x);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_peekable() {
|
||||
let xs = vec![0u, 1, 2, 3, 4, 5];
|
||||
let mut it = xs.iter().map(|&x|x).peekable();
|
||||
assert_eq!(it.peek().unwrap(), &0);
|
||||
assert_eq!(it.next().unwrap(), 0);
|
||||
assert_eq!(it.next().unwrap(), 1);
|
||||
assert_eq!(it.next().unwrap(), 2);
|
||||
assert_eq!(it.peek().unwrap(), &3);
|
||||
assert_eq!(it.peek().unwrap(), &3);
|
||||
assert_eq!(it.next().unwrap(), 3);
|
||||
assert_eq!(it.next().unwrap(), 4);
|
||||
assert_eq!(it.peek().unwrap(), &5);
|
||||
assert_eq!(it.next().unwrap(), 5);
|
||||
assert!(it.peek().is_none());
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_take_while() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
|
||||
let ys = [0u, 1, 2, 3, 5, 13];
|
||||
let mut it = xs.iter().take_while(|&x| *x < 15u);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_skip_while() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
|
||||
let ys = [15, 16, 17, 19];
|
||||
let mut it = xs.iter().skip_while(|&x| *x < 15u);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_skip() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
|
||||
let ys = [13, 15, 16, 17, 19, 20, 30];
|
||||
let mut it = xs.iter().skip(5);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_take() {
|
||||
let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
|
||||
let ys = [0u, 1, 2, 3, 5];
|
||||
let mut it = xs.iter().take(5);
|
||||
let mut i = 0;
|
||||
for &x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_scan() {
|
||||
// test the type inference
|
||||
fn add(old: &mut int, new: &uint) -> Option<f64> {
|
||||
*old += *new as int;
|
||||
Some(*old as f64)
|
||||
}
|
||||
let xs = [0u, 1, 2, 3, 4];
|
||||
let ys = [0f64, 1.0, 3.0, 6.0, 10.0];
|
||||
|
||||
let mut it = xs.iter().scan(0, add);
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_flat_map() {
|
||||
let xs = [0u, 3, 6];
|
||||
let ys = [0u, 1, 2, 3, 4, 5, 6, 7, 8];
|
||||
let mut it = xs.iter().flat_map(|&x| count(x, 1).take(3));
|
||||
let mut i = 0;
|
||||
for x in it {
|
||||
assert_eq!(x, ys[i]);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, ys.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inspect() {
|
||||
let xs = [1u, 2, 3, 4];
|
||||
let mut n = 0;
|
||||
|
||||
let ys = xs.iter()
|
||||
.map(|&x| x)
|
||||
.inspect(|_| n += 1)
|
||||
.collect::<Vec<uint>>();
|
||||
|
||||
assert_eq!(n, xs.len());
|
||||
assert_eq!(xs.as_slice(), ys.as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unfoldr() {
|
||||
fn count(st: &mut uint) -> Option<uint> {
|
||||
if *st < 10 {
|
||||
let ret = Some(*st);
|
||||
*st += 1;
|
||||
ret
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mut it = Unfold::new(0, count);
|
||||
let mut i = 0;
|
||||
for counted in it {
|
||||
assert_eq!(counted, i);
|
||||
i += 1;
|
||||
}
|
||||
assert_eq!(i, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cycle() {
|
||||
let cycle_len = 3;
|
||||
let it = count(0u, 1).take(cycle_len).cycle();
|
||||
assert_eq!(it.size_hint(), (uint::MAX, None));
|
||||
for (i, x) in it.take(100).enumerate() {
|
||||
assert_eq!(i % cycle_len, x);
|
||||
}
|
||||
|
||||
let mut it = count(0u, 1).take(0).cycle();
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_nth() {
|
||||
let v = &[0i, 1, 2, 3, 4];
|
||||
for i in range(0u, v.len()) {
|
||||
assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_last() {
|
||||
let v = &[0i, 1, 2, 3, 4];
|
||||
assert_eq!(v.iter().last().unwrap(), &4);
|
||||
assert_eq!(v.slice(0, 1).iter().last().unwrap(), &0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_len() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().count(), 4);
|
||||
assert_eq!(v.slice(0, 10).iter().count(), 10);
|
||||
assert_eq!(v.slice(0, 0).iter().count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_sum() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).sum(), 6);
|
||||
assert_eq!(v.iter().map(|&x| x).sum(), 55);
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).sum(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_product() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).product(), 0);
|
||||
assert_eq!(v.slice(1, 5).iter().map(|&x| x).product(), 24);
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).product(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_max() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).max(), Some(3));
|
||||
assert_eq!(v.iter().map(|&x| x).max(), Some(10));
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).max(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_min() {
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
assert_eq!(v.slice(0, 4).iter().map(|&x| x).min(), Some(0));
|
||||
assert_eq!(v.iter().map(|&x| x).min(), Some(0));
|
||||
assert_eq!(v.slice(0, 0).iter().map(|&x| x).min(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_size_hint() {
|
||||
let c = count(0i, 1);
|
||||
let v = &[0i, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
let v2 = &[10i, 11, 12];
|
||||
let vi = v.iter();
|
||||
|
||||
assert_eq!(c.size_hint(), (uint::MAX, None));
|
||||
assert_eq!(vi.size_hint(), (10, Some(10)));
|
||||
|
||||
assert_eq!(c.take(5).size_hint(), (5, Some(5)));
|
||||
assert_eq!(c.skip(5).size_hint().val1(), None);
|
||||
assert_eq!(c.take_while(|_| false).size_hint(), (0, None));
|
||||
assert_eq!(c.skip_while(|_| false).size_hint(), (0, None));
|
||||
assert_eq!(c.enumerate().size_hint(), (uint::MAX, None));
|
||||
assert_eq!(c.chain(vi.map(|&i| i)).size_hint(), (uint::MAX, None));
|
||||
assert_eq!(c.zip(vi).size_hint(), (10, Some(10)));
|
||||
assert_eq!(c.scan(0i, |_,_| Some(0i)).size_hint(), (0, None));
|
||||
assert_eq!(c.filter(|_| false).size_hint(), (0, None));
|
||||
assert_eq!(c.map(|_| 0i).size_hint(), (uint::MAX, None));
|
||||
assert_eq!(c.filter_map(|_| Some(0i)).size_hint(), (0, None));
|
||||
|
||||
assert_eq!(vi.take(5).size_hint(), (5, Some(5)));
|
||||
assert_eq!(vi.take(12).size_hint(), (10, Some(10)));
|
||||
assert_eq!(vi.skip(3).size_hint(), (7, Some(7)));
|
||||
assert_eq!(vi.skip(12).size_hint(), (0, Some(0)));
|
||||
assert_eq!(vi.take_while(|_| false).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.skip_while(|_| false).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.enumerate().size_hint(), (10, Some(10)));
|
||||
assert_eq!(vi.chain(v2.iter()).size_hint(), (13, Some(13)));
|
||||
assert_eq!(vi.zip(v2.iter()).size_hint(), (3, Some(3)));
|
||||
assert_eq!(vi.scan(0i, |_,_| Some(0i)).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.filter(|_| false).size_hint(), (0, Some(10)));
|
||||
assert_eq!(vi.map(|i| i+1).size_hint(), (10, Some(10)));
|
||||
assert_eq!(vi.filter_map(|_| Some(0i)).size_hint(), (0, Some(10)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let a = vec![1i, 2, 3, 4, 5];
|
||||
let b: Vec<int> = a.iter().map(|&x| x).collect();
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
let v: Box<&[int]> = box &[1i, 2, 3, 4, 5];
|
||||
assert!(v.iter().all(|&x| x < 10));
|
||||
assert!(!v.iter().all(|&x| x % 2 == 0));
|
||||
assert!(!v.iter().all(|&x| x > 100));
|
||||
assert!(v.slice(0, 0).iter().all(|_| fail!()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_any() {
|
||||
let v: Box<&[int]> = box &[1i, 2, 3, 4, 5];
|
||||
assert!(v.iter().any(|&x| x < 10));
|
||||
assert!(v.iter().any(|&x| x % 2 == 0));
|
||||
assert!(!v.iter().any(|&x| x > 100));
|
||||
assert!(!v.slice(0, 0).iter().any(|_| fail!()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find() {
|
||||
let v: &[int] = &[1i, 3, 9, 27, 103, 14, 11];
|
||||
assert_eq!(*v.iter().find(|x| *x & 1 == 0).unwrap(), 14);
|
||||
assert_eq!(*v.iter().find(|x| *x % 3 == 0).unwrap(), 3);
|
||||
assert!(v.iter().find(|x| *x % 12 == 0).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position() {
|
||||
let v = &[1i, 3, 9, 27, 103, 14, 11];
|
||||
assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
|
||||
assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1);
|
||||
assert!(v.iter().position(|x| *x % 12 == 0).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count() {
|
||||
let xs = &[1i, 2, 2, 1, 5, 9, 0, 2];
|
||||
assert_eq!(xs.iter().filter(|x| **x == 2).count(), 3);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 5).count(), 1);
|
||||
assert_eq!(xs.iter().filter(|x| **x == 95).count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_by() {
|
||||
let xs: &[int] = &[-3i, 0, 1, 5, -10];
|
||||
assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_by() {
|
||||
let xs: &[int] = &[-3i, 0, 1, 5, -10];
|
||||
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_by_ref() {
|
||||
let mut xs = range(0i, 10);
|
||||
// sum the first five values
|
||||
let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
|
||||
assert_eq!(partial_sum, 10);
|
||||
assert_eq!(xs.next(), Some(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev() {
|
||||
let xs = [2i, 4, 6, 8, 10, 12, 14, 16];
|
||||
let mut it = xs.iter();
|
||||
it.next();
|
||||
it.next();
|
||||
assert!(it.rev().map(|&x| x).collect::<Vec<int>>() ==
|
||||
vec![16, 14, 12, 10, 8, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_map() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().map(|&x| x * -1);
|
||||
assert_eq!(it.next(), Some(-1));
|
||||
assert_eq!(it.next(), Some(-2));
|
||||
assert_eq!(it.next_back(), Some(-6));
|
||||
assert_eq!(it.next_back(), Some(-5));
|
||||
assert_eq!(it.next(), Some(-3));
|
||||
assert_eq!(it.next_back(), Some(-4));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_enumerate() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().map(|&x| x).enumerate();
|
||||
assert_eq!(it.next(), Some((0, 1)));
|
||||
assert_eq!(it.next(), Some((1, 2)));
|
||||
assert_eq!(it.next_back(), Some((5, 6)));
|
||||
assert_eq!(it.next_back(), Some((4, 5)));
|
||||
assert_eq!(it.next_back(), Some((3, 4)));
|
||||
assert_eq!(it.next_back(), Some((2, 3)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_zip() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let ys = [1i, 2, 3, 7];
|
||||
let a = xs.iter().map(|&x| x);
|
||||
let b = ys.iter().map(|&x| x);
|
||||
let mut it = a.zip(b);
|
||||
assert_eq!(it.next(), Some((1, 1)));
|
||||
assert_eq!(it.next(), Some((2, 2)));
|
||||
assert_eq!(it.next_back(), Some((4, 7)));
|
||||
assert_eq!(it.next_back(), Some((3, 3)));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter(|&x| *x & 1 == 0);
|
||||
assert_eq!(it.next_back().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &4);
|
||||
assert_eq!(it.next().unwrap(), &2);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter_map() {
|
||||
let xs = [1i, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
|
||||
assert_eq!(it.next_back().unwrap(), 12);
|
||||
assert_eq!(it.next_back().unwrap(), 8);
|
||||
assert_eq!(it.next().unwrap(), 4);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_chain() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let ys = [7i, 9, 11];
|
||||
let mut it = xs.iter().chain(ys.iter()).rev();
|
||||
assert_eq!(it.next().unwrap(), &11)
|
||||
assert_eq!(it.next().unwrap(), &9)
|
||||
assert_eq!(it.next_back().unwrap(), &1)
|
||||
assert_eq!(it.next_back().unwrap(), &2)
|
||||
assert_eq!(it.next_back().unwrap(), &3)
|
||||
assert_eq!(it.next_back().unwrap(), &4)
|
||||
assert_eq!(it.next_back().unwrap(), &5)
|
||||
assert_eq!(it.next_back().unwrap(), &7)
|
||||
assert_eq!(it.next_back(), None)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rposition() {
|
||||
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
||||
fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
|
||||
let v = [(0i, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
||||
|
||||
assert_eq!(v.iter().rposition(f), Some(3u));
|
||||
assert!(v.iter().rposition(g).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_rposition_fail() {
|
||||
use std::gc::GC;
|
||||
let v = [(box 0i, box(GC) 0i), (box 0i, box(GC) 0i),
|
||||
(box 0i, box(GC) 0i), (box 0i, box(GC) 0i)];
|
||||
let mut i = 0i;
|
||||
v.iter().rposition(|_elt| {
|
||||
if i == 2 {
|
||||
fail!()
|
||||
}
|
||||
i += 1;
|
||||
false
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
fn check_randacc_iter<A: PartialEq, T: Clone + RandomAccessIterator<A>>(a: T, len: uint)
|
||||
{
|
||||
let mut b = a.clone();
|
||||
assert_eq!(len, b.indexable());
|
||||
let mut n = 0u;
|
||||
for (i, elt) in a.enumerate() {
|
||||
assert!(Some(elt) == b.idx(i));
|
||||
n += 1;
|
||||
}
|
||||
assert_eq!(n, len);
|
||||
assert!(None == b.idx(n));
|
||||
// call recursively to check after picking off an element
|
||||
if len > 0 {
|
||||
b.next();
|
||||
check_randacc_iter(b, len-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_flat_map() {
|
||||
let u = [0u,1];
|
||||
let v = [5u,6,7,8];
|
||||
let mut it = u.iter().flat_map(|x| v.slice(*x, v.len()).iter());
|
||||
assert_eq!(it.next_back().unwrap(), &8);
|
||||
assert_eq!(it.next().unwrap(), &5);
|
||||
assert_eq!(it.next_back().unwrap(), &7);
|
||||
assert_eq!(it.next_back().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &8);
|
||||
assert_eq!(it.next().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &7);
|
||||
assert_eq!(it.next_back(), None);
|
||||
assert_eq!(it.next(), None);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_chain() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let ys = [7i, 9, 11];
|
||||
let mut it = xs.iter().chain(ys.iter());
|
||||
assert_eq!(it.idx(0).unwrap(), &1);
|
||||
assert_eq!(it.idx(5).unwrap(), &7);
|
||||
assert_eq!(it.idx(7).unwrap(), &11);
|
||||
assert!(it.idx(8).is_none());
|
||||
|
||||
it.next();
|
||||
it.next();
|
||||
it.next_back();
|
||||
|
||||
assert_eq!(it.idx(0).unwrap(), &3);
|
||||
assert_eq!(it.idx(4).unwrap(), &9);
|
||||
assert!(it.idx(6).is_none());
|
||||
|
||||
check_randacc_iter(it, xs.len() + ys.len() - 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_enumerate() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
check_randacc_iter(xs.iter().enumerate(), xs.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_rev() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
check_randacc_iter(xs.iter().rev(), xs.len());
|
||||
let mut it = xs.iter().rev();
|
||||
it.next();
|
||||
it.next_back();
|
||||
it.next();
|
||||
check_randacc_iter(it, xs.len() - 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_zip() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let ys = [7i, 9, 11];
|
||||
check_randacc_iter(xs.iter().zip(ys.iter()), cmp::min(xs.len(), ys.len()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_take() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let empty: &[int] = [];
|
||||
check_randacc_iter(xs.iter().take(3), 3);
|
||||
check_randacc_iter(xs.iter().take(20), xs.len());
|
||||
check_randacc_iter(xs.iter().take(0), 0);
|
||||
check_randacc_iter(empty.iter().take(2), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_skip() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let empty: &[int] = [];
|
||||
check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
|
||||
check_randacc_iter(empty.iter().skip(2), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_inspect() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
|
||||
// test .map and .inspect that don't implement Clone
|
||||
let mut it = xs.iter().inspect(|_| {});
|
||||
assert_eq!(xs.len(), it.indexable());
|
||||
for (i, elt) in xs.iter().enumerate() {
|
||||
assert_eq!(Some(elt), it.idx(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_map() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
|
||||
let mut it = xs.iter().map(|x| *x);
|
||||
assert_eq!(xs.len(), it.indexable());
|
||||
for (i, elt) in xs.iter().enumerate() {
|
||||
assert_eq!(Some(*elt), it.idx(i));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_access_cycle() {
|
||||
let xs = [1i, 2, 3, 4, 5];
|
||||
let empty: &[int] = [];
|
||||
check_randacc_iter(xs.iter().cycle().take(27), 27);
|
||||
check_randacc_iter(empty.iter().cycle(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_range() {
|
||||
assert!(range(11i, 14).rev().collect::<Vec<int>>() == vec![13i, 12, 11]);
|
||||
for _ in range(10i, 0).rev() {
|
||||
fail!("unreachable");
|
||||
}
|
||||
|
||||
assert!(range(11u, 14).rev().collect::<Vec<uint>>() == vec![13u, 12, 11]);
|
||||
for _ in range(10u, 0).rev() {
|
||||
fail!("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range() {
|
||||
/// A mock type to check Range when ToPrimitive returns None
|
||||
struct Foo;
|
||||
|
||||
impl ToPrimitive for Foo {
|
||||
fn to_i64(&self) -> Option<i64> { None }
|
||||
fn to_u64(&self) -> Option<u64> { None }
|
||||
}
|
||||
|
||||
impl Add<Foo, Foo> for Foo {
|
||||
fn add(&self, _: &Foo) -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Foo {
|
||||
fn eq(&self, _: &Foo) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Foo {
|
||||
fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Foo {
|
||||
fn clone(&self) -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Foo, Foo> for Foo {
|
||||
fn mul(&self, _: &Foo) -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl num::One for Foo {
|
||||
fn one() -> Foo {
|
||||
Foo
|
||||
}
|
||||
}
|
||||
|
||||
assert!(range(0i, 5).collect::<Vec<int>>() == vec![0i, 1, 2, 3, 4]);
|
||||
assert!(range(-10i, -1).collect::<Vec<int>>() ==
|
||||
vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
|
||||
assert!(range(0i, 5).rev().collect::<Vec<int>>() == vec![4, 3, 2, 1, 0]);
|
||||
assert_eq!(range(200i, -5).count(), 0);
|
||||
assert_eq!(range(200i, -5).rev().count(), 0);
|
||||
assert_eq!(range(200i, 200).count(), 0);
|
||||
assert_eq!(range(200i, 200).rev().count(), 0);
|
||||
|
||||
assert_eq!(range(0i, 100).size_hint(), (100, Some(100)));
|
||||
// this test is only meaningful when sizeof uint < sizeof u64
|
||||
assert_eq!(range(uint::MAX - 1, uint::MAX).size_hint(), (1, Some(1)));
|
||||
assert_eq!(range(-10i, -1).size_hint(), (9, Some(9)));
|
||||
assert_eq!(range(Foo, Foo).size_hint(), (0, None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_inclusive() {
|
||||
assert!(range_inclusive(0i, 5).collect::<Vec<int>>() ==
|
||||
vec![0i, 1, 2, 3, 4, 5]);
|
||||
assert!(range_inclusive(0i, 5).rev().collect::<Vec<int>>() ==
|
||||
vec![5i, 4, 3, 2, 1, 0]);
|
||||
assert_eq!(range_inclusive(200i, -5).count(), 0);
|
||||
assert_eq!(range_inclusive(200i, -5).rev().count(), 0);
|
||||
assert!(range_inclusive(200i, 200).collect::<Vec<int>>() == vec![200]);
|
||||
assert!(range_inclusive(200i, 200).rev().collect::<Vec<int>>() == vec![200]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_step() {
|
||||
assert!(range_step(0i, 20, 5).collect::<Vec<int>>() ==
|
||||
vec![0, 5, 10, 15]);
|
||||
assert!(range_step(20i, 0, -5).collect::<Vec<int>>() ==
|
||||
vec![20, 15, 10, 5]);
|
||||
assert!(range_step(20i, 0, -6).collect::<Vec<int>>() ==
|
||||
vec![20, 14, 8, 2]);
|
||||
assert!(range_step(200u8, 255, 50).collect::<Vec<u8>>() ==
|
||||
vec![200u8, 250]);
|
||||
assert!(range_step(200i, -5, 1).collect::<Vec<int>>() == vec![]);
|
||||
assert!(range_step(200i, 200, 1).collect::<Vec<int>>() == vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_step_inclusive() {
|
||||
assert!(range_step_inclusive(0i, 20, 5).collect::<Vec<int>>() ==
|
||||
vec![0, 5, 10, 15, 20]);
|
||||
assert!(range_step_inclusive(20i, 0, -5).collect::<Vec<int>>() ==
|
||||
vec![20, 15, 10, 5, 0]);
|
||||
assert!(range_step_inclusive(20i, 0, -6).collect::<Vec<int>>() ==
|
||||
vec![20, 14, 8, 2]);
|
||||
assert!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>() ==
|
||||
vec![200u8, 250]);
|
||||
assert!(range_step_inclusive(200i, -5, 1).collect::<Vec<int>>() ==
|
||||
vec![]);
|
||||
assert!(range_step_inclusive(200i, 200, 1).collect::<Vec<int>>() ==
|
||||
vec![200]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse() {
|
||||
let mut ys = [1i, 2, 3, 4, 5];
|
||||
ys.mut_iter().reverse_();
|
||||
assert!(ys == [5, 4, 3, 2, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peekable_is_empty() {
|
||||
let a = [1i];
|
||||
let mut it = a.iter().peekable();
|
||||
assert!( !it.is_empty() );
|
||||
it.next();
|
||||
assert!( it.is_empty() );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max() {
|
||||
let v: [int, ..0] = [];
|
||||
assert_eq!(v.iter().min_max(), NoElements);
|
||||
|
||||
let v = [1i];
|
||||
assert!(v.iter().min_max() == OneElement(&1));
|
||||
|
||||
let v = [1i, 2, 3, 4, 5];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &5));
|
||||
|
||||
let v = [1i, 2, 3, 4, 5, 6];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &6));
|
||||
|
||||
let v = [1i, 1, 1, 1];
|
||||
assert!(v.iter().min_max() == MinMax(&1, &1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_max_result() {
|
||||
let r: MinMaxResult<int> = NoElements;
|
||||
assert_eq!(r.into_option(), None)
|
||||
|
||||
let r = OneElement(1i);
|
||||
assert_eq!(r.into_option(), Some((1,1)));
|
||||
|
||||
let r = MinMax(1i,2);
|
||||
assert_eq!(r.into_option(), Some((1,2)));
|
||||
}
|
31
src/libcoretest/lib.rs
Normal file
31
src/libcoretest/lib.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![feature(globs, unsafe_destructor, macro_rules)]
|
||||
|
||||
extern crate core;
|
||||
extern crate test;
|
||||
extern crate libc;
|
||||
|
||||
mod any;
|
||||
mod atomics;
|
||||
mod cell;
|
||||
mod char;
|
||||
mod cmp;
|
||||
mod finally;
|
||||
mod fmt;
|
||||
mod iter;
|
||||
mod mem;
|
||||
mod num;
|
||||
mod ops;
|
||||
mod option;
|
||||
mod ptr;
|
||||
mod raw;
|
||||
mod result;
|
||||
mod tuple;
|
173
src/libcoretest/mem.rs
Normal file
173
src/libcoretest/mem.rs
Normal file
|
@ -0,0 +1,173 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
use core::mem::*;
|
||||
use test::Bencher;
|
||||
|
||||
#[test]
|
||||
fn size_of_basic() {
|
||||
assert_eq!(size_of::<u8>(), 1u);
|
||||
assert_eq!(size_of::<u16>(), 2u);
|
||||
assert_eq!(size_of::<u32>(), 4u);
|
||||
assert_eq!(size_of::<u64>(), 8u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
fn size_of_32() {
|
||||
assert_eq!(size_of::<uint>(), 4u);
|
||||
assert_eq!(size_of::<*const uint>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn size_of_64() {
|
||||
assert_eq!(size_of::<uint>(), 8u);
|
||||
assert_eq!(size_of::<*const uint>(), 8u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn size_of_val_basic() {
|
||||
assert_eq!(size_of_val(&1u8), 1);
|
||||
assert_eq!(size_of_val(&1u16), 2);
|
||||
assert_eq!(size_of_val(&1u32), 4);
|
||||
assert_eq!(size_of_val(&1u64), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn align_of_basic() {
|
||||
assert_eq!(align_of::<u8>(), 1u);
|
||||
assert_eq!(align_of::<u16>(), 2u);
|
||||
assert_eq!(align_of::<u32>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
fn align_of_32() {
|
||||
assert_eq!(align_of::<uint>(), 4u);
|
||||
assert_eq!(align_of::<*const uint>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn align_of_64() {
|
||||
assert_eq!(align_of::<uint>(), 8u);
|
||||
assert_eq!(align_of::<*const uint>(), 8u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn align_of_val_basic() {
|
||||
assert_eq!(align_of_val(&1u8), 1u);
|
||||
assert_eq!(align_of_val(&1u16), 2u);
|
||||
assert_eq!(align_of_val(&1u32), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_swap() {
|
||||
let mut x = 31337i;
|
||||
let mut y = 42i;
|
||||
swap(&mut x, &mut y);
|
||||
assert_eq!(x, 42);
|
||||
assert_eq!(y, 31337);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_replace() {
|
||||
let mut x = Some("test".to_string());
|
||||
let y = replace(&mut x, None);
|
||||
assert!(x.is_none());
|
||||
assert!(y.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transmute_copy() {
|
||||
assert_eq!(1u, unsafe { transmute_copy(&1i) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transmute() {
|
||||
trait Foo {}
|
||||
impl Foo for int {}
|
||||
|
||||
let a = box 100i as Box<Foo>;
|
||||
unsafe {
|
||||
let x: ::core::raw::TraitObject = transmute(a);
|
||||
assert!(*(x.data as *const int) == 100);
|
||||
let _x: Box<Foo> = transmute(x);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
assert!(Vec::from_slice([76u8]) == transmute("L".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME #13642 (these benchmarks should be in another place)
|
||||
/// Completely miscellaneous language-construct benchmarks.
|
||||
// Static/dynamic method dispatch
|
||||
|
||||
struct Struct {
|
||||
field: int
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn method(&self) -> int;
|
||||
}
|
||||
|
||||
impl Trait for Struct {
|
||||
fn method(&self) -> int {
|
||||
self.field
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn trait_vtable_method_call(b: &mut Bencher) {
|
||||
let s = Struct { field: 10 };
|
||||
let t = &s as &Trait;
|
||||
b.iter(|| {
|
||||
t.method()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn trait_static_method_call(b: &mut Bencher) {
|
||||
let s = Struct { field: 10 };
|
||||
b.iter(|| {
|
||||
s.method()
|
||||
});
|
||||
}
|
||||
|
||||
// Overhead of various match forms
|
||||
|
||||
#[bench]
|
||||
fn match_option_some(b: &mut Bencher) {
|
||||
let x = Some(10i);
|
||||
b.iter(|| {
|
||||
match x {
|
||||
Some(y) => y,
|
||||
None => 11
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn match_vec_pattern(b: &mut Bencher) {
|
||||
let x = [1i,2,3,4,5,6];
|
||||
b.iter(|| {
|
||||
match x {
|
||||
[1,2,3,..] => 10i,
|
||||
_ => 11i,
|
||||
}
|
||||
});
|
||||
}
|
11
src/libcoretest/num/i16.rs
Normal file
11
src/libcoretest/num/i16.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
int_module!(i16, i16)
|
11
src/libcoretest/num/i32.rs
Normal file
11
src/libcoretest/num/i32.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
int_module!(i32, i32)
|
11
src/libcoretest/num/i64.rs
Normal file
11
src/libcoretest/num/i64.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
int_module!(i64, i64)
|
11
src/libcoretest/num/i8.rs
Normal file
11
src/libcoretest/num/i8.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
int_module!(i8, i8)
|
11
src/libcoretest/num/int.rs
Normal file
11
src/libcoretest/num/int.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
int_module!(int, int)
|
160
src/libcoretest/num/int_macros.rs
Normal file
160
src/libcoretest/num/int_macros.rs
Normal file
|
@ -0,0 +1,160 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![macro_escape]
|
||||
|
||||
macro_rules! int_module (($T:ty, $T_i:ident) => (
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::$T_i::*;
|
||||
use core::int;
|
||||
use num;
|
||||
use core::num::CheckedDiv;
|
||||
|
||||
#[test]
|
||||
fn test_overflows() {
|
||||
assert!(MAX > 0);
|
||||
assert!(MIN <= 0);
|
||||
assert!(MIN + MAX + 1 == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10 as $T, 2 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_abs() {
|
||||
assert!((1 as $T).abs() == 1 as $T);
|
||||
assert!((0 as $T).abs() == 0 as $T);
|
||||
assert!((-1 as $T).abs() == 1 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_abs_sub() {
|
||||
assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
|
||||
assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
|
||||
assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T);
|
||||
assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signum() {
|
||||
assert!((1 as $T).signum() == 1 as $T);
|
||||
assert!((0 as $T).signum() == 0 as $T);
|
||||
assert!((-0 as $T).signum() == 0 as $T);
|
||||
assert!((-1 as $T).signum() == -1 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_positive() {
|
||||
assert!((1 as $T).is_positive());
|
||||
assert!(!(0 as $T).is_positive());
|
||||
assert!(!(-0 as $T).is_positive());
|
||||
assert!(!(-1 as $T).is_positive());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_negative() {
|
||||
assert!(!(1 as $T).is_negative());
|
||||
assert!(!(0 as $T).is_negative());
|
||||
assert!(!(-0 as $T).is_negative());
|
||||
assert!((-1 as $T).is_negative());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwise_operators() {
|
||||
assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
|
||||
assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
|
||||
assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
|
||||
assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
|
||||
assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
|
||||
assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
|
||||
}
|
||||
|
||||
static A: $T = 0b0101100;
|
||||
static B: $T = 0b0100001;
|
||||
static C: $T = 0b1111001;
|
||||
|
||||
static _0: $T = 0;
|
||||
static _1: $T = !0;
|
||||
|
||||
#[test]
|
||||
fn test_count_ones() {
|
||||
assert!(A.count_ones() == 3);
|
||||
assert!(B.count_ones() == 2);
|
||||
assert!(C.count_ones() == 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_zeros() {
|
||||
assert!(A.count_zeros() == BITS as $T - 3);
|
||||
assert!(B.count_zeros() == BITS as $T - 2);
|
||||
assert!(C.count_zeros() == BITS as $T - 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate() {
|
||||
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
|
||||
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
|
||||
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
|
||||
|
||||
// Rotating these should make no difference
|
||||
//
|
||||
// We test using 124 bits because to ensure that overlong bit shifts do
|
||||
// not cause undefined behaviour. See #10183.
|
||||
assert_eq!(_0.rotate_left(124), _0);
|
||||
assert_eq!(_1.rotate_left(124), _1);
|
||||
assert_eq!(_0.rotate_right(124), _0);
|
||||
assert_eq!(_1.rotate_right(124), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_swap_bytes() {
|
||||
assert_eq!(A.swap_bytes().swap_bytes(), A);
|
||||
assert_eq!(B.swap_bytes().swap_bytes(), B);
|
||||
assert_eq!(C.swap_bytes().swap_bytes(), C);
|
||||
|
||||
// Swapping these should make no difference
|
||||
assert_eq!(_0.swap_bytes(), _0);
|
||||
assert_eq!(_1.swap_bytes(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_le() {
|
||||
assert_eq!(Int::from_le(A.to_le()), A);
|
||||
assert_eq!(Int::from_le(B.to_le()), B);
|
||||
assert_eq!(Int::from_le(C.to_le()), C);
|
||||
assert_eq!(Int::from_le(_0), _0);
|
||||
assert_eq!(Int::from_le(_1), _1);
|
||||
assert_eq!(_0.to_le(), _0);
|
||||
assert_eq!(_1.to_le(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_be() {
|
||||
assert_eq!(Int::from_be(A.to_be()), A);
|
||||
assert_eq!(Int::from_be(B.to_be()), B);
|
||||
assert_eq!(Int::from_be(C.to_be()), C);
|
||||
assert_eq!(Int::from_be(_0), _0);
|
||||
assert_eq!(Int::from_be(_1), _1);
|
||||
assert_eq!(_0.to_be(), _0);
|
||||
assert_eq!(_1.to_be(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signed_checked_div() {
|
||||
assert!(10i.checked_div(&2) == Some(5));
|
||||
assert!(5i.checked_div(&0) == None);
|
||||
assert!(int::MIN.checked_div(&-1) == None);
|
||||
}
|
||||
}
|
||||
|
||||
))
|
39
src/libcoretest/num/mod.rs
Normal file
39
src/libcoretest/num/mod.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::num::cast;
|
||||
|
||||
mod int_macros;
|
||||
mod i8;
|
||||
mod i16;
|
||||
mod i32;
|
||||
mod i64;
|
||||
mod int;
|
||||
mod uint_macros;
|
||||
mod u8;
|
||||
mod u16;
|
||||
mod u32;
|
||||
mod u64;
|
||||
mod uint;
|
||||
|
||||
/// Helper function for testing numeric operations
|
||||
pub fn test_num<T:Num + NumCast + ::std::fmt::Show>(ten: T, two: T) {
|
||||
assert_eq!(ten.add(&two), cast(12i).unwrap());
|
||||
assert_eq!(ten.sub(&two), cast(8i).unwrap());
|
||||
assert_eq!(ten.mul(&two), cast(20i).unwrap());
|
||||
assert_eq!(ten.div(&two), cast(5i).unwrap());
|
||||
assert_eq!(ten.rem(&two), cast(0i).unwrap());
|
||||
|
||||
assert_eq!(ten.add(&two), ten + two);
|
||||
assert_eq!(ten.sub(&two), ten - two);
|
||||
assert_eq!(ten.mul(&two), ten * two);
|
||||
assert_eq!(ten.div(&two), ten / two);
|
||||
assert_eq!(ten.rem(&two), ten % two);
|
||||
}
|
11
src/libcoretest/num/u16.rs
Normal file
11
src/libcoretest/num/u16.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
uint_module!(u16, u16)
|
11
src/libcoretest/num/u32.rs
Normal file
11
src/libcoretest/num/u32.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
uint_module!(u32, u32)
|
11
src/libcoretest/num/u64.rs
Normal file
11
src/libcoretest/num/u64.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
uint_module!(u64, u64)
|
11
src/libcoretest/num/u8.rs
Normal file
11
src/libcoretest/num/u8.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
uint_module!(u8, u8)
|
11
src/libcoretest/num/uint.rs
Normal file
11
src/libcoretest/num/uint.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
uint_module!(uint, uint)
|
118
src/libcoretest/num/uint_macros.rs
Normal file
118
src/libcoretest/num/uint_macros.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![macro_escape]
|
||||
|
||||
macro_rules! uint_module (($T:ty, $T_i:ident) => (
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::$T_i::*;
|
||||
use num;
|
||||
use core::num::CheckedDiv;
|
||||
|
||||
#[test]
|
||||
fn test_overflows() {
|
||||
assert!(MAX > 0);
|
||||
assert!(MIN <= 0);
|
||||
assert!(MIN + MAX + 1 == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num() {
|
||||
num::test_num(10 as $T, 2 as $T);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitwise_operators() {
|
||||
assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
|
||||
assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
|
||||
assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
|
||||
assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
|
||||
assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
|
||||
assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
|
||||
}
|
||||
|
||||
static A: $T = 0b0101100;
|
||||
static B: $T = 0b0100001;
|
||||
static C: $T = 0b1111001;
|
||||
|
||||
static _0: $T = 0;
|
||||
static _1: $T = !0;
|
||||
|
||||
#[test]
|
||||
fn test_count_ones() {
|
||||
assert!(A.count_ones() == 3);
|
||||
assert!(B.count_ones() == 2);
|
||||
assert!(C.count_ones() == 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_zeros() {
|
||||
assert!(A.count_zeros() == BITS as $T - 3);
|
||||
assert!(B.count_zeros() == BITS as $T - 2);
|
||||
assert!(C.count_zeros() == BITS as $T - 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate() {
|
||||
assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
|
||||
assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
|
||||
assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
|
||||
|
||||
// Rotating these should make no difference
|
||||
//
|
||||
// We test using 124 bits because to ensure that overlong bit shifts do
|
||||
// not cause undefined behaviour. See #10183.
|
||||
assert_eq!(_0.rotate_left(124), _0);
|
||||
assert_eq!(_1.rotate_left(124), _1);
|
||||
assert_eq!(_0.rotate_right(124), _0);
|
||||
assert_eq!(_1.rotate_right(124), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_swap_bytes() {
|
||||
assert_eq!(A.swap_bytes().swap_bytes(), A);
|
||||
assert_eq!(B.swap_bytes().swap_bytes(), B);
|
||||
assert_eq!(C.swap_bytes().swap_bytes(), C);
|
||||
|
||||
// Swapping these should make no difference
|
||||
assert_eq!(_0.swap_bytes(), _0);
|
||||
assert_eq!(_1.swap_bytes(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_le() {
|
||||
assert_eq!(Int::from_le(A.to_le()), A);
|
||||
assert_eq!(Int::from_le(B.to_le()), B);
|
||||
assert_eq!(Int::from_le(C.to_le()), C);
|
||||
assert_eq!(Int::from_le(_0), _0);
|
||||
assert_eq!(Int::from_le(_1), _1);
|
||||
assert_eq!(_0.to_le(), _0);
|
||||
assert_eq!(_1.to_le(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_be() {
|
||||
assert_eq!(Int::from_be(A.to_be()), A);
|
||||
assert_eq!(Int::from_be(B.to_be()), B);
|
||||
assert_eq!(Int::from_be(C.to_be()), C);
|
||||
assert_eq!(Int::from_be(_0), _0);
|
||||
assert_eq!(Int::from_be(_1), _1);
|
||||
assert_eq!(_0.to_be(), _0);
|
||||
assert_eq!(_1.to_be(), _1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsigned_checked_div() {
|
||||
assert!(10u.checked_div(&2) == Some(5));
|
||||
assert!(5u.checked_div(&0) == None);
|
||||
}
|
||||
}
|
||||
))
|
29
src/libcoretest/ops.rs
Normal file
29
src/libcoretest/ops.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
// Overhead of dtors
|
||||
|
||||
struct HasDtor {
|
||||
_x: int
|
||||
}
|
||||
|
||||
impl Drop for HasDtor {
|
||||
fn drop(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn alloc_obj_with_dtor(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
HasDtor { _x : 10 };
|
||||
})
|
||||
}
|
278
src/libcoretest/option.rs
Normal file
278
src/libcoretest/option.rs
Normal file
|
@ -0,0 +1,278 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::option::*;
|
||||
use core::kinds::marker;
|
||||
use core::mem;
|
||||
|
||||
#[test]
|
||||
fn test_get_ptr() {
|
||||
unsafe {
|
||||
let x = box 0i;
|
||||
let addr_x: *const int = mem::transmute(&*x);
|
||||
let opt = Some(x);
|
||||
let y = opt.unwrap();
|
||||
let addr_y: *const int = mem::transmute(&*y);
|
||||
assert_eq!(addr_x, addr_y);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_str() {
|
||||
let x = "test".to_string();
|
||||
let addr_x = x.as_slice().as_ptr();
|
||||
let opt = Some(x);
|
||||
let y = opt.unwrap();
|
||||
let addr_y = y.as_slice().as_ptr();
|
||||
assert_eq!(addr_x, addr_y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_resource() {
|
||||
use std::rc::Rc;
|
||||
use core::cell::RefCell;
|
||||
|
||||
struct R {
|
||||
i: Rc<RefCell<int>>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl Drop for R {
|
||||
fn drop(&mut self) {
|
||||
let ii = &*self.i;
|
||||
let i = *ii.borrow();
|
||||
*ii.borrow_mut() = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn r(i: Rc<RefCell<int>>) -> R {
|
||||
R {
|
||||
i: i
|
||||
}
|
||||
}
|
||||
|
||||
let i = Rc::new(RefCell::new(0i));
|
||||
{
|
||||
let x = r(i.clone());
|
||||
let opt = Some(x);
|
||||
let _y = opt.unwrap();
|
||||
}
|
||||
assert_eq!(*i.borrow(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_dance() {
|
||||
let x = Some(());
|
||||
let mut y = Some(5i);
|
||||
let mut y2 = 0;
|
||||
for _x in x.iter() {
|
||||
y2 = y.take_unwrap();
|
||||
}
|
||||
assert_eq!(y2, 5);
|
||||
assert!(y.is_none());
|
||||
}
|
||||
|
||||
#[test] #[should_fail]
|
||||
fn test_option_too_much_dance() {
|
||||
let mut y = Some(marker::NoCopy);
|
||||
let _y2 = y.take_unwrap();
|
||||
let _y3 = y.take_unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
let x: Option<int> = Some(1i);
|
||||
assert_eq!(x.and(Some(2i)), Some(2));
|
||||
assert_eq!(x.and(None::<int>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.and(Some(2i)), None);
|
||||
assert_eq!(x.and(None::<int>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and_then() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), None);
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.or(Some(2)), Some(1));
|
||||
assert_eq!(x.or(None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.or(Some(2)), Some(2));
|
||||
assert_eq!(x.or(None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(1));
|
||||
assert_eq!(x.or_else(|| None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(2));
|
||||
assert_eq!(x.or_else(|| None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_while_some() {
|
||||
let mut i = 0i;
|
||||
Some(10i).while_some(|j| {
|
||||
i += 1;
|
||||
if j > 0 {
|
||||
Some(j-1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
assert_eq!(i, 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap() {
|
||||
assert_eq!(Some(1i).unwrap(), 1);
|
||||
let s = Some("hello".to_string()).unwrap();
|
||||
assert_eq!(s.as_slice(), "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_unwrap_fail1() {
|
||||
let x: Option<int> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_unwrap_fail2() {
|
||||
let x: Option<String> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.unwrap_or(2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.unwrap_or(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filtered() {
|
||||
let some_stuff = Some(42i);
|
||||
let modified_stuff = some_stuff.filtered(|&x| {x < 10});
|
||||
assert_eq!(some_stuff.unwrap(), 42);
|
||||
assert!(modified_stuff.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let val = 5i;
|
||||
|
||||
let x = Some(val);
|
||||
let mut it = x.iter();
|
||||
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
assert_eq!(it.next(), Some(&val));
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_iter() {
|
||||
let val = 5i;
|
||||
let new_val = 11i;
|
||||
|
||||
let mut x = Some(val);
|
||||
{
|
||||
let mut it = x.mut_iter();
|
||||
|
||||
assert_eq!(it.size_hint(), (1, Some(1)));
|
||||
|
||||
match it.next() {
|
||||
Some(interior) => {
|
||||
assert_eq!(*interior, val);
|
||||
*interior = new_val;
|
||||
}
|
||||
None => assert!(false),
|
||||
}
|
||||
|
||||
assert_eq!(it.size_hint(), (0, Some(0)));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
assert_eq!(x, Some(new_val));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let small = Some(1.0f64);
|
||||
let big = Some(5.0f64);
|
||||
let nan = Some(0.0f64/0.0);
|
||||
assert!(!(nan < big));
|
||||
assert!(!(nan > big));
|
||||
assert!(small < big);
|
||||
assert!(None < big);
|
||||
assert!(big > None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutate() {
|
||||
let mut x = Some(3i);
|
||||
assert!(x.mutate(|i| i+1));
|
||||
assert_eq!(x, Some(4i));
|
||||
assert!(x.mutate_or_set(0, |i| i+1));
|
||||
assert_eq!(x, Some(5i));
|
||||
x = None;
|
||||
assert!(!x.mutate(|i| i+1));
|
||||
assert_eq!(x, None);
|
||||
assert!(!x.mutate_or_set(0i, |i| i+1));
|
||||
assert_eq!(x, Some(0i));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let v: Option<Vec<int>> = collect(range(0i, 0)
|
||||
.map(|_| Some(0i)));
|
||||
assert!(v == Some(vec![]));
|
||||
|
||||
let v: Option<Vec<int>> = collect(range(0i, 3)
|
||||
.map(|x| Some(x)));
|
||||
assert!(v == Some(vec![0, 1, 2]));
|
||||
|
||||
let v: Option<Vec<int>> = collect(range(0i, 3)
|
||||
.map(|x| if x > 1 { None } else { Some(x) }));
|
||||
assert!(v == None);
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions = [|| Some(()), || None, || fail!()];
|
||||
|
||||
let v: Option<Vec<()>> = collect(functions.mut_iter().map(|f| (*f)()));
|
||||
|
||||
assert!(v == None);
|
||||
}
|
255
src/libcoretest/ptr.rs
Normal file
255
src/libcoretest/ptr.rs
Normal file
|
@ -0,0 +1,255 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![allow(deprecated)]
|
||||
use core::ptr::*;
|
||||
use libc::c_char;
|
||||
use core::mem;
|
||||
use std::str;
|
||||
use libc;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
unsafe {
|
||||
struct Pair {
|
||||
fst: int,
|
||||
snd: int
|
||||
};
|
||||
let mut p = Pair {fst: 10, snd: 20};
|
||||
let pptr: *mut Pair = &mut p;
|
||||
let iptr: *mut int = mem::transmute(pptr);
|
||||
assert_eq!(*iptr, 10);
|
||||
*iptr = 30;
|
||||
assert_eq!(*iptr, 30);
|
||||
assert_eq!(p.fst, 30);
|
||||
|
||||
*pptr = Pair {fst: 50, snd: 60};
|
||||
assert_eq!(*iptr, 50);
|
||||
assert_eq!(p.fst, 50);
|
||||
assert_eq!(p.snd, 60);
|
||||
|
||||
let v0 = vec![32000u16, 32001u16, 32002u16];
|
||||
let mut v1 = vec![0u16, 0u16, 0u16];
|
||||
|
||||
copy_memory(v1.as_mut_ptr().offset(1),
|
||||
v0.as_ptr().offset(1), 1);
|
||||
assert!((*v1.get(0) == 0u16 &&
|
||||
*v1.get(1) == 32001u16 &&
|
||||
*v1.get(2) == 0u16));
|
||||
copy_memory(v1.as_mut_ptr(),
|
||||
v0.as_ptr().offset(2), 1);
|
||||
assert!((*v1.get(0) == 32002u16 &&
|
||||
*v1.get(1) == 32001u16 &&
|
||||
*v1.get(2) == 0u16));
|
||||
copy_memory(v1.as_mut_ptr().offset(2),
|
||||
v0.as_ptr(), 1u);
|
||||
assert!((*v1.get(0) == 32002u16 &&
|
||||
*v1.get(1) == 32001u16 &&
|
||||
*v1.get(2) == 32000u16));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_position() {
|
||||
use libc::c_char;
|
||||
|
||||
"hello".with_c_str(|p| {
|
||||
unsafe {
|
||||
assert!(2u == position(p, |c| *c == 'l' as c_char));
|
||||
assert!(4u == position(p, |c| *c == 'o' as c_char));
|
||||
assert!(5u == position(p, |c| *c == 0 as c_char));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buf_len() {
|
||||
"hello".with_c_str(|p0| {
|
||||
"there".with_c_str(|p1| {
|
||||
"thing".with_c_str(|p2| {
|
||||
let v = vec![p0, p1, p2, null()];
|
||||
unsafe {
|
||||
assert_eq!(buf_len(v.as_ptr()), 3u);
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_null() {
|
||||
let p: *const int = null();
|
||||
assert!(p.is_null());
|
||||
assert!(!p.is_not_null());
|
||||
|
||||
let q = unsafe { p.offset(1) };
|
||||
assert!(!q.is_null());
|
||||
assert!(q.is_not_null());
|
||||
|
||||
let mp: *mut int = mut_null();
|
||||
assert!(mp.is_null());
|
||||
assert!(!mp.is_not_null());
|
||||
|
||||
let mq = unsafe { mp.offset(1) };
|
||||
assert!(!mq.is_null());
|
||||
assert!(mq.is_not_null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_option() {
|
||||
unsafe {
|
||||
let p: *const int = null();
|
||||
assert_eq!(p.to_option(), None);
|
||||
|
||||
let q: *const int = &2;
|
||||
assert_eq!(q.to_option().unwrap(), &2);
|
||||
|
||||
let p: *mut int = mut_null();
|
||||
assert_eq!(p.to_option(), None);
|
||||
|
||||
let q: *mut int = &mut 2;
|
||||
assert_eq!(q.to_option().unwrap(), &2);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_addition() {
|
||||
unsafe {
|
||||
let xs = Vec::from_elem(16, 5i);
|
||||
let mut ptr = xs.as_ptr();
|
||||
let end = ptr.offset(16);
|
||||
|
||||
while ptr < end {
|
||||
assert_eq!(*ptr, 5);
|
||||
ptr = ptr.offset(1);
|
||||
}
|
||||
|
||||
let mut xs_mut = xs;
|
||||
let mut m_ptr = xs_mut.as_mut_ptr();
|
||||
let m_end = m_ptr.offset(16);
|
||||
|
||||
while m_ptr < m_end {
|
||||
*m_ptr += 5;
|
||||
m_ptr = m_ptr.offset(1);
|
||||
}
|
||||
|
||||
assert!(xs_mut == Vec::from_elem(16, 10i));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_subtraction() {
|
||||
unsafe {
|
||||
let xs = vec![0,1,2,3,4,5,6,7,8,9];
|
||||
let mut idx = 9i8;
|
||||
let ptr = xs.as_ptr();
|
||||
|
||||
while idx >= 0i8 {
|
||||
assert_eq!(*(ptr.offset(idx as int)), idx as int);
|
||||
idx = idx - 1i8;
|
||||
}
|
||||
|
||||
let mut xs_mut = xs;
|
||||
let m_start = xs_mut.as_mut_ptr();
|
||||
let mut m_ptr = m_start.offset(9);
|
||||
|
||||
while m_ptr >= m_start {
|
||||
*m_ptr += *m_ptr;
|
||||
m_ptr = m_ptr.offset(-1);
|
||||
}
|
||||
|
||||
assert!(xs_mut == vec![0,2,4,6,8,10,12,14,16,18]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_array_each_with_len() {
|
||||
unsafe {
|
||||
let one = "oneOne".to_c_str();
|
||||
let two = "twoTwo".to_c_str();
|
||||
let three = "threeThree".to_c_str();
|
||||
let arr = vec![
|
||||
one.as_ptr(),
|
||||
two.as_ptr(),
|
||||
three.as_ptr()
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
];
|
||||
|
||||
let mut ctr = 0;
|
||||
let mut iteration_count = 0;
|
||||
array_each_with_len(arr.as_ptr(), arr.len(), |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr());
|
||||
assert_eq!(actual.as_slice(), expected.as_slice());
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
});
|
||||
assert_eq!(iteration_count, 3u);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_array_each() {
|
||||
unsafe {
|
||||
let one = "oneOne".to_c_str();
|
||||
let two = "twoTwo".to_c_str();
|
||||
let three = "threeThree".to_c_str();
|
||||
let arr = vec![
|
||||
one.as_ptr(),
|
||||
two.as_ptr(),
|
||||
three.as_ptr(),
|
||||
// fake a null terminator
|
||||
null()
|
||||
];
|
||||
let expected_arr = [
|
||||
one, two, three
|
||||
];
|
||||
|
||||
let arr_ptr = arr.as_ptr();
|
||||
let mut ctr = 0u;
|
||||
let mut iteration_count = 0u;
|
||||
array_each(arr_ptr, |e| {
|
||||
let actual = str::raw::from_c_str(e);
|
||||
let expected = str::raw::from_c_str(expected_arr[ctr].as_ptr());
|
||||
assert_eq!(actual.as_slice(), expected.as_slice());
|
||||
ctr += 1;
|
||||
iteration_count += 1;
|
||||
});
|
||||
assert_eq!(iteration_count, 3);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_ptr_array_each_with_len_null_ptr() {
|
||||
unsafe {
|
||||
array_each_with_len(0 as *const *const libc::c_char, 1, |e| {
|
||||
str::raw::from_c_str(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_ptr_array_each_null_ptr() {
|
||||
unsafe {
|
||||
array_each(0 as *const *const libc::c_char, |e| {
|
||||
str::raw::from_c_str(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_memory() {
|
||||
let mut xs = [0u8, ..20];
|
||||
let ptr = xs.as_mut_ptr();
|
||||
unsafe { set_memory(ptr, 5u8, xs.len()); }
|
||||
assert!(xs == [5u8, ..20]);
|
||||
}
|
35
src/libcoretest/raw.rs
Normal file
35
src/libcoretest/raw.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::raw::*;
|
||||
use core::mem;
|
||||
|
||||
#[test]
|
||||
fn synthesize_closure() {
|
||||
unsafe {
|
||||
let x = 10;
|
||||
let f: |int| -> int = |y| x + y;
|
||||
|
||||
assert_eq!(f(20), 30);
|
||||
|
||||
let original_closure: Closure = mem::transmute(f);
|
||||
|
||||
let actual_function_pointer = original_closure.code;
|
||||
let environment = original_closure.env;
|
||||
|
||||
let new_closure = Closure {
|
||||
code: actual_function_pointer,
|
||||
env: environment
|
||||
};
|
||||
|
||||
let new_f: |int| -> int = mem::transmute(new_closure);
|
||||
assert_eq!(new_f(20), 30);
|
||||
}
|
||||
}
|
161
src/libcoretest/result.rs
Normal file
161
src/libcoretest/result.rs
Normal file
|
@ -0,0 +1,161 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::result::{collect, fold, fold_};
|
||||
use core::iter::range;
|
||||
|
||||
pub fn op1() -> Result<int, &'static str> { Ok(666) }
|
||||
pub fn op2() -> Result<int, &'static str> { Err("sadface") }
|
||||
|
||||
#[test]
|
||||
pub fn test_and() {
|
||||
assert_eq!(op1().and(Ok(667i)).unwrap(), 667);
|
||||
assert_eq!(op1().and(Err::<(), &'static str>("bad")).unwrap_err(),
|
||||
"bad");
|
||||
|
||||
assert_eq!(op2().and(Ok(667i)).unwrap_err(), "sadface");
|
||||
assert_eq!(op2().and(Err::<(),&'static str>("bad")).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_and_then() {
|
||||
assert_eq!(op1().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap(), 667);
|
||||
assert_eq!(op1().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
|
||||
"bad");
|
||||
|
||||
assert_eq!(op2().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap_err(),
|
||||
"sadface");
|
||||
assert_eq!(op2().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_or() {
|
||||
assert_eq!(op1().or(Ok(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or(Err("bad")).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or(Ok(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_or_else() {
|
||||
assert_eq!(op1().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or_else(|e| Err::<int, &'static str>(e)).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or_else(|e| Err::<int, &'static str>(e)).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_impl_map() {
|
||||
assert!(Ok::<int, int>(1).map(|x| x + 1) == Ok(2));
|
||||
assert!(Err::<int, int>(1).map(|x| x + 1) == Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_impl_map_err() {
|
||||
assert!(Ok::<int, int>(1).map_err(|x| x + 1) == Ok(1));
|
||||
assert!(Err::<int, int>(1).map_err(|x| x + 1) == Err(2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let v: Result<Vec<int>, ()> = collect(range(0i, 0).map(|_| Ok::<int, ()>(0)));
|
||||
assert!(v == Ok(vec![]));
|
||||
|
||||
let v: Result<Vec<int>, ()> = collect(range(0i, 3).map(|x| Ok::<int, ()>(x)));
|
||||
assert!(v == Ok(vec![0, 1, 2]));
|
||||
|
||||
let v: Result<Vec<int>, int> = collect(range(0i, 3)
|
||||
.map(|x| if x > 1 { Err(x) } else { Ok(x) }));
|
||||
assert!(v == Err(2));
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions = [|| Ok(()), || Err(1i), || fail!()];
|
||||
|
||||
let v: Result<Vec<()>, int> = collect(functions.mut_iter().map(|f| (*f)()));
|
||||
assert!(v == Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold() {
|
||||
assert_eq!(fold_(range(0i, 0)
|
||||
.map(|_| Ok::<(), ()>(()))),
|
||||
Ok(()));
|
||||
assert_eq!(fold(range(0i, 3)
|
||||
.map(|x| Ok::<int, ()>(x)),
|
||||
0, |a, b| a + b),
|
||||
Ok(3));
|
||||
assert_eq!(fold_(range(0i, 3)
|
||||
.map(|x| if x > 1 { Err(x) } else { Ok(()) })),
|
||||
Err(2));
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions = [|| Ok(()), || Err(1i), || fail!()];
|
||||
|
||||
assert_eq!(fold_(functions.mut_iter()
|
||||
.map(|f| (*f)())),
|
||||
Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_fmt_default() {
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let err: Result<int, &'static str> = Err("Err");
|
||||
|
||||
let s = format!("{}", ok);
|
||||
assert_eq!(s.as_slice(), "Ok(100)");
|
||||
let s = format!("{}", err);
|
||||
assert_eq!(s.as_slice(), "Err(Err)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_unwrap_or() {
|
||||
let ok: Result<int, &'static str> = Ok(100i);
|
||||
let ok_err: Result<int, &'static str> = Err("Err");
|
||||
|
||||
assert_eq!(ok.unwrap_or(50), 100);
|
||||
assert_eq!(ok_err.unwrap_or(50), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_unwrap_or_else() {
|
||||
fn handler(msg: &'static str) -> int {
|
||||
if msg == "I got this." {
|
||||
50i
|
||||
} else {
|
||||
fail!("BadBad")
|
||||
}
|
||||
}
|
||||
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let ok_err: Result<int, &'static str> = Err("I got this.");
|
||||
|
||||
assert_eq!(ok.unwrap_or_else(handler), 100);
|
||||
assert_eq!(ok_err.unwrap_or_else(handler), 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
pub fn test_unwrap_or_else_failure() {
|
||||
fn handler(msg: &'static str) -> int {
|
||||
if msg == "I got this." {
|
||||
50i
|
||||
} else {
|
||||
fail!("BadBad")
|
||||
}
|
||||
}
|
||||
|
||||
let bad_err: Result<int, &'static str> = Err("Unrecoverable mess.");
|
||||
let _ : int = bad_err.unwrap_or_else(handler);
|
||||
}
|
92
src/libcoretest/tuple.rs
Normal file
92
src/libcoretest/tuple.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let a = (1i, "2");
|
||||
let b = a.clone();
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_getters() {
|
||||
macro_rules! test_getter(
|
||||
($x:expr, $valN:ident, $refN:ident, $mutN:ident,
|
||||
$init:expr, $incr:expr, $result:expr) => ({
|
||||
assert_eq!($x.$valN(), $init);
|
||||
assert_eq!(*$x.$refN(), $init);
|
||||
*$x.$mutN() += $incr;
|
||||
assert_eq!(*$x.$refN(), $result);
|
||||
})
|
||||
)
|
||||
let mut x = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64);
|
||||
test_getter!(x, val0, ref0, mut0, 0, 1, 1);
|
||||
test_getter!(x, val1, ref1, mut1, 1, 1, 2);
|
||||
test_getter!(x, val2, ref2, mut2, 2, 1, 3);
|
||||
test_getter!(x, val3, ref3, mut3, 3, 1, 4);
|
||||
test_getter!(x, val4, ref4, mut4, 4, 1, 5);
|
||||
test_getter!(x, val5, ref5, mut5, 5, 1, 6);
|
||||
test_getter!(x, val6, ref6, mut6, 6, 1, 7);
|
||||
test_getter!(x, val7, ref7, mut7, 7, 1, 8);
|
||||
test_getter!(x, val8, ref8, mut8, 8, 1, 9);
|
||||
test_getter!(x, val9, ref9, mut9, 9, 1, 10);
|
||||
test_getter!(x, val10, ref10, mut10, 10.0, 1.0, 11.0);
|
||||
test_getter!(x, val11, ref11, mut11, 11.0, 1.0, 12.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tuple_cmp() {
|
||||
let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
|
||||
|
||||
let nan = 0.0f64/0.0;
|
||||
|
||||
// PartialEq
|
||||
assert_eq!(small, small);
|
||||
assert_eq!(big, big);
|
||||
assert!(small != big);
|
||||
assert!(big != small);
|
||||
|
||||
// PartialOrd
|
||||
assert!(small < big);
|
||||
assert!(!(small < small));
|
||||
assert!(!(big < small));
|
||||
assert!(!(big < big));
|
||||
|
||||
assert!(small <= small);
|
||||
assert!(big <= big);
|
||||
|
||||
assert!(big > small);
|
||||
assert!(small >= small);
|
||||
assert!(big >= small);
|
||||
assert!(big >= big);
|
||||
|
||||
assert!(!((1.0f64, 2.0f64) < (nan, 3.0)));
|
||||
assert!(!((1.0f64, 2.0f64) <= (nan, 3.0)));
|
||||
assert!(!((1.0f64, 2.0f64) > (nan, 3.0)));
|
||||
assert!(!((1.0f64, 2.0f64) >= (nan, 3.0)));
|
||||
assert!(((1.0f64, 2.0f64) < (2.0, nan)));
|
||||
assert!(!((2.0f64, 2.0f64) < (2.0, nan)));
|
||||
|
||||
// Ord
|
||||
assert!(small.cmp(&small) == Equal);
|
||||
assert!(big.cmp(&big) == Equal);
|
||||
assert!(small.cmp(&big) == Less);
|
||||
assert!(big.cmp(&small) == Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let s = format!("{}", (1i,));
|
||||
assert_eq!(s.as_slice(), "(1,)");
|
||||
let s = format!("{}", (1i, true));
|
||||
assert_eq!(s.as_slice(), "(1, true)");
|
||||
let s = format!("{}", (1i, "hi", true));
|
||||
assert_eq!(s.as_slice(), "(1, hi, true)");
|
||||
}
|
|
@ -28,7 +28,7 @@ use std::gc::Gc;
|
|||
* as `TyVisitor`; then build a MovePtrAdaptor wrapped around your struct.
|
||||
*/
|
||||
pub trait MovePtr {
|
||||
fn move_ptr(&mut self, adjustment: |*u8| -> *u8);
|
||||
fn move_ptr(&mut self, adjustment: |*const u8| -> *const u8);
|
||||
fn push_ptr(&mut self);
|
||||
fn pop_ptr(&mut self);
|
||||
}
|
||||
|
@ -51,12 +51,12 @@ impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
|
|||
|
||||
#[inline]
|
||||
pub fn bump(&mut self, sz: uint) {
|
||||
self.inner.move_ptr(|p| ((p as uint) + sz) as *u8)
|
||||
self.inner.move_ptr(|p| ((p as uint) + sz) as *const u8)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn align(&mut self, a: uint) {
|
||||
self.inner.move_ptr(|p| align(p as uint, a) as *u8)
|
||||
self.inner.move_ptr(|p| align(p as uint, a) as *const u8)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -202,35 +202,35 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.align_to::<Gc<u8>>();
|
||||
if ! self.inner.visit_box(mtbl, inner) { return false; }
|
||||
self.bump_past::<Gc<u8>>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_uniq(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.align_to::<Box<u8>>();
|
||||
if ! self.inner.visit_uniq(mtbl, inner) { return false; }
|
||||
self.bump_past::<Box<u8>>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_ptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
self.align_to::<*u8>();
|
||||
fn visit_ptr(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.align_to::<*const u8>();
|
||||
if ! self.inner.visit_ptr(mtbl, inner) { return false; }
|
||||
self.bump_past::<*u8>();
|
||||
self.bump_past::<*const u8>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.align_to::<&'static u8>();
|
||||
if ! self.inner.visit_rptr(mtbl, inner) { return false; }
|
||||
self.bump_past::<&'static u8>();
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.align_to::<&'static [u8]>();
|
||||
if ! self.inner.visit_evec_slice(mtbl, inner) { return false; }
|
||||
self.bump_past::<&'static [u8]>();
|
||||
|
@ -238,7 +238,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
}
|
||||
|
||||
fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
|
||||
mtbl: uint, inner: *TyDesc) -> bool {
|
||||
mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.align(align);
|
||||
if ! self.inner.visit_evec_fixed(n, sz, align, mtbl, inner) {
|
||||
return false;
|
||||
|
@ -254,7 +254,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
}
|
||||
|
||||
fn visit_rec_field(&mut self, i: uint, name: &str,
|
||||
mtbl: uint, inner: *TyDesc) -> bool {
|
||||
mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
unsafe { self.align((*inner).align); }
|
||||
if ! self.inner.visit_rec_field(i, name, mtbl, inner) {
|
||||
return false;
|
||||
|
@ -278,7 +278,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
}
|
||||
|
||||
fn visit_class_field(&mut self, i: uint, name: &str, named: bool, mtbl: uint,
|
||||
inner: *TyDesc) -> bool {
|
||||
inner: *const TyDesc) -> bool {
|
||||
unsafe { self.align((*inner).align); }
|
||||
if ! self.inner.visit_class_field(i, name, named, mtbl, inner) {
|
||||
return false;
|
||||
|
@ -301,7 +301,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *const TyDesc) -> bool {
|
||||
unsafe { self.align((*inner).align); }
|
||||
if ! self.inner.visit_tup_field(i, inner) { return false; }
|
||||
unsafe { self.bump((*inner).size); }
|
||||
|
@ -321,12 +321,14 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_fn_input(&mut self, i: uint, mode: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_fn_input(&mut self, i: uint, mode: uint,
|
||||
inner: *const TyDesc) -> bool {
|
||||
if ! self.inner.visit_fn_input(i, mode, inner) { return false; }
|
||||
true
|
||||
}
|
||||
|
||||
fn visit_fn_output(&mut self, retstyle: uint, variadic: bool, inner: *TyDesc) -> bool {
|
||||
fn visit_fn_output(&mut self, retstyle: uint, variadic: bool,
|
||||
inner: *const TyDesc) -> bool {
|
||||
if ! self.inner.visit_fn_output(retstyle, variadic, inner) { return false; }
|
||||
true
|
||||
}
|
||||
|
@ -340,7 +342,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
}
|
||||
|
||||
fn visit_enter_enum(&mut self, n_variants: uint,
|
||||
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
|
||||
get_disr: unsafe extern fn(ptr: *const Opaque) -> Disr,
|
||||
sz: uint, align: uint)
|
||||
-> bool {
|
||||
self.align(align);
|
||||
|
@ -361,7 +363,8 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_enum_variant_field(&mut self, i: uint, offset: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_enum_variant_field(&mut self, i: uint, offset: uint,
|
||||
inner: *const TyDesc) -> bool {
|
||||
self.inner.push_ptr();
|
||||
self.bump(offset);
|
||||
if ! self.inner.visit_enum_variant_field(i, offset, inner) { return false; }
|
||||
|
@ -381,7 +384,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
|
|||
}
|
||||
|
||||
fn visit_leave_enum(&mut self, n_variants: uint,
|
||||
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
|
||||
get_disr: unsafe extern fn(ptr: *const Opaque) -> Disr,
|
||||
sz: uint, align: uint) -> bool {
|
||||
if ! self.inner.visit_leave_enum(n_variants, get_disr, sz, align) {
|
||||
return false;
|
||||
|
|
|
@ -92,8 +92,8 @@ enum VariantState {
|
|||
}
|
||||
|
||||
pub struct ReprVisitor<'a> {
|
||||
ptr: *u8,
|
||||
ptr_stk: Vec<*u8>,
|
||||
ptr: *const u8,
|
||||
ptr_stk: Vec<*const u8>,
|
||||
var_stk: Vec<VariantState>,
|
||||
writer: &'a mut io::Writer,
|
||||
last_err: Option<io::IoError>,
|
||||
|
@ -101,7 +101,7 @@ pub struct ReprVisitor<'a> {
|
|||
|
||||
impl<'a> MovePtr for ReprVisitor<'a> {
|
||||
#[inline]
|
||||
fn move_ptr(&mut self, adjustment: |*u8| -> *u8) {
|
||||
fn move_ptr(&mut self, adjustment: |*const u8| -> *const u8) {
|
||||
self.ptr = adjustment(self.ptr);
|
||||
}
|
||||
fn push_ptr(&mut self) {
|
||||
|
@ -114,7 +114,7 @@ impl<'a> MovePtr for ReprVisitor<'a> {
|
|||
|
||||
impl<'a> ReprVisitor<'a> {
|
||||
// Various helpers for the TyVisitor impl
|
||||
pub fn new(ptr: *u8, writer: &'a mut io::Writer) -> ReprVisitor<'a> {
|
||||
pub fn new(ptr: *const u8, writer: &'a mut io::Writer) -> ReprVisitor<'a> {
|
||||
ReprVisitor {
|
||||
ptr: ptr,
|
||||
ptr_stk: vec!(),
|
||||
|
@ -128,18 +128,19 @@ impl<'a> ReprVisitor<'a> {
|
|||
pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T| -> bool) -> bool {
|
||||
unsafe {
|
||||
let ptr = self.ptr;
|
||||
f(self, mem::transmute::<*u8,&T>(ptr))
|
||||
f(self, mem::transmute::<*const u8,&T>(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn visit_inner(&mut self, inner: *TyDesc) -> bool {
|
||||
pub fn visit_inner(&mut self, inner: *const TyDesc) -> bool {
|
||||
let ptr = self.ptr;
|
||||
self.visit_ptr_inner(ptr, inner)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn visit_ptr_inner(&mut self, ptr: *u8, inner: *TyDesc) -> bool {
|
||||
pub fn visit_ptr_inner(&mut self, ptr: *const u8,
|
||||
inner: *const TyDesc) -> bool {
|
||||
unsafe {
|
||||
let u = ReprVisitor::new(ptr, mem::transmute_copy(&self.writer));
|
||||
let mut v = reflect::MovePtrAdaptor::new(u);
|
||||
|
@ -183,8 +184,9 @@ impl<'a> ReprVisitor<'a> {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
|
||||
let mut p = ptr as *u8;
|
||||
pub fn write_vec_range(&mut self, ptr: *const (), len: uint,
|
||||
inner: *const TyDesc) -> bool {
|
||||
let mut p = ptr as *const u8;
|
||||
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
|
||||
try!(self, self.writer.write(['[' as u8]));
|
||||
let mut first = true;
|
||||
|
@ -197,8 +199,8 @@ impl<'a> ReprVisitor<'a> {
|
|||
} else {
|
||||
try!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
self.visit_ptr_inner(p as *u8, inner);
|
||||
p = align(unsafe { p.offset(sz as int) as uint }, al) as *u8;
|
||||
self.visit_ptr_inner(p as *const u8, inner);
|
||||
p = align(unsafe { p.offset(sz as int) as uint }, al) as *const u8;
|
||||
left -= dec;
|
||||
}
|
||||
try!(self, self.writer.write([']' as u8]));
|
||||
|
@ -276,40 +278,46 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
fn visit_estr_fixed(&mut self, _n: uint, _sz: uint,
|
||||
_align: uint) -> bool { fail!(); }
|
||||
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_box(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
try!(self, self.writer.write("box(GC) ".as_bytes()));
|
||||
self.write_mut_qualifier(mtbl);
|
||||
self.get::<&raw::Box<()>>(|this, b| {
|
||||
let p = &b.data as *() as *u8;
|
||||
let p = &b.data as *const () as *const u8;
|
||||
this.visit_ptr_inner(p, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_uniq(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_uniq(&mut self, _mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
try!(self, self.writer.write("box ".as_bytes()));
|
||||
self.get::<*u8>(|this, b| {
|
||||
self.get::<*const u8>(|this, b| {
|
||||
this.visit_ptr_inner(*b, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_ptr(&mut self, mtbl: uint, _inner: *TyDesc) -> bool {
|
||||
self.get::<*u8>(|this, p| {
|
||||
fn visit_ptr(&mut self, mtbl: uint, _inner: *const TyDesc) -> bool {
|
||||
self.get::<*const u8>(|this, p| {
|
||||
try!(this, write!(this.writer, "({} as *", *p));
|
||||
this.write_mut_qualifier(mtbl);
|
||||
if mtbl == 0 {
|
||||
try!(this, this.writer.write("mut ".as_bytes()));
|
||||
} else if mtbl == 1 {
|
||||
try!(this, this.writer.write("const ".as_bytes()));
|
||||
} else {
|
||||
fail!("invalid mutability value");
|
||||
}
|
||||
try!(this, this.writer.write("())".as_bytes()));
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_rptr(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
try!(self, self.writer.write(['&' as u8]));
|
||||
self.write_mut_qualifier(mtbl);
|
||||
self.get::<*u8>(|this, p| {
|
||||
self.get::<*const u8>(|this, p| {
|
||||
this.visit_ptr_inner(*p, inner)
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
self.get::<raw::Slice<()>>(|this, s| {
|
||||
try!(this, this.writer.write(['&' as u8]));
|
||||
this.write_mut_qualifier(mtbl);
|
||||
|
@ -321,7 +329,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
}
|
||||
|
||||
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
|
||||
_: uint, inner: *TyDesc) -> bool {
|
||||
_: uint, inner: *const TyDesc) -> bool {
|
||||
let assumed_size = if sz == 0 { n } else { sz };
|
||||
self.get::<()>(|this, b| {
|
||||
this.write_vec_range(b, assumed_size, inner)
|
||||
|
@ -335,7 +343,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
}
|
||||
|
||||
fn visit_rec_field(&mut self, i: uint, name: &str,
|
||||
mtbl: uint, inner: *TyDesc) -> bool {
|
||||
mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
try!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
|
@ -366,7 +374,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
}
|
||||
|
||||
fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
|
||||
_mtbl: uint, inner: *TyDesc) -> bool {
|
||||
_mtbl: uint, inner: *const TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
try!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
|
@ -396,7 +404,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_tup_field(&mut self, i: uint, inner: *const TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
try!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
|
@ -415,7 +423,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_enter_enum(&mut self,
|
||||
_n_variants: uint,
|
||||
get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
|
||||
get_disr: unsafe extern fn(ptr: *const Opaque) -> Disr,
|
||||
_sz: uint,
|
||||
_align: uint) -> bool {
|
||||
let disr = unsafe {
|
||||
|
@ -456,7 +464,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
fn visit_enum_variant_field(&mut self,
|
||||
i: uint,
|
||||
_offset: uint,
|
||||
inner: *TyDesc)
|
||||
inner: *const TyDesc)
|
||||
-> bool {
|
||||
match *self.var_stk.get(self.var_stk.len() - 1) {
|
||||
Matched => {
|
||||
|
@ -489,7 +497,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
fn visit_leave_enum(&mut self,
|
||||
_n_variants: uint,
|
||||
_get_disr: unsafe extern fn(ptr: *Opaque) -> Disr,
|
||||
_get_disr: unsafe extern fn(ptr: *const Opaque) -> Disr,
|
||||
_sz: uint,
|
||||
_align: uint)
|
||||
-> bool {
|
||||
|
@ -505,7 +513,8 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
true
|
||||
}
|
||||
|
||||
fn visit_fn_input(&mut self, i: uint, _mode: uint, inner: *TyDesc) -> bool {
|
||||
fn visit_fn_input(&mut self, i: uint, _mode: uint,
|
||||
inner: *const TyDesc) -> bool {
|
||||
if i != 0 {
|
||||
try!(self, self.writer.write(", ".as_bytes()));
|
||||
}
|
||||
|
@ -515,7 +524,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
}
|
||||
|
||||
fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool,
|
||||
inner: *TyDesc) -> bool {
|
||||
inner: *const TyDesc) -> bool {
|
||||
if variadic {
|
||||
try!(self, self.writer.write(", ...".as_bytes()));
|
||||
}
|
||||
|
@ -543,7 +552,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
|
|||
|
||||
pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
|
||||
unsafe {
|
||||
let ptr = object as *T as *u8;
|
||||
let ptr = object as *const T as *const u8;
|
||||
let tydesc = get_tydesc::<T>();
|
||||
let u = ReprVisitor::new(ptr, writer);
|
||||
let mut v = reflect::MovePtrAdaptor::new(u);
|
||||
|
@ -579,22 +588,22 @@ fn test_repr() {
|
|||
assert_eq!(s.as_slice(), e);
|
||||
}
|
||||
|
||||
exact_test(&10, "10");
|
||||
exact_test(&10i, "10");
|
||||
exact_test(&true, "true");
|
||||
exact_test(&false, "false");
|
||||
exact_test(&1.234, "1.234f64");
|
||||
exact_test(&1.234f64, "1.234f64");
|
||||
exact_test(&("hello"), "\"hello\"");
|
||||
|
||||
exact_test(&(box(GC) 10), "box(GC) 10");
|
||||
exact_test(&(box 10), "box 10");
|
||||
exact_test(&(&10), "&10");
|
||||
let mut x = 10;
|
||||
exact_test(&(box(GC) 10i), "box(GC) 10");
|
||||
exact_test(&(box 10i), "box 10");
|
||||
exact_test(&(&10i), "&10");
|
||||
let mut x = 10i;
|
||||
exact_test(&(&mut x), "&mut 10");
|
||||
|
||||
exact_test(&(0 as *()), "(0x0 as *())");
|
||||
exact_test(&(0 as *mut ()), "(0x0 as *mut ())");
|
||||
exact_test(&(0i as *const()), "(0x0 as *const ())");
|
||||
exact_test(&(0i as *mut ()), "(0x0 as *mut ())");
|
||||
|
||||
exact_test(&(1,), "(1,)");
|
||||
exact_test(&(1i,), "(1,)");
|
||||
exact_test(&(&["hi", "there"]),
|
||||
"&[\"hi\", \"there\"]");
|
||||
exact_test(&(P{a:10, b:1.234}),
|
||||
|
@ -604,8 +613,8 @@ fn test_repr() {
|
|||
exact_test(&(box P{a:10, b:1.234}),
|
||||
"box repr::P{a: 10, b: 1.234f64}");
|
||||
|
||||
exact_test(&(&[1, 2]), "&[1, 2]");
|
||||
exact_test(&(&mut [1, 2]), "&mut [1, 2]");
|
||||
exact_test(&(&[1i, 2i]), "&[1, 2]");
|
||||
exact_test(&(&mut [1i, 2i]), "&mut [1, 2]");
|
||||
|
||||
exact_test(&'\'', "'\\''");
|
||||
exact_test(&'"', "'\"'");
|
||||
|
|
|
@ -38,14 +38,14 @@ use libc::{c_void, size_t, c_int};
|
|||
#[link(name = "miniz", kind = "static")]
|
||||
extern {
|
||||
/// Raw miniz compression function.
|
||||
fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
|
||||
fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
|
||||
src_buf_len: size_t,
|
||||
pout_len: *mut size_t,
|
||||
flags: c_int)
|
||||
-> *mut c_void;
|
||||
|
||||
/// Raw miniz decompression function.
|
||||
fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
|
||||
fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
|
||||
src_buf_len: size_t,
|
||||
pout_len: *mut size_t,
|
||||
flags: c_int)
|
||||
|
@ -59,7 +59,7 @@ static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler
|
|||
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
|
||||
unsafe {
|
||||
let mut outsz : size_t = 0;
|
||||
let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
|
||||
let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
|
||||
bytes.len() as size_t,
|
||||
&mut outsz,
|
||||
flags);
|
||||
|
@ -84,7 +84,7 @@ pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
|
|||
fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
|
||||
unsafe {
|
||||
let mut outsz : size_t = 0;
|
||||
let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
|
||||
let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
|
||||
bytes.len() as size_t,
|
||||
&mut outsz,
|
||||
flags);
|
||||
|
|
|
@ -370,7 +370,7 @@ impl Matches {
|
|||
}
|
||||
|
||||
fn is_arg(arg: &str) -> bool {
|
||||
arg.len() > 1 && arg[0] == '-' as u8
|
||||
arg.len() > 1 && arg.as_bytes()[0] == '-' as u8
|
||||
}
|
||||
|
||||
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
||||
|
@ -553,7 +553,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
|
|||
} else {
|
||||
let mut names;
|
||||
let mut i_arg = None;
|
||||
if cur.as_slice()[1] == '-' as u8 {
|
||||
if cur.as_bytes()[1] == '-' as u8 {
|
||||
let tail = cur.as_slice().slice(2, curlen);
|
||||
let tail_eq: Vec<&str> = tail.split('=').collect();
|
||||
if tail_eq.len() <= 1 {
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::collections::Collection;
|
||||
use std::default::Default;
|
||||
use std::fmt;
|
||||
use std::iter::FromIterator;
|
||||
use std::path::BytesContainer;
|
||||
use std::slice;
|
||||
|
||||
// Note 1: It is not clear whether the flexibility of providing both
|
||||
|
@ -61,6 +64,32 @@ impl<'a,T> MaybeOwnedVector<'a,T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PartialEq> PartialEq for MaybeOwnedVector<'a, T> {
|
||||
fn eq(&self, other: &MaybeOwnedVector<T>) -> bool {
|
||||
self.as_slice() == other.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Eq> Eq for MaybeOwnedVector<'a, T> {}
|
||||
|
||||
impl<'a, T: PartialOrd> PartialOrd for MaybeOwnedVector<'a, T> {
|
||||
fn partial_cmp(&self, other: &MaybeOwnedVector<T>) -> Option<Ordering> {
|
||||
self.as_slice().partial_cmp(&other.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> {
|
||||
fn cmp(&self, other: &MaybeOwnedVector<T>) -> Ordering {
|
||||
self.as_slice().cmp(&other.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PartialEq, V: Vector<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
|
||||
fn equiv(&self, other: &V) -> bool {
|
||||
self.as_slice() == other.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
// The `Vector` trait is provided in the prelude and is implemented on
|
||||
// both `&'a [T]` and `Vec<T>`, so it makes sense to try to support it
|
||||
// seamlessly. The other vector related traits from the prelude do
|
||||
|
@ -108,6 +137,34 @@ impl<'a,T:Clone> CloneableVector<T> for MaybeOwnedVector<'a,T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> {
|
||||
fn clone(&self) -> MaybeOwnedVector<'a, T> {
|
||||
match *self {
|
||||
Growable(ref v) => Growable(v.to_owned()),
|
||||
Borrowed(v) => Borrowed(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, T> Default for MaybeOwnedVector<'a, T> {
|
||||
fn default() -> MaybeOwnedVector<'a, T> {
|
||||
Growable(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Collection for MaybeOwnedVector<'a, T> {
|
||||
fn len(&self) -> uint {
|
||||
self.as_slice().len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BytesContainer for MaybeOwnedVector<'a, u8> {
|
||||
fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
|
||||
self.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,T:Clone> MaybeOwnedVector<'a,T> {
|
||||
/// Convert `self` into a growable `Vec`, not making a copy if possible.
|
||||
pub fn into_vec(self) -> Vec<T> {
|
||||
|
|
|
@ -27,7 +27,7 @@ pub struct Context {
|
|||
stack_bounds: Option<(uint, uint)>,
|
||||
}
|
||||
|
||||
pub type InitFn = extern "C" fn(uint, *(), *()) -> !;
|
||||
pub type InitFn = extern "C" fn(uint, *mut (), *mut ()) -> !;
|
||||
|
||||
impl Context {
|
||||
pub fn empty() -> Context {
|
||||
|
@ -49,7 +49,7 @@ impl Context {
|
|||
pub fn new(init: InitFn, arg: uint, start: proc():Send,
|
||||
stack: &mut Stack) -> Context {
|
||||
|
||||
let sp: *uint = stack.end();
|
||||
let sp: *const uint = stack.end();
|
||||
let sp: *mut uint = sp as *mut uint;
|
||||
// Save and then immediately load the current context,
|
||||
// which we will then modify to call the given function when restored
|
||||
|
@ -66,7 +66,7 @@ impl Context {
|
|||
// them in terms of the code running on them (and hopefully they don't
|
||||
// overflow). Additionally, their coroutine stacks are listed as being
|
||||
// zero-length, so that's how we detect what's what here.
|
||||
let stack_base: *uint = stack.start();
|
||||
let stack_base: *const uint = stack.start();
|
||||
let bounds = if sp as uint == stack_base as uint {
|
||||
None
|
||||
} else {
|
||||
|
@ -116,7 +116,7 @@ impl Context {
|
|||
|
||||
#[link(name = "context_switch", kind = "static")]
|
||||
extern {
|
||||
fn rust_swap_registers(out_regs: *mut Registers, in_regs: *Registers);
|
||||
fn rust_swap_registers(out_regs: *mut Registers, in_regs: *const Registers);
|
||||
}
|
||||
|
||||
// Register contexts used in various architectures
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue