Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a54476b0
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a54476b0
编写于
8月 07, 2013
作者:
E
Erick Tryzelaar
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'remotes/origin/master' into remove-str-trailing-nulls
上级
aababbba
cdba212e
变更
41
隐藏空白更改
内联
并排
Showing
41 changed file
with
897 addition
and
861 deletion
+897
-861
Makefile.in
Makefile.in
+1
-1
doc/tutorial-tasks.md
doc/tutorial-tasks.md
+2
-2
doc/tutorial.md
doc/tutorial.md
+1
-1
src/libextra/base64.rs
src/libextra/base64.rs
+70
-114
src/libextra/extra.rs
src/libextra/extra.rs
+1
-0
src/libextra/hex.rs
src/libextra/hex.rs
+193
-0
src/libextra/iter.rs
src/libextra/iter.rs
+0
-331
src/libextra/ringbuf.rs
src/libextra/ringbuf.rs
+1
-1
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/foreign.rs
+5
-0
src/librustc/middle/trans/type_use.rs
src/librustc/middle/trans/type_use.rs
+2
-1
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/mod.rs
+14
-0
src/librustdoc/markdown_pass.rs
src/librustdoc/markdown_pass.rs
+2
-2
src/librusti/rusti.rs
src/librusti/rusti.rs
+9
-8
src/libstd/borrow.rs
src/libstd/borrow.rs
+12
-0
src/libstd/cmp.rs
src/libstd/cmp.rs
+0
-1
src/libstd/iterator.rs
src/libstd/iterator.rs
+26
-44
src/libstd/managed.rs
src/libstd/managed.rs
+24
-1
src/libstd/num/num.rs
src/libstd/num/num.rs
+157
-60
src/libstd/owned.rs
src/libstd/owned.rs
+13
-1
src/libstd/prelude.rs
src/libstd/prelude.rs
+2
-1
src/libstd/ptr.rs
src/libstd/ptr.rs
+41
-0
src/libstd/str.rs
src/libstd/str.rs
+14
-11
src/libstd/str/ascii.rs
src/libstd/str/ascii.rs
+169
-11
src/libstd/unstable/intrinsics.rs
src/libstd/unstable/intrinsics.rs
+10
-1
src/libstd/vec.rs
src/libstd/vec.rs
+20
-10
src/libsyntax/ext/deriving/cmp/totalord.rs
src/libsyntax/ext/deriving/cmp/totalord.rs
+47
-16
src/test/bench/core-set.rs
src/test/bench/core-set.rs
+2
-2
src/test/bench/noise.rs
src/test/bench/noise.rs
+1
-1
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-chameneos-redux.rs
+1
-1
src/test/bench/shootout-fasta-redux.rs
src/test/bench/shootout-fasta-redux.rs
+1
-1
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-k-nucleotide.rs
+2
-2
src/test/bench/shootout-nbody.rs
src/test/bench/shootout-nbody.rs
+1
-1
src/test/bench/shootout-spectralnorm.rs
src/test/bench/shootout-spectralnorm.rs
+1
-1
src/test/bench/task-perf-alloc-unwind.rs
src/test/bench/task-perf-alloc-unwind.rs
+1
-1
src/test/bench/task-perf-linked-failure.rs
src/test/bench/task-perf-linked-failure.rs
+2
-2
src/test/run-pass/class-impl-parameterized-trait.rs
src/test/run-pass/class-impl-parameterized-trait.rs
+0
-83
src/test/run-pass/class-implements-multiple-traits.rs
src/test/run-pass/class-implements-multiple-traits.rs
+0
-129
src/test/run-pass/coerce-reborrow-imm-vec-arg.rs
src/test/run-pass/coerce-reborrow-imm-vec-arg.rs
+0
-6
src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs
src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs
+0
-7
src/test/run-pass/deriving-cmp-shortcircuit.rs
src/test/run-pass/deriving-cmp-shortcircuit.rs
+46
-0
src/test/run-pass/rcvr-borrowed-to-region.rs
src/test/run-pass/rcvr-borrowed-to-region.rs
+3
-6
未找到文件。
Makefile.in
浏览文件 @
a54476b0
...
...
@@ -297,7 +297,7 @@ COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/, \
LIBSYNTAX_CRATE
:=
$(S)
src/libsyntax/syntax.rs
LIBSYNTAX_INPUTS
:=
$(
wildcard
$(
addprefix
$(S)
src/libsyntax/,
\
*
.rs
*
/
*
.rs
*
/
*
/
*
.rs
))
*
.rs
*
/
*
.rs
*
/
*
/
*
.rs
*
/
*
/
*
/
*
.rs
))
DRIVER_CRATE
:=
$(S)
src/driver/driver.rs
...
...
doc/tutorial-tasks.md
浏览文件 @
a54476b0
...
...
@@ -544,7 +544,7 @@ an intermediate generation has already exited:
~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# fn wait_for_a_while() {
do 1000.times
{ task::yield() } }
# fn wait_for_a_while() {
for _ in range(0, 1000u)
{ task::yield() } }
# do task::try::<int> {
do task::spawn_supervised {
do task::spawn_supervised {
...
...
@@ -563,7 +563,7 @@ other at all, using `task::spawn_unlinked` for _isolated failure_.
~~~
# use std::task;
# fn random() -> uint { 100 }
# fn sleep_for(i: uint) {
do i.times
{ task::yield() } }
# fn sleep_for(i: uint) {
for _ in range(0, i)
{ task::yield() } }
# do task::try::<()> {
let (time1, time2) = (random(), random());
do task::spawn_unlinked {
...
...
doc/tutorial.md
浏览文件 @
a54476b0
...
...
@@ -1894,7 +1894,7 @@ struct TimeBomb {
impl Drop for TimeBomb {
fn drop(&self) {
do self.explosivity.times
{
for _ in range(0, self.explosivity)
{
println("blam!");
}
}
...
...
src/libextra/base64.rs
浏览文件 @
a54476b0
...
...
@@ -9,6 +9,7 @@
// except according to those terms.
//! Base64 binary-to-text encoding
use
std
::
str
;
/// Available encoding character sets
pub
enum
CharacterSet
{
...
...
@@ -40,21 +41,13 @@ pub struct Config {
pub
static
MIME
:
Config
=
Config
{
char_set
:
Standard
,
pad
:
true
,
line_length
:
Some
(
76
)};
static
STANDARD_CHARS
:
[
char
,
..
64
]
=
[
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'+'
,
'/'
];
static
URLSAFE_CHARS
:
[
char
,
..
64
]
=
[
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'-'
,
'_'
];
static
STANDARD_CHARS
:
&
'static
[
u8
]
=
bytes!
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
,
"abcdefghijklmnopqrstuvwxyz"
,
"0123456789+/"
);
static
URLSAFE_CHARS
:
&
'static
[
u8
]
=
bytes!
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
,
"abcdefghijklmnopqrstuvwxyz"
,
"0123456789-_"
);
/// A trait for converting a value to base64 encoding.
pub
trait
ToBase64
{
...
...
@@ -80,12 +73,12 @@ impl<'self> ToBase64 for &'self [u8] {
* ~~~
*/
fn
to_base64
(
&
self
,
config
:
Config
)
->
~
str
{
let
char
s
=
match
config
.char_set
{
let
byte
s
=
match
config
.char_set
{
Standard
=>
STANDARD_CHARS
,
UrlSafe
=>
URLSAFE_CHARS
};
let
mut
s
=
~
""
;
let
mut
v
:
~
[
u8
]
=
~
[]
;
let
mut
i
=
0
;
let
mut
cur_length
=
0
;
let
len
=
self
.len
();
...
...
@@ -93,7 +86,8 @@ fn to_base64(&self, config: Config) -> ~str {
match
config
.line_length
{
Some
(
line_length
)
=>
if
cur_length
>=
line_length
{
s
.push_str
(
"
\r\n
"
);
v
.push
(
'\r'
as
u8
);
v
.push
(
'\n'
as
u8
);
cur_length
=
0
;
},
None
=>
()
...
...
@@ -104,10 +98,10 @@ fn to_base64(&self, config: Config) -> ~str {
(
self
[
i
+
2
]
as
u32
);
// This 24-bit number gets separated into four 6-bit numbers.
s
.push_char
(
char
s
[(
n
>>
18
)
&
63
]);
s
.push_char
(
char
s
[(
n
>>
12
)
&
63
]);
s
.push_char
(
char
s
[(
n
>>
6
)
&
63
]);
s
.push_char
(
char
s
[
n
&
63
]);
v
.push
(
byte
s
[(
n
>>
18
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
12
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
6
)
&
63
]);
v
.push
(
byte
s
[
n
&
63
]);
cur_length
+=
4
;
i
+=
3
;
...
...
@@ -117,7 +111,8 @@ fn to_base64(&self, config: Config) -> ~str {
match
config
.line_length
{
Some
(
line_length
)
=>
if
cur_length
>=
line_length
{
s
.push_str
(
"
\r\n
"
);
v
.push
(
'\r'
as
u8
);
v
.push
(
'\n'
as
u8
);
},
None
=>
()
}
...
...
@@ -129,48 +124,29 @@ fn to_base64(&self, config: Config) -> ~str {
0
=>
(),
1
=>
{
let
n
=
(
self
[
i
]
as
u32
)
<<
16
;
s
.push_char
(
char
s
[(
n
>>
18
)
&
63
]);
s
.push_char
(
char
s
[(
n
>>
12
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
18
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
12
)
&
63
]);
if
config
.pad
{
s
.push_str
(
"=="
);
v
.push
(
'='
as
u8
);
v
.push
(
'='
as
u8
);
}
}
2
=>
{
let
n
=
(
self
[
i
]
as
u32
)
<<
16
|
(
self
[
i
+
1u
]
as
u32
)
<<
8
;
s
.push_char
(
char
s
[(
n
>>
18
)
&
63
]);
s
.push_char
(
char
s
[(
n
>>
12
)
&
63
]);
s
.push_char
(
char
s
[(
n
>>
6
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
18
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
12
)
&
63
]);
v
.push
(
byte
s
[(
n
>>
6
)
&
63
]);
if
config
.pad
{
s
.push_char
(
'='
);
v
.push
(
'='
as
u8
);
}
}
_
=>
fail
!
(
"Algebra is broken, please alert the math police"
)
}
s
}
}
impl
<
'self
>
ToBase64
for
&
'self
str
{
/**
* Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
*
*
* # Example
*
* ~~~ {.rust}
* extern mod extra;
* use extra::base64::{ToBase64, standard};
*
* fn main () {
* let str = "Hello, World".to_base64(standard);
* printfln!("%s", str);
* }
* ~~~
*
*/
fn
to_base64
(
&
self
,
config
:
Config
)
->
~
str
{
self
.as_bytes
()
.to_base64
(
config
)
unsafe
{
str
::
raw
::
from_bytes_owned
(
v
)
}
}
}
...
...
@@ -181,22 +157,31 @@ pub trait FromBase64 {
fn
from_base64
(
&
self
)
->
Result
<~
[
u8
],
~
str
>
;
}
impl
<
'self
>
FromBase64
for
&
'self
[
u8
]
{
impl
<
'self
>
FromBase64
for
&
'self
str
{
/**
* Convert base64 `u8` vector into u8 byte values.
* Every 4 encoded characters is converted into 3 octets, modulo padding.
* Convert any base64 encoded string (literal, `@`, `&`, or `~`)
* to the byte values it encodes.
*
* You can use the `from_bytes` function in `std::str`
* to turn a `[u8]` into a string with characters corresponding to those
* values.
*
* # Example
*
* This converts a string literal to base64 and back.
*
* ~~~ {.rust}
* extern mod extra;
* use extra::base64::{ToBase64, FromBase64, standard};
* use std::str;
*
* fn main () {
* let
str = [52,32]
.to_base64(standard);
* printfln!("%s", str);
* let bytes = str.from_base64();
* let
hello_str = "Hello, World"
.to_base64(standard);
* printfln!("%s",
hello_
str);
* let bytes =
hello_
str.from_base64();
* printfln!("%?", bytes);
* let result_str = str::from_bytes(bytes);
* printfln!("%s", result_str);
* }
* ~~~
*/
...
...
@@ -205,12 +190,11 @@ fn from_base64(&self) -> Result<~[u8], ~str> {
let
mut
buf
:
u32
=
0
;
let
mut
modulus
=
0
;
let
mut
it
=
self
.iter
();
for
&
byte
in
it
{
let
ch
=
byte
as
char
;
let
mut
it
=
self
.byte_iter
()
.enumerate
();
for
(
idx
,
byte
)
in
it
{
let
val
=
byte
as
u32
;
match
ch
{
match
byte
as
char
{
'A'
..
'Z'
=>
buf
|
=
val
-
0x41
,
'a'
..
'z'
=>
buf
|
=
val
-
0x47
,
'0'
..
'9'
=>
buf
|
=
val
+
0x04
,
...
...
@@ -218,7 +202,8 @@ fn from_base64(&self) -> Result<~[u8], ~str> {
'/'
|
'_'
=>
buf
|
=
0x3F
,
'\r'
|
'\n'
=>
loop
,
'='
=>
break
,
_
=>
return
Err
(
~
"Invalid Base64 character"
)
_
=>
return
Err
(
fmt!
(
"Invalid character '%c' at position %u"
,
self
.char_at
(
idx
),
idx
))
}
buf
<<=
6
;
...
...
@@ -231,8 +216,11 @@ fn from_base64(&self) -> Result<~[u8], ~str> {
}
}
if
!
it
.all
(|
&
byte
|
{
byte
as
char
==
'='
})
{
return
Err
(
~
"Invalid Base64 character"
);
for
(
idx
,
byte
)
in
it
{
if
(
byte
as
char
)
!=
'='
{
return
Err
(
fmt!
(
"Invalid character '%c' at position %u"
,
self
.char_at
(
idx
),
idx
));
}
}
match
modulus
{
...
...
@@ -251,39 +239,6 @@ fn from_base64(&self) -> Result<~[u8], ~str> {
}
}
impl
<
'self
>
FromBase64
for
&
'self
str
{
/**
* Convert any base64 encoded string (literal, `@`, `&`, or `~`)
* to the byte values it encodes.
*
* You can use the `from_bytes` function in `std::str`
* to turn a `[u8]` into a string with characters corresponding to those
* values.
*
* # Example
*
* This converts a string literal to base64 and back.
*
* ~~~ {.rust}
* extern mod extra;
* use extra::base64::{ToBase64, FromBase64, standard};
* use std::str;
*
* fn main () {
* let hello_str = "Hello, World".to_base64(standard);
* printfln!("%s", hello_str);
* let bytes = hello_str.from_base64();
* printfln!("%?", bytes);
* let result_str = str::from_bytes(bytes);
* printfln!("%s", result_str);
* }
* ~~~
*/
fn
from_base64
(
&
self
)
->
Result
<~
[
u8
],
~
str
>
{
self
.as_bytes
()
.from_base64
()
}
}
#[cfg(test)]
mod
test
{
use
test
::
BenchHarness
;
...
...
@@ -291,27 +246,28 @@ mod test {
#[test]
fn
test_to_base64_basic
()
{
assert_eq!
(
""
.to_base64
(
STANDARD
),
~
""
);
assert_eq!
(
"f"
.to_base64
(
STANDARD
),
~
"Zg=="
);
assert_eq!
(
"fo"
.to_base64
(
STANDARD
),
~
"Zm8="
);
assert_eq!
(
"foo"
.to_base64
(
STANDARD
),
~
"Zm9v"
);
assert_eq!
(
"foob"
.to_base64
(
STANDARD
),
~
"Zm9vYg=="
);
assert_eq!
(
"fooba"
.to_base64
(
STANDARD
),
~
"Zm9vYmE="
);
assert_eq!
(
"foobar"
.to_base64
(
STANDARD
),
~
"Zm9vYmFy"
);
assert_eq!
(
""
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
""
);
assert_eq!
(
"f"
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
"Zg=="
);
assert_eq!
(
"fo"
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
"Zm8="
);
assert_eq!
(
"foo"
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
"Zm9v"
);
assert_eq!
(
"foob"
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
"Zm9vYg=="
);
assert_eq!
(
"fooba"
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
"Zm9vYmE="
);
assert_eq!
(
"foobar"
.
as_bytes
()
.
to_base64
(
STANDARD
),
~
"Zm9vYmFy"
);
}
#[test]
fn
test_to_base64_line_break
()
{
assert
!
(
!
[
0u8
,
1000
]
.to_base64
(
Config
{
line_length
:
None
,
..
STANDARD
})
.contains
(
"
\r\n
"
));
assert_eq!
(
"foobar"
.to_base64
(
Config
{
line_length
:
Some
(
4
),
..
STANDARD
}),
assert_eq!
(
"foobar"
.as_bytes
()
.to_base64
(
Config
{
line_length
:
Some
(
4
),
..
STANDARD
}),
~
"Zm9v
\r\n
YmFy"
);
}
#[test]
fn
test_to_base64_padding
()
{
assert_eq!
(
"f"
.to_base64
(
Config
{
pad
:
false
,
..
STANDARD
}),
~
"Zg"
);
assert_eq!
(
"fo"
.to_base64
(
Config
{
pad
:
false
,
..
STANDARD
}),
~
"Zm8"
);
assert_eq!
(
"f"
.
as_bytes
()
.
to_base64
(
Config
{
pad
:
false
,
..
STANDARD
}),
~
"Zg"
);
assert_eq!
(
"fo"
.
as_bytes
()
.
to_base64
(
Config
{
pad
:
false
,
..
STANDARD
}),
~
"Zm8"
);
}
#[test]
...
...
@@ -345,7 +301,7 @@ fn test_from_base64_urlsafe() {
#[test]
fn
test_from_base64_invalid_char
()
{
assert
!
(
"Zm$="
.from_base64
()
.is_err
())
assert
!
(
"Zg==$"
.from_base64
()
.is_err
());
assert
!
(
"Zg==$"
.from_base64
()
.is_err
());
}
#[test]
...
...
@@ -369,20 +325,20 @@ fn test_base64_random() {
}
#[bench]
pub
fn
to_base64
(
bh
:
&
mut
BenchHarness
)
{
pub
fn
bench_
to_base64
(
bh
:
&
mut
BenchHarness
)
{
let
s
=
"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム
\
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"
;
do
bh
.iter
{
s
.to_base64
(
STANDARD
);
s
.
as_bytes
()
.
to_base64
(
STANDARD
);
}
bh
.bytes
=
s
.len
()
as
u64
;
}
#[bench]
pub
fn
from_base64
(
bh
:
&
mut
BenchHarness
)
{
pub
fn
bench_
from_base64
(
bh
:
&
mut
BenchHarness
)
{
let
s
=
"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム
\
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"
;
let
b
=
s
.to_base64
(
STANDARD
);
let
b
=
s
.
as_bytes
()
.
to_base64
(
STANDARD
);
do
bh
.iter
{
b
.from_base64
();
}
...
...
src/libextra/extra.rs
浏览文件 @
a54476b0
...
...
@@ -102,6 +102,7 @@
pub
mod
semver
;
pub
mod
fileinput
;
pub
mod
flate
;
pub
mod
hex
;
#[cfg(unicode)]
mod
unicode
;
...
...
src/libextra/hex.rs
0 → 100644
浏览文件 @
a54476b0
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Hex binary-to-text encoding
use
std
::
str
;
use
std
::
vec
;
/// A trait for converting a value to hexadecimal encoding
pub
trait
ToHex
{
/// Converts the value of `self` to a hex value, returning the owned
/// string.
fn
to_hex
(
&
self
)
->
~
str
;
}
static
CHARS
:
&
'static
[
u8
]
=
bytes!
(
"0123456789abcdef"
);
impl
<
'self
>
ToHex
for
&
'self
[
u8
]
{
/**
* Turn a vector of `u8` bytes into a hexadecimal string.
*
* # Example
*
* ~~~ {.rust}
* extern mod extra;
* use extra::hex::ToHex;
*
* fn main () {
* let str = [52,32].to_hex();
* printfln!("%s", str);
* }
* ~~~
*/
fn
to_hex
(
&
self
)
->
~
str
{
let
mut
v
=
vec
::
with_capacity
(
self
.len
()
*
2
);
for
&
byte
in
self
.iter
()
{
v
.push
(
CHARS
[
byte
>>
4
]);
v
.push
(
CHARS
[
byte
&
0xf
]);
}
unsafe
{
str
::
raw
::
from_bytes_owned
(
v
)
}
}
}
/// A trait for converting hexadecimal encoded values
pub
trait
FromHex
{
/// Converts the value of `self`, interpreted as hexadecimal encoded data,
/// into an owned vector of bytes, returning the vector.
fn
from_hex
(
&
self
)
->
Result
<~
[
u8
],
~
str
>
;
}
impl
<
'self
>
FromHex
for
&
'self
str
{
/**
* Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`)
* to the byte values it encodes.
*
* You can use the `from_bytes` function in `std::str`
* to turn a `[u8]` into a string with characters corresponding to those
* values.
*
* # Example
*
* This converts a string literal to hexadecimal and back.
*
* ~~~ {.rust}
* extern mod extra;
* use extra::hex::{FromHex, ToHex};
* use std::str;
*
* fn main () {
* let hello_str = "Hello, World".to_hex();
* printfln!("%s", hello_str);
* let bytes = hello_str.from_hex().unwrap();
* printfln!("%?", bytes);
* let result_str = str::from_bytes(bytes);
* printfln!("%s", result_str);
* }
* ~~~
*/
fn
from_hex
(
&
self
)
->
Result
<~
[
u8
],
~
str
>
{
// This may be an overestimate if there is any whitespace
let
mut
b
=
vec
::
with_capacity
(
self
.len
()
/
2
);
let
mut
modulus
=
0
;
let
mut
buf
=
0u8
;
for
(
idx
,
byte
)
in
self
.byte_iter
()
.enumerate
()
{
buf
<<=
4
;
match
byte
as
char
{
'A'
..
'F'
=>
buf
|
=
byte
-
(
'A'
as
u8
)
+
10
,
'a'
..
'f'
=>
buf
|
=
byte
-
(
'a'
as
u8
)
+
10
,
'0'
..
'9'
=>
buf
|
=
byte
-
(
'0'
as
u8
),
' '
|
'\r'
|
'\n'
|
'\t'
=>
{
buf
>>=
4
;
loop
}
_
=>
return
Err
(
fmt!
(
"Invalid character '%c' at position %u"
,
self
.char_at
(
idx
),
idx
))
}
modulus
+=
1
;
if
modulus
==
2
{
modulus
=
0
;
b
.push
(
buf
);
}
}
match
modulus
{
0
=>
Ok
(
b
),
_
=>
Err
(
~
"Invalid input length"
)
}
}
}
#[cfg(test)]
mod
tests
{
use
test
::
BenchHarness
;
use
hex
::
*
;
#[test]
pub
fn
test_to_hex
()
{
assert_eq!
(
"foobar"
.as_bytes
()
.to_hex
(),
~
"666f6f626172"
);
}
#[test]
pub
fn
test_from_hex_okay
()
{
assert_eq!
(
"666f6f626172"
.from_hex
()
.unwrap
(),
"foobar"
.as_bytes
()
.to_owned
());
assert_eq!
(
"666F6F626172"
.from_hex
()
.unwrap
(),
"foobar"
.as_bytes
()
.to_owned
());
}
#[test]
pub
fn
test_from_hex_odd_len
()
{
assert
!
(
"666"
.from_hex
()
.is_err
());
assert
!
(
"66 6"
.from_hex
()
.is_err
());
}
#[test]
pub
fn
test_from_hex_invalid_char
()
{
assert
!
(
"66y6"
.from_hex
()
.is_err
());
}
#[test]
pub
fn
test_from_hex_ignores_whitespace
()
{
assert_eq!
(
"666f 6f6
\r\n
26172 "
.from_hex
()
.unwrap
(),
"foobar"
.as_bytes
()
.to_owned
());
}
#[test]
pub
fn
test_to_hex_all_bytes
()
{
for
i
in
range
(
0
,
256
)
{
assert_eq!
([
i
as
u8
]
.to_hex
(),
fmt!
(
"%02x"
,
i
as
uint
));
}
}
#[test]
pub
fn
test_from_hex_all_bytes
()
{
for
i
in
range
(
0
,
256
)
{
assert_eq!
(
fmt!
(
"%02x"
,
i
as
uint
)
.from_hex
()
.unwrap
(),
~
[
i
as
u8
]);
assert_eq!
(
fmt!
(
"%02X"
,
i
as
uint
)
.from_hex
()
.unwrap
(),
~
[
i
as
u8
]);
}
}
#[bench]
pub
fn
bench_to_hex
(
bh
:
&
mut
BenchHarness
)
{
let
s
=
"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム
\
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"
;
do
bh
.iter
{
s
.as_bytes
()
.to_hex
();
}
bh
.bytes
=
s
.len
()
as
u64
;
}
#[bench]
pub
fn
bench_from_hex
(
bh
:
&
mut
BenchHarness
)
{
let
s
=
"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム
\
ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"
;
let
b
=
s
.as_bytes
()
.to_hex
();
do
bh
.iter
{
b
.from_hex
();
}
bh
.bytes
=
b
.len
()
as
u64
;
}
}
src/libextra/iter.rs
已删除
100644 → 0
浏览文件 @
aababbba
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*! Composable internal iterators
Internal iterators are functions implementing the protocol used by the `for` loop.
An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal
breaking out of iteration. The adaptors in the module work with any such iterator, not just ones
tied to specific traits. For example:
~~~ {.rust}
println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
~~~
An external iterator object implementing the interface in the `iterator` module can be used as an
internal iterator by calling the `advance` method. For example:
~~~ {.rust}
let xs = [0u, 1, 2, 3, 4, 5];
let ys = [30, 40, 50, 60];
let mut it = xs.iter().chain(ys.iter());
for &x: &uint in it {
println(x.to_str());
}
~~~
Internal iterators provide a subset of the functionality of an external iterator. It's not possible
to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often
much easier to implement.
*/
use
std
::
vec
;
use
std
::
cmp
::
Ord
;
use
std
::
option
::{
Option
,
Some
,
None
};
use
std
::
num
::{
One
,
Zero
};
use
std
::
ops
::{
Add
,
Mul
};
#[allow(missing_doc)]
pub
trait
FromIter
<
T
>
{
/// Build a container with elements from an internal iterator.
///
/// # Example:
///
/// ~~~ {.rust}
/// let xs = ~[1, 2, 3];
/// let ys: ~[int] = do FromIter::from_iter |f| { xs.iter().advance(|x| f(*x)) };
/// assert_eq!(xs, ys);
/// ~~~
pub
fn
from_iter
(
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
Self
;
}
/**
* Return true if `predicate` is true for any values yielded by an internal iterator.
*
* Example:
*
* ~~~ {.rust}
* let xs = ~[1u, 2, 3, 4, 5];
* assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f)));
* assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f)));
* ~~~
*/
#[inline]
pub
fn
any
<
T
>
(
predicate
:
&
fn
(
T
)
->
bool
,
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
bool
{
do
iter
|
x
|
{
predicate
(
x
)
}
}
/**
* Return true if `predicate` is true for all values yielded by an internal iterator.
*
* # Example:
*
* ~~~ {.rust}
* assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f)));
* assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f)));
* ~~~
*/
#[inline]
pub
fn
all
<
T
>
(
predicate
:
&
fn
(
T
)
->
bool
,
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
bool
{
// If we ever break, iter will return false, so this will only return true
// if predicate returns true for everything.
iter
(|
x
|
predicate
(
x
))
}
/**
* Return the first element where `predicate` returns `true`. Return `None` if no element is found.
*
* # Example:
*
* ~~~ {.rust}
* let xs = ~[1u, 2, 3, 4, 5, 6];
* assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4);
* ~~~
*/
#[inline]
pub
fn
find
<
T
>
(
predicate
:
&
fn
(
&
T
)
->
bool
,
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
Option
<
T
>
{
let
mut
ret
=
None
;
do
iter
|
x
|
{
if
predicate
(
&
x
)
{
ret
=
Some
(
x
);
false
}
else
{
true
}
};
ret
}
/**
* Return the largest item yielded by an iterator. Return `None` if the iterator is empty.
*
* # Example:
*
* ~~~ {.rust}
* let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
* assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15);
* ~~~
*/
#[inline]
pub
fn
max
<
T
:
Ord
>
(
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
Option
<
T
>
{
let
mut
result
=
None
;
do
iter
|
x
|
{
match
result
{
Some
(
ref
mut
y
)
=>
{
if
x
>
*
y
{
*
y
=
x
;
}
}
None
=>
result
=
Some
(
x
)
}
true
};
result
}
/**
* Return the smallest item yielded by an iterator. Return `None` if the iterator is empty.
*
* # Example:
*
* ~~~ {.rust}
* let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
* assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5);
* ~~~
*/
#[inline]
pub
fn
min
<
T
:
Ord
>
(
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
Option
<
T
>
{
let
mut
result
=
None
;
do
iter
|
x
|
{
match
result
{
Some
(
ref
mut
y
)
=>
{
if
x
<
*
y
{
*
y
=
x
;
}
}
None
=>
result
=
Some
(
x
)
}
true
};
result
}
/**
* Reduce an iterator to an accumulated value.
*
* # Example:
*
* ~~~ {.rust}
* assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
* ~~~
*/
#[inline]
pub
fn
fold
<
T
,
U
>
(
start
:
T
,
iter
:
&
fn
(
f
:
&
fn
(
U
)
->
bool
)
->
bool
,
f
:
&
fn
(
&
mut
T
,
U
))
->
T
{
let
mut
result
=
start
;
do
iter
|
x
|
{
f
(
&
mut
result
,
x
);
true
};
result
}
/**
* Reduce an iterator to an accumulated value.
*
* `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
* forces the iterator to yield borrowed pointers.
*
* # Example:
*
* ~~~ {.rust}
* fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
* fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
* }
* ~~~
*/
#[inline]
pub
fn
fold_ref
<
T
,
U
>
(
start
:
T
,
iter
:
&
fn
(
f
:
&
fn
(
&
U
)
->
bool
)
->
bool
,
f
:
&
fn
(
&
mut
T
,
&
U
))
->
T
{
let
mut
result
=
start
;
do
iter
|
x
|
{
f
(
&
mut
result
,
x
);
true
};
result
}
/**
* Return the sum of the items yielding by an iterator.
*
* # Example:
*
* ~~~ {.rust}
* let xs: ~[int] = ~[1, 2, 3, 4];
* assert_eq!(do sum |f| { xs.iter().advance(f) }, 10);
* ~~~
*/
#[inline]
pub
fn
sum
<
T
:
Zero
+
Add
<
T
,
T
>>
(
iter
:
&
fn
(
f
:
&
fn
(
&
T
)
->
bool
)
->
bool
)
->
T
{
fold_ref
(
Zero
::
zero
::
<
T
>
(),
iter
,
|
a
,
x
|
*
a
=
a
.add
(
x
))
}
/**
* Return the product of the items yielded by an iterator.
*
* # Example:
*
* ~~~ {.rust}
* let xs: ~[int] = ~[1, 2, 3, 4];
* assert_eq!(do product |f| { xs.iter().advance(f) }, 24);
* ~~~
*/
#[inline]
pub
fn
product
<
T
:
One
+
Mul
<
T
,
T
>>
(
iter
:
&
fn
(
f
:
&
fn
(
&
T
)
->
bool
)
->
bool
)
->
T
{
fold_ref
(
One
::
one
::
<
T
>
(),
iter
,
|
a
,
x
|
*
a
=
a
.mul
(
x
))
}
impl
<
T
>
FromIter
<
T
>
for
~
[
T
]{
#[inline]
pub
fn
from_iter
(
iter
:
&
fn
(
f
:
&
fn
(
T
)
->
bool
)
->
bool
)
->
~
[
T
]
{
let
mut
v
=
~
[];
do
iter
|
x
|
{
v
.push
(
x
);
true
};
v
}
}
#[cfg(test)]
mod
tests
{
use
super
::
*
;
use
prelude
::
*
;
use
int
;
use
uint
;
#[test]
fn
test_from_iter
()
{
let
xs
=
~
[
1
,
2
,
3
];
let
ys
:
~
[
int
]
=
do
FromIter
::
from_iter
|
f
|
{
xs
.iter
()
.advance
(|
x
|
f
(
*
x
))
};
assert_eq!
(
xs
,
ys
);
}
#[test]
fn
test_any
()
{
let
xs
=
~
[
1u
,
2
,
3
,
4
,
5
];
assert
!
(
any
(|
&
x
:
&
uint
|
x
>
2
,
|
f
|
xs
.iter
()
.advance
(
f
)));
assert
!
(
!
any
(|
&
x
:
&
uint
|
x
>
5
,
|
f
|
xs
.iter
()
.advance
(
f
)));
}
#[test]
fn
test_all
()
{
assert
!
(
all
(|
x
:
uint
|
x
<
6
,
|
f
|
uint
::
range
(
1
,
6
,
f
)));
assert
!
(
!
all
(|
x
:
uint
|
x
<
5
,
|
f
|
uint
::
range
(
1
,
6
,
f
)));
}
#[test]
fn
test_find
()
{
let
xs
=
~
[
1u
,
2
,
3
,
4
,
5
,
6
];
assert_eq!
(
*
find
(|
&
&
x
:
&
&
uint
|
x
>
3
,
|
f
|
xs
.iter
()
.advance
(
f
))
.unwrap
(),
4
);
}
#[test]
fn
test_max
()
{
let
xs
=
~
[
8
,
2
,
3
,
1
,
-
5
,
9
,
11
,
15
];
assert_eq!
(
max
(|
f
|
xs
.iter
()
.advance
(
f
))
.unwrap
(),
&
15
);
}
#[test]
fn
test_min
()
{
let
xs
=
~
[
8
,
2
,
3
,
1
,
-
5
,
9
,
11
,
15
];
assert_eq!
(
min
(|
f
|
xs
.iter
()
.advance
(
f
))
.unwrap
(),
&-
5
);
}
#[test]
fn
test_fold
()
{
assert_eq!
(
fold
(
0
i
,
|
f
|
int
::
range
(
1
,
5
,
f
),
|
a
,
x
|
*
a
+=
x
),
10
);
}
#[test]
fn
test_sum
()
{
let
xs
:
~
[
int
]
=
~
[
1
,
2
,
3
,
4
];
assert_eq!
(
do
sum
|
f
|
{
xs
.iter
()
.advance
(
f
)
},
10
);
}
#[test]
fn
test_empty_sum
()
{
let
xs
:
~
[
int
]
=
~
[];
assert_eq!
(
do
sum
|
f
|
{
xs
.iter
()
.advance
(
f
)
},
0
);
}
#[test]
fn
test_product
()
{
let
xs
:
~
[
int
]
=
~
[
1
,
2
,
3
,
4
];
assert_eq!
(
do
product
|
f
|
{
xs
.iter
()
.advance
(
f
)
},
24
);
}
#[test]
fn
test_empty_product
()
{
let
xs
:
~
[
int
]
=
~
[];
assert_eq!
(
do
product
|
f
|
{
xs
.iter
()
.advance
(
f
)
},
1
);
}
}
src/libextra/ringbuf.rs
浏览文件 @
a54476b0
...
...
@@ -696,7 +696,7 @@ fn test_from_iterator() {
let
u
:
~
[
int
]
=
deq
.iter
()
.transform
(|
&
x
|
x
)
.collect
();
assert_eq!
(
u
,
v
);
let
mut
seq
=
iterator
::
Counter
::
new
(
0u
,
2
)
.take_
(
256
);
let
mut
seq
=
iterator
::
count
(
0u
,
2
)
.take_
(
256
);
let
deq
:
RingBuf
<
uint
>
=
seq
.collect
();
for
(
i
,
&
x
)
in
deq
.iter
()
.enumerate
()
{
assert_eq!
(
2
*
i
,
x
);
...
...
src/librustc/middle/trans/foreign.rs
浏览文件 @
a54476b0
...
...
@@ -888,6 +888,11 @@ fn count_zeros_intrinsic(bcx: @mut Block, name: &'static str) {
let
offset
=
get_param
(
decl
,
first_real_arg
+
1
);
Ret
(
bcx
,
GEP
(
bcx
,
ptr
,
[
offset
]));
}
"offset_inbounds"
=>
{
let
ptr
=
get_param
(
decl
,
first_real_arg
);
let
offset
=
get_param
(
decl
,
first_real_arg
+
1
);
Ret
(
bcx
,
InBoundsGEP
(
bcx
,
ptr
,
[
offset
]));
}
"memcpy32"
=>
memcpy_intrinsic
(
bcx
,
"llvm.memcpy.p0i8.p0i8.i32"
,
substs
.tys
[
0
],
32
),
"memcpy64"
=>
memcpy_intrinsic
(
bcx
,
"llvm.memcpy.p0i8.p0i8.i64"
,
substs
.tys
[
0
],
64
),
"memmove32"
=>
memcpy_intrinsic
(
bcx
,
"llvm.memmove.p0i8.p0i8.i32"
,
substs
.tys
[
0
],
32
),
...
...
src/librustc/middle/trans/type_use.rs
浏览文件 @
a54476b0
...
...
@@ -148,7 +148,8 @@ fn store_type_uses(cx: Context, fn_id: def_id) -> @~[type_uses] {
"visit_tydesc"
|
"forget"
|
"frame_address"
|
"morestack_addr"
=>
0
,
"offset"
|
"memcpy32"
|
"memcpy64"
|
"memmove32"
|
"memmove64"
|
"offset"
|
"offset_inbounds"
|
"memcpy32"
|
"memcpy64"
|
"memmove32"
|
"memmove64"
|
"memset32"
|
"memset64"
=>
use_repr
,
"sqrtf32"
|
"sqrtf64"
|
"powif32"
|
"powif64"
|
...
...
src/librustc/middle/typeck/check/mod.rs
浏览文件 @
a54476b0
...
...
@@ -3481,6 +3481,20 @@ fn param(ccx: @mut CrateCtxt, n: uint) -> ty::t {
mutbl
:
ast
::
m_imm
}))
}
"offset_inbounds"
=>
{
(
1
,
~
[
ty
::
mk_ptr
(
tcx
,
ty
::
mt
{
ty
:
param
(
ccx
,
0
),
mutbl
:
ast
::
m_imm
}),
ty
::
mk_int
()
],
ty
::
mk_ptr
(
tcx
,
ty
::
mt
{
ty
:
param
(
ccx
,
0
),
mutbl
:
ast
::
m_imm
}))
}
"memcpy32"
=>
{
(
1
,
~
[
...
...
src/librustdoc/markdown_pass.rs
浏览文件 @
a54476b0
...
...
@@ -637,7 +637,7 @@ fn should_request_new_writer_for_each_page() {
let
doc
=
(
page_pass
::
mk_pass
(
config
::
DocPerMod
)
.f
)(
srv
,
doc
);
write_markdown
(
doc
,
writer_factory
);
// We expect two pages to have been written
do
2
.times
{
for
_
in
range
(
0
,
2u
)
{
po
.recv
();
}
}
...
...
@@ -649,7 +649,7 @@ fn should_write_title_for_each_page() {
~
"#[link(name =
\"
core
\"
)]; mod a { }"
);
let
doc
=
(
page_pass
::
mk_pass
(
config
::
DocPerMod
)
.f
)(
srv
,
doc
);
write_markdown
(
doc
,
writer_factory
);
do
2
.times
{
for
_
in
range
(
0
,
2u
)
{
let
(
page
,
markdown
)
=
po
.recv
();
match
page
{
doc
::
CratePage
(
_
)
=>
{
...
...
src/librusti/rusti.rs
浏览文件 @
a54476b0
...
...
@@ -565,7 +565,10 @@ fn repl() -> Repl {
}
}
#[cfg(not(target_word_size
=
"32"
))]
// FIXME: #7220 rusti on 32bit mac doesn't work.
// FIXME: #7641 rusti on 32bit linux cross compile doesn't work
// FIXME: #7115 re-enable once LLVM has been upgraded
#[cfg(thiswillneverbeacfgflag)]
fn
run_program
(
prog
:
&
str
)
{
let
mut
r
=
repl
();
for
cmd
in
prog
.split_iter
(
'\n'
)
{
...
...
@@ -574,9 +577,6 @@ fn run_program(prog: &str) {
"the command '%s' failed"
,
cmd
);
}
}
// FIXME: #7220 rusti on 32bit mac doesn't work
// FIXME: #7641 rusti on 32bit linux cross compile doesn't work
#[cfg(target_word_size
=
"32"
)]
fn
run_program
(
_
:
&
str
)
{}
#[test]
...
...
@@ -594,12 +594,13 @@ fn regression_5784() {
run_program
(
"let a = 3;"
);
}
#[test]
#[test]
#[ignore]
fn
new_tasks
()
{
// XXX: can't spawn new tasks because the JIT code is cleaned up
// after the main function is done.
run_program
(
"
use std::task::try;
try( || println(
\"
Please don't segfault
\"
) );
do try { println(
\"
Please?
\"
); }
spawn( || println(
\"
Please don't segfault
\"
) );
do spawn { println(
\"
Please?
\"
); }
"
);
}
...
...
src/libstd/borrow.rs
浏览文件 @
a54476b0
...
...
@@ -58,3 +58,15 @@ fn gt(&self, other: & &'self T) -> bool {
*
(
*
self
)
>
*
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
'self
,
T
:
TotalOrd
>
TotalOrd
for
&
'self
T
{
#[inline]
fn
cmp
(
&
self
,
other
:
&
&
'self
T
)
->
Ordering
{
(
**
self
)
.cmp
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
'self
,
T
:
TotalEq
>
TotalEq
for
&
'self
T
{
#[inline]
fn
equals
(
&
self
,
other
:
&
&
'self
T
)
->
bool
{
(
**
self
)
.equals
(
*
other
)
}
}
src/libstd/cmp.rs
浏览文件 @
a54476b0
...
...
@@ -153,7 +153,6 @@ pub fn cmp2<A:TotalOrd,B:TotalOrd>(
Return `o1` if it is not `Equal`, otherwise `o2`. Simulates the
lexical ordering on a type `(int, int)`.
*/
// used in deriving code in libsyntax
#[inline]
pub
fn
lexical_ordering
(
o1
:
Ordering
,
o2
:
Ordering
)
->
Ordering
{
match
o1
{
...
...
src/libstd/iterator.rs
浏览文件 @
a54476b0
...
...
@@ -18,7 +18,7 @@
*/
use
cmp
;
use
num
::{
Zero
,
One
};
use
num
::{
Zero
,
One
,
Saturating
};
use
option
::{
Option
,
Some
,
None
};
use
ops
::{
Add
,
Mul
};
use
cmp
::
Ord
;
...
...
@@ -313,7 +313,7 @@ fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>)
/// ~~~ {.rust}
/// let xs = [2u, 3];
/// let ys = [0u, 1, 0, 1, 2];
/// let mut it = xs.iter().flat_map_(|&x|
Counter::new
(0u, 1).take_(x));
/// let mut it = xs.iter().flat_map_(|&x|
count
(0u, 1).take_(x));
/// // Check that `it` has the same elements as `ys`
/// let mut i = 0;
/// for x: uint in it {
...
...
@@ -351,7 +351,7 @@ fn flat_map_<'r, B, U: Iterator<B>>(self, f: &'r fn(A) -> U)
/// ~~~ {.rust}
/// use std::iterator::Counter;
///
/// for i in
Counter::new
(0, 10) {
/// for i in
count
(0, 10) {
/// printfln!("%d", i);
/// }
/// ~~~
...
...
@@ -723,7 +723,7 @@ pub trait MultiplicativeIterator<A> {
/// use std::iterator::Counter;
///
/// fn factorial(n: uint) -> uint {
///
Counter::new
(1u, 1).take_while(|&i| i <= n).product()
///
count
(1u, 1).take_while(|&i| i <= n).product()
/// }
/// assert!(factorial(0) == 1);
/// assert!(factorial(1) == 1);
...
...
@@ -790,7 +790,7 @@ pub trait ClonableIterator {
/// # Example
///
/// ~~~ {.rust}
/// let a =
Counter::new
(1,1).take_(1);
/// let a =
count
(1,1).take_(1);
/// let mut cy = a.cycle();
/// assert_eq!(cy.next(), Some(1));
/// assert_eq!(cy.next(), Some(1));
...
...
@@ -884,15 +884,10 @@ fn size_hint(&self) -> (uint, Option<uint>) {
let
(
a_lower
,
a_upper
)
=
self
.a
.size_hint
();
let
(
b_lower
,
b_upper
)
=
self
.b
.size_hint
();
let
lower
=
if
uint
::
max_value
-
a_lower
<
b_lower
{
uint
::
max_value
}
else
{
a_lower
+
b_lower
};
let
lower
=
a_lower
.saturating_add
(
b_lower
);
let
upper
=
match
(
a_upper
,
b_upper
)
{
(
Some
(
x
),
Some
(
y
))
if
uint
::
max_value
-
x
<
y
=>
Some
(
uint
::
max_value
),
(
Some
(
x
),
Some
(
y
))
=>
Some
(
x
+
y
),
(
Some
(
x
),
Some
(
y
))
=>
Some
(
x
.saturating_add
(
y
)),
_
=>
None
};
...
...
@@ -916,12 +911,7 @@ impl<A, T: RandomAccessIterator<A>, U: RandomAccessIterator<A>> RandomAccessIter
#[inline]
fn
indexable
(
&
self
)
->
uint
{
let
(
a
,
b
)
=
(
self
.a
.indexable
(),
self
.b
.indexable
());
let
total
=
a
+
b
;
if
total
<
a
||
total
<
b
{
uint
::
max_value
}
else
{
total
}
a
.saturating_add
(
b
)
}
#[inline]
...
...
@@ -1273,11 +1263,10 @@ fn next(&mut self) -> Option<A> {
fn
size_hint
(
&
self
)
->
(
uint
,
Option
<
uint
>
)
{
let
(
lower
,
upper
)
=
self
.iter
.size_hint
();
let
lower
=
if
lower
>=
self
.n
{
lower
-
self
.n
}
else
{
0
}
;
let
lower
=
lower
.saturating_sub
(
self
.n
)
;
let
upper
=
match
upper
{
Some
(
x
)
if
x
>=
self
.n
=>
Some
(
x
-
self
.n
),
Some
(
_
)
=>
Some
(
0
),
Some
(
x
)
=>
Some
(
x
.saturating_sub
(
self
.n
)),
None
=>
None
};
...
...
@@ -1288,12 +1277,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
impl
<
A
,
T
:
RandomAccessIterator
<
A
>>
RandomAccessIterator
<
A
>
for
Skip
<
T
>
{
#[inline]
fn
indexable
(
&
self
)
->
uint
{
let
N
=
self
.iter
.indexable
();
if
N
<
self
.n
{
0
}
else
{
N
-
self
.n
}
self
.iter
.indexable
()
.saturating_sub
(
self
.n
)
}
#[inline]
...
...
@@ -1316,10 +1300,9 @@ pub struct Take<T> {
impl
<
A
,
T
:
Iterator
<
A
>>
Iterator
<
A
>
for
Take
<
T
>
{
#[inline]
fn
next
(
&
mut
self
)
->
Option
<
A
>
{
let
next
=
self
.iter
.next
();
if
self
.n
!=
0
{
self
.n
-=
1
;
next
self
.iter
.next
()
}
else
{
None
}
...
...
@@ -1410,9 +1393,10 @@ fn next(&mut self) -> Option<B> {
fn
size_hint
(
&
self
)
->
(
uint
,
Option
<
uint
>
)
{
let
(
flo
,
fhi
)
=
self
.frontiter
.map_default
((
0
,
Some
(
0
)),
|
it
|
it
.size_hint
());
let
(
blo
,
bhi
)
=
self
.backiter
.map_default
((
0
,
Some
(
0
)),
|
it
|
it
.size_hint
());
let
lo
=
flo
.saturating_add
(
blo
);
match
(
self
.iter
.size_hint
(),
fhi
,
bhi
)
{
((
0
,
Some
(
0
)),
Some
(
a
),
Some
(
b
))
=>
(
flo
+
blo
,
Some
(
a
+
b
)),
_
=>
(
flo
+
b
lo
,
None
)
((
0
,
Some
(
0
)),
Some
(
a
),
Some
(
b
))
=>
(
lo
,
Some
(
a
.saturating_add
(
b
)
)),
_
=>
(
lo
,
None
)
}
}
}
...
...
@@ -1527,12 +1511,10 @@ pub struct Counter<A> {
step
:
A
}
impl
<
A
>
Counter
<
A
>
{
/// Creates a new counter with the specified start/step
#[inline]
pub
fn
new
(
start
:
A
,
step
:
A
)
->
Counter
<
A
>
{
Counter
{
state
:
start
,
step
:
step
}
}
/// Creates a new counter with the specified start/step
#[inline]
pub
fn
count
<
A
>
(
start
:
A
,
step
:
A
)
->
Counter
<
A
>
{
Counter
{
state
:
start
,
step
:
step
}
}
/// A range of numbers from [0, N)
...
...
@@ -1619,7 +1601,7 @@ mod tests {
#[test]
fn
test_counter_from_iter
()
{
let
mut
it
=
Counter
::
new
(
0
,
5
)
.take_
(
10
);
let
mut
it
=
count
(
0
,
5
)
.take_
(
10
);
let
xs
:
~
[
int
]
=
FromIterator
::
from_iterator
(
&
mut
it
);
assert_eq!
(
xs
,
~
[
0
,
5
,
10
,
15
,
20
,
25
,
30
,
35
,
40
,
45
]);
}
...
...
@@ -1637,7 +1619,7 @@ fn test_iterator_chain() {
}
assert_eq!
(
i
,
expected
.len
());
let
ys
=
Counter
::
new
(
30u
,
10
)
.take_
(
4
);
let
ys
=
count
(
30u
,
10
)
.take_
(
4
);
let
mut
it
=
xs
.iter
()
.transform
(|
&
x
|
x
)
.chain_
(
ys
);
let
mut
i
=
0
;
for
x
in
it
{
...
...
@@ -1649,7 +1631,7 @@ fn test_iterator_chain() {
#[test]
fn
test_filter_map
()
{
let
mut
it
=
Counter
::
new
(
0u
,
1u
)
.take_
(
10
)
let
mut
it
=
count
(
0u
,
1u
)
.take_
(
10
)
.filter_map
(|
x
|
if
x
.is_even
()
{
Some
(
x
*
x
)
}
else
{
None
});
assert_eq!
(
it
.collect
::
<~
[
uint
]
>
(),
~
[
0
*
0
,
2
*
2
,
4
*
4
,
6
*
6
,
8
*
8
]);
}
...
...
@@ -1738,7 +1720,7 @@ fn add(old: &mut int, new: &uint) -> Option<float> {
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
|
Counter
::
new
(
x
,
1
)
.take_
(
3
));
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
]);
...
...
@@ -1785,13 +1767,13 @@ fn count(st: &mut uint) -> Option<uint> {
#[test]
fn
test_cycle
()
{
let
cycle_len
=
3
;
let
it
=
Counter
::
new
(
0u
,
1
)
.take_
(
cycle_len
)
.cycle
();
let
it
=
count
(
0u
,
1
)
.take_
(
cycle_len
)
.cycle
();
assert_eq!
(
it
.size_hint
(),
(
uint
::
max_value
,
None
));
for
(
i
,
x
)
in
it
.take_
(
100
)
.enumerate
()
{
assert_eq!
(
i
%
cycle_len
,
x
);
}
let
mut
it
=
Counter
::
new
(
0u
,
1
)
.take_
(
0
)
.cycle
();
let
mut
it
=
count
(
0u
,
1
)
.take_
(
0
)
.cycle
();
assert_eq!
(
it
.size_hint
(),
(
0
,
Some
(
0
)));
assert_eq!
(
it
.next
(),
None
);
}
...
...
@@ -1853,7 +1835,7 @@ fn test_iterator_min() {
#[test]
fn
test_iterator_size_hint
()
{
let
c
=
Counter
::
new
(
0
,
1
);
let
c
=
count
(
0
,
1
);
let
v
=
&
[
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
];
let
v2
=
&
[
10
,
11
,
12
];
let
vi
=
v
.iter
();
...
...
src/libstd/managed.rs
浏览文件 @
a54476b0
...
...
@@ -12,7 +12,7 @@
use
ptr
::
to_unsafe_ptr
;
#[cfg(not(test))]
use
cmp
::
{
Eq
,
Ord
}
;
#[cfg(not(test))]
use
cmp
::
*
;
pub
static
RC_MANAGED_UNIQUE
:
uint
=
(
-
2
)
as
uint
;
pub
static
RC_IMMORTAL
:
uint
=
0x77777777
;
...
...
@@ -71,6 +71,29 @@ fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) }
fn
gt
(
&
self
,
other
:
&@
mut
T
)
->
bool
{
*
(
*
self
)
>
*
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
T
:
TotalOrd
>
TotalOrd
for
@
T
{
#[inline]
fn
cmp
(
&
self
,
other
:
&@
T
)
->
Ordering
{
(
**
self
)
.cmp
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
T
:
TotalOrd
>
TotalOrd
for
@
mut
T
{
#[inline]
fn
cmp
(
&
self
,
other
:
&@
mut
T
)
->
Ordering
{
(
**
self
)
.cmp
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
T
:
TotalEq
>
TotalEq
for
@
T
{
#[inline]
fn
equals
(
&
self
,
other
:
&@
T
)
->
bool
{
(
**
self
)
.equals
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
T
:
TotalEq
>
TotalEq
for
@
mut
T
{
#[inline]
fn
equals
(
&
self
,
other
:
&@
mut
T
)
->
bool
{
(
**
self
)
.equals
(
*
other
)
}
}
#[test]
fn
test
()
{
let
x
=
@
3
;
...
...
src/libstd/num/num.rs
浏览文件 @
a54476b0
...
...
@@ -466,6 +466,56 @@ fn zero() -> ~T { ~Zero::zero() }
fn
is_zero
(
&
self
)
->
bool
{
(
**
self
)
.is_zero
()
}
}
/// Saturating math operations
pub
trait
Saturating
:
Int
{
/// Saturating addition operator.
/// Returns a+b, saturating at the numeric bounds instead of overflowing.
#[inline]
fn
saturating_add
(
self
,
v
:
Self
)
->
Self
{
let
x
=
self
+
v
;
if
v
>=
Zero
::
zero
()
{
if
x
<
self
{
// overflow
Bounded
::
max_value
::
<
Self
>
()
}
else
{
x
}
}
else
{
if
x
>
self
{
// underflow
Bounded
::
min_value
::
<
Self
>
()
}
else
{
x
}
}
}
/// Saturating subtraction operator.
/// Returns a-b, saturating at the numeric bounds instead of overflowing.
#[inline]
fn
saturating_sub
(
self
,
v
:
Self
)
->
Self
{
let
x
=
self
-
v
;
if
v
>=
Zero
::
zero
()
{
if
x
>
self
{
// underflow
Bounded
::
min_value
::
<
Self
>
()
}
else
{
x
}
}
else
{
if
x
<
self
{
// overflow
Bounded
::
max_value
::
<
Self
>
()
}
else
{
x
}
}
}
}
impl
Saturating
for
int
{}
impl
Saturating
for
i8
{}
impl
Saturating
for
i16
{}
impl
Saturating
for
i32
{}
impl
Saturating
for
i64
{}
impl
Saturating
for
uint
{}
impl
Saturating
for
u8
{}
impl
Saturating
for
u16
{}
impl
Saturating
for
u32
{}
impl
Saturating
for
u64
{}
/// Helper function for testing numeric operations
#[cfg(test)]
pub
fn
test_num
<
T
:
Num
+
NumCast
>
(
ten
:
T
,
two
:
T
)
{
...
...
@@ -482,64 +532,111 @@ pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
assert_eq!
(
ten
.rem
(
&
two
),
ten
%
two
);
}
macro_rules!
test_cast_20
(
(
$_20:expr
)
=>
({
let
_20
=
$_20
;
assert_eq!
(
20u
,
_20
.to_uint
());
assert_eq!
(
20u8
,
_20
.to_u8
());
assert_eq!
(
20u16
,
_20
.to_u16
());
assert_eq!
(
20u32
,
_20
.to_u32
());
assert_eq!
(
20u64
,
_20
.to_u64
());
assert_eq!
(
20
i
,
_20
.to_int
());
assert_eq!
(
20i8
,
_20
.to_i8
());
assert_eq!
(
20i16
,
_20
.to_i16
());
assert_eq!
(
20i32
,
_20
.to_i32
());
assert_eq!
(
20i64
,
_20
.to_i64
());
assert_eq!
(
20
f
,
_20
.to_float
());
assert_eq!
(
20f32
,
_20
.to_f32
());
assert_eq!
(
20f64
,
_20
.to_f64
());
assert_eq!
(
_20
,
NumCast
::
from
(
20u
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u8
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u16
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u32
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u64
));
assert_eq!
(
_20
,
NumCast
::
from
(
20
i
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i8
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i16
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i32
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i64
));
assert_eq!
(
_20
,
NumCast
::
from
(
20
f
));
assert_eq!
(
_20
,
NumCast
::
from
(
20f32
));
assert_eq!
(
_20
,
NumCast
::
from
(
20f64
));
assert_eq!
(
_20
,
cast
(
20u
));
assert_eq!
(
_20
,
cast
(
20u8
));
assert_eq!
(
_20
,
cast
(
20u16
));
assert_eq!
(
_20
,
cast
(
20u32
));
assert_eq!
(
_20
,
cast
(
20u64
));
assert_eq!
(
_20
,
cast
(
20
i
));
assert_eq!
(
_20
,
cast
(
20i8
));
assert_eq!
(
_20
,
cast
(
20i16
));
assert_eq!
(
_20
,
cast
(
20i32
));
assert_eq!
(
_20
,
cast
(
20i64
));
assert_eq!
(
_20
,
cast
(
20
f
));
assert_eq!
(
_20
,
cast
(
20f32
));
assert_eq!
(
_20
,
cast
(
20f64
));
})
)
#[cfg(test)]
mod
tests
{
use
super
::
*
;
macro_rules!
test_cast_20
(
(
$_20:expr
)
=>
({
let
_20
=
$_20
;
assert_eq!
(
20u
,
_20
.to_uint
());
assert_eq!
(
20u8
,
_20
.to_u8
());
assert_eq!
(
20u16
,
_20
.to_u16
());
assert_eq!
(
20u32
,
_20
.to_u32
());
assert_eq!
(
20u64
,
_20
.to_u64
());
assert_eq!
(
20
i
,
_20
.to_int
());
assert_eq!
(
20i8
,
_20
.to_i8
());
assert_eq!
(
20i16
,
_20
.to_i16
());
assert_eq!
(
20i32
,
_20
.to_i32
());
assert_eq!
(
20i64
,
_20
.to_i64
());
assert_eq!
(
20
f
,
_20
.to_float
());
assert_eq!
(
20f32
,
_20
.to_f32
());
assert_eq!
(
20f64
,
_20
.to_f64
());
assert_eq!
(
_20
,
NumCast
::
from
(
20u
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u8
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u16
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u32
));
assert_eq!
(
_20
,
NumCast
::
from
(
20u64
));
assert_eq!
(
_20
,
NumCast
::
from
(
20
i
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i8
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i16
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i32
));
assert_eq!
(
_20
,
NumCast
::
from
(
20i64
));
assert_eq!
(
_20
,
NumCast
::
from
(
20
f
));
assert_eq!
(
_20
,
NumCast
::
from
(
20f32
));
assert_eq!
(
_20
,
NumCast
::
from
(
20f64
));
assert_eq!
(
_20
,
cast
(
20u
));
assert_eq!
(
_20
,
cast
(
20u8
));
assert_eq!
(
_20
,
cast
(
20u16
));
assert_eq!
(
_20
,
cast
(
20u32
));
assert_eq!
(
_20
,
cast
(
20u64
));
assert_eq!
(
_20
,
cast
(
20
i
));
assert_eq!
(
_20
,
cast
(
20i8
));
assert_eq!
(
_20
,
cast
(
20i16
));
assert_eq!
(
_20
,
cast
(
20i32
));
assert_eq!
(
_20
,
cast
(
20i64
));
assert_eq!
(
_20
,
cast
(
20
f
));
assert_eq!
(
_20
,
cast
(
20f32
));
assert_eq!
(
_20
,
cast
(
20f64
));
})
)
#[test]
fn
test_u8_cast
()
{
test_cast_20!
(
20u8
)
}
#[test]
fn
test_u16_cast
()
{
test_cast_20!
(
20u16
)
}
#[test]
fn
test_u32_cast
()
{
test_cast_20!
(
20u32
)
}
#[test]
fn
test_u64_cast
()
{
test_cast_20!
(
20u64
)
}
#[test]
fn
test_uint_cast
()
{
test_cast_20!
(
20u
)
}
#[test]
fn
test_i8_cast
()
{
test_cast_20!
(
20i8
)
}
#[test]
fn
test_i16_cast
()
{
test_cast_20!
(
20i16
)
}
#[test]
fn
test_i32_cast
()
{
test_cast_20!
(
20i32
)
}
#[test]
fn
test_i64_cast
()
{
test_cast_20!
(
20i64
)
}
#[test]
fn
test_int_cast
()
{
test_cast_20!
(
20
i
)
}
#[test]
fn
test_f32_cast
()
{
test_cast_20!
(
20f32
)
}
#[test]
fn
test_f64_cast
()
{
test_cast_20!
(
20f64
)
}
#[test]
fn
test_float_cast
()
{
test_cast_20!
(
20
f
)
}
#[test]
fn
test_saturating_add_uint
()
{
use
uint
::
max_value
;
assert_eq!
(
3u
.saturating_add
(
5u
),
8u
);
assert_eq!
(
3u
.saturating_add
(
max_value
-
1
),
max_value
);
assert_eq!
(
max_value
.saturating_add
(
max_value
),
max_value
);
assert_eq!
((
max_value
-
2
)
.saturating_add
(
1
),
max_value
-
1
);
}
#[test]
fn
test_saturating_sub_uint
()
{
use
uint
::
max_value
;
assert_eq!
(
5u
.saturating_sub
(
3u
),
2u
);
assert_eq!
(
3u
.saturating_sub
(
5u
),
0u
);
assert_eq!
(
0u
.saturating_sub
(
1u
),
0u
);
assert_eq!
((
max_value
-
1
)
.saturating_sub
(
max_value
),
0
);
}
#[test]
fn
test_u8_cast
()
{
test_cast_20!
(
20u8
)
}
#[test]
fn
test_u16_cast
()
{
test_cast_20!
(
20u16
)
}
#[test]
fn
test_u32_cast
()
{
test_cast_20!
(
20u32
)
}
#[test]
fn
test_u64_cast
()
{
test_cast_20!
(
20u64
)
}
#[test]
fn
test_uint_cast
()
{
test_cast_20!
(
20u
)
}
#[test]
fn
test_i8_cast
()
{
test_cast_20!
(
20i8
)
}
#[test]
fn
test_i16_cast
()
{
test_cast_20!
(
20i16
)
}
#[test]
fn
test_i32_cast
()
{
test_cast_20!
(
20i32
)
}
#[test]
fn
test_i64_cast
()
{
test_cast_20!
(
20i64
)
}
#[test]
fn
test_int_cast
()
{
test_cast_20!
(
20
i
)
}
#[test]
fn
test_f32_cast
()
{
test_cast_20!
(
20f32
)
}
#[test]
fn
test_f64_cast
()
{
test_cast_20!
(
20f64
)
}
#[test]
fn
test_float_cast
()
{
test_cast_20!
(
20
f
)
}
#[test]
fn
test_saturating_add_int
()
{
use
int
::{
min_value
,
max_value
};
assert_eq!
(
3
i
.saturating_add
(
5
i
),
8
i
);
assert_eq!
(
3
i
.saturating_add
(
max_value
-
1
),
max_value
);
assert_eq!
(
max_value
.saturating_add
(
max_value
),
max_value
);
assert_eq!
((
max_value
-
2
)
.saturating_add
(
1
),
max_value
-
1
);
assert_eq!
(
3
i
.saturating_add
(
-
5
i
),
-
2
i
);
assert_eq!
(
min_value
.saturating_add
(
-
1
i
),
min_value
);
assert_eq!
((
-
2
i
)
.saturating_add
(
-
max_value
),
min_value
);
}
#[test]
fn
test_saturating_sub_int
()
{
use
int
::{
min_value
,
max_value
};
assert_eq!
(
3
i
.saturating_sub
(
5
i
),
-
2
i
);
assert_eq!
(
min_value
.saturating_sub
(
1
i
),
min_value
);
assert_eq!
((
-
2
i
)
.saturating_sub
(
max_value
),
min_value
);
assert_eq!
(
3
i
.saturating_sub
(
-
5
i
),
8
i
);
assert_eq!
(
3
i
.saturating_sub
(
-
(
max_value
-
1
)),
max_value
);
assert_eq!
(
max_value
.saturating_sub
(
-
max_value
),
max_value
);
assert_eq!
((
max_value
-
2
)
.saturating_sub
(
-
1
),
max_value
-
1
);
}
}
src/libstd/owned.rs
浏览文件 @
a54476b0
...
...
@@ -10,7 +10,7 @@
//! Operations on unique pointer types
#[cfg(not(test))]
use
cmp
::
{
Eq
,
Ord
}
;
#[cfg(not(test))]
use
cmp
::
*
;
#[cfg(not(test))]
impl
<
T
:
Eq
>
Eq
for
~
T
{
...
...
@@ -31,3 +31,15 @@ fn ge(&self, other: &~T) -> bool { *(*self) >= *(*other) }
#[inline]
fn
gt
(
&
self
,
other
:
&~
T
)
->
bool
{
*
(
*
self
)
>
*
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
T
:
TotalOrd
>
TotalOrd
for
~
T
{
#[inline]
fn
cmp
(
&
self
,
other
:
&~
T
)
->
Ordering
{
(
**
self
)
.cmp
(
*
other
)
}
}
#[cfg(not(test))]
impl
<
T
:
TotalEq
>
TotalEq
for
~
T
{
#[inline]
fn
equals
(
&
self
,
other
:
&~
T
)
->
bool
{
(
**
self
)
.equals
(
*
other
)
}
}
src/libstd/prelude.rs
浏览文件 @
a54476b0
...
...
@@ -50,6 +50,7 @@
pub
use
container
::{
Container
,
Mutable
,
Map
,
MutableMap
,
Set
,
MutableSet
};
pub
use
hash
::
Hash
;
pub
use
iter
::
Times
;
pub
use
iterator
::
Extendable
;
pub
use
iterator
::{
Iterator
,
IteratorUtil
,
DoubleEndedIterator
,
DoubleEndedIteratorUtil
};
pub
use
iterator
::{
ClonableIterator
,
OrdIterator
};
pub
use
num
::{
Num
,
NumCast
};
...
...
@@ -65,7 +66,7 @@
pub
use
ptr
::
RawPtr
;
pub
use
ascii
::{
Ascii
,
AsciiCast
,
OwnedAsciiCast
,
AsciiStr
,
ToBytesConsume
};
pub
use
str
::{
Str
,
StrVector
,
StrSlice
,
OwnedStr
};
pub
use
from_str
::
{
FromStr
}
;
pub
use
from_str
::
FromStr
;
pub
use
to_bytes
::
IterBytes
;
pub
use
to_str
::{
ToStr
,
ToStrConsume
};
pub
use
tuple
::{
CopyableTuple
,
ImmutableTuple
,
ExtendedTupleOps
};
...
...
src/libstd/ptr.rs
浏览文件 @
a54476b0
...
...
@@ -272,6 +272,7 @@ pub trait RawPtr<T> {
fn
is_not_null
(
&
self
)
->
bool
;
unsafe
fn
to_option
(
&
self
)
->
Option
<&
T
>
;
fn
offset
(
&
self
,
count
:
int
)
->
Self
;
unsafe
fn
offset_inbounds
(
self
,
count
:
int
)
->
Self
;
}
/// Extension methods for immutable pointers
...
...
@@ -304,6 +305,22 @@ unsafe fn to_option(&self) -> Option<&T> {
/// Calculates the offset from a pointer.
#[inline]
fn
offset
(
&
self
,
count
:
int
)
->
*
T
{
offset
(
*
self
,
count
)
}
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
/// the object, or one-byte-past-the-end.
#[inline]
#[cfg(stage0)]
unsafe
fn
offset_inbounds
(
self
,
count
:
int
)
->
*
T
{
intrinsics
::
offset
(
self
,
count
)
}
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
/// the object, or one-byte-past-the-end.
#[inline]
#[cfg(not(stage0))]
unsafe
fn
offset_inbounds
(
self
,
count
:
int
)
->
*
T
{
intrinsics
::
offset_inbounds
(
self
,
count
)
}
}
/// Extension methods for mutable pointers
...
...
@@ -336,6 +353,30 @@ unsafe fn to_option(&self) -> Option<&T> {
/// Calculates the offset from a mutable pointer.
#[inline]
fn
offset
(
&
self
,
count
:
int
)
->
*
mut
T
{
mut_offset
(
*
self
,
count
)
}
/// 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
/// undefined behaviour.
///
/// This method should be preferred over `offset` when the guarantee can be
/// satisfied, to enable better optimization.
#[inline]
#[cfg(stage0)]
unsafe
fn
offset_inbounds
(
self
,
count
:
int
)
->
*
mut
T
{
intrinsics
::
offset
(
self
as
*
T
,
count
)
as
*
mut
T
}
/// 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
/// undefined behaviour.
///
/// This method should be preferred over `offset` when the guarantee can be
/// satisfied, to enable better optimization.
#[inline]
#[cfg(not(stage0))]
unsafe
fn
offset_inbounds
(
self
,
count
:
int
)
->
*
mut
T
{
intrinsics
::
offset_inbounds
(
self
as
*
T
,
count
)
as
*
mut
T
}
}
// Equality for pointers
...
...
src/libstd/str.rs
浏览文件 @
a54476b0
...
...
@@ -3483,19 +3483,22 @@ fn test_char_range_at_reverse_underflow() {
fn
test_add
()
{
#[allow(unnecessary_allocation)]
;
macro_rules!
t
(
(
$s1:expr
,
$s2:expr
,
$e:expr
)
=>
{
assert_eq!
(
$s1
+
$s2
,
$e
);
assert_eq!
(
$s1
.to_owned
()
+
$s2
,
$e
);
assert_eq!
(
$s1
.to_managed
()
+
$s2
,
$e
);
}
(
$s1:expr
,
$s2:expr
,
$e:expr
)
=>
{
{
let
s1
=
$s1
;
let
s2
=
$s2
;
let
e
=
$e
;
assert_eq!
(
s1
+
s2
,
e
.to_owned
());
assert_eq!
(
s1
.to_owned
()
+
s2
,
e
.to_owned
());
assert_eq!
(
s1
.to_managed
()
+
s2
,
e
.to_owned
());
}
}
);
t!
(
"foo"
,
"bar"
,
~
"foobar"
);
t!
(
"foo"
,
@
"bar"
,
~
"foobar"
);
t!
(
"foo"
,
~
"bar"
,
~
"foobar"
);
t!
(
"ศไทย中"
,
"华Việt Nam"
,
~
"ศไทย中华Việt Nam"
);
t!
(
"ศไทย中"
,
@
"华Việt Nam"
,
~
"ศไทย中华Việt Nam"
);
t!
(
"ศไทย中"
,
~
"华Việt Nam"
,
~
"ศไทย中华Việt Nam"
);
t!
(
"foo"
,
"bar"
,
"foobar"
);
t!
(
"foo"
,
@
"bar"
,
"foobar"
);
t!
(
"foo"
,
~
"bar"
,
"foobar"
);
t!
(
"ศไทย中"
,
"华Việt Nam"
,
"ศไทย中华Việt Nam"
);
t!
(
"ศไทย中"
,
@
"华Việt Nam"
,
"ศไทย中华Việt Nam"
);
t!
(
"ศไทย中"
,
~
"华Việt Nam"
,
"ศไทย中华Việt Nam"
);
}
#[test]
...
...
src/libstd/str/ascii.rs
浏览文件 @
a54476b0
...
...
@@ -13,7 +13,10 @@
use
to_str
::{
ToStr
,
ToStrConsume
};
use
str
;
use
str
::
StrSlice
;
use
str
::
OwnedStr
;
use
container
::
Container
;
use
cast
;
use
ptr
;
use
iterator
::{
Iterator
,
IteratorUtil
};
use
vec
::{
CopyableVector
,
ImmutableVector
};
#[cfg(stage0)]
...
...
@@ -41,27 +44,19 @@ pub fn to_char(self) -> char {
/// Convert to lowercase.
#[inline]
pub
fn
to_lower
(
self
)
->
Ascii
{
if
self
.chr
>=
65
&&
self
.chr
<=
90
{
Ascii
{
chr
:
self
.chr
|
0x20
}
}
else
{
self
}
Ascii
{
chr
:
ASCII_LOWER_MAP
[
self
.chr
]}
}
/// Convert to uppercase.
#[inline]
pub
fn
to_upper
(
self
)
->
Ascii
{
if
self
.chr
>=
97
&&
self
.chr
<=
122
{
Ascii
{
chr
:
self
.chr
&
!
0x20
}
}
else
{
self
}
Ascii
{
chr
:
ASCII_UPPER_MAP
[
self
.chr
]}
}
/// Compares two ascii characters of equality, ignoring case.
#[inline]
pub
fn
eq_ignore_case
(
self
,
other
:
Ascii
)
->
bool
{
self
.to_lower
()
.chr
==
other
.to_lower
()
.chr
ASCII_LOWER_MAP
[
self
.chr
]
==
ASCII_LOWER_MAP
[
other
.chr
]
}
}
...
...
@@ -292,10 +287,124 @@ fn into_bytes(self) -> ~[u8] {
}
}
/// Convert the string to ASCII upper case:
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
#[inline]
pub
fn
to_ascii_upper
(
string
:
&
str
)
->
~
str
{
map_bytes
(
string
,
ASCII_UPPER_MAP
)
}
/// Convert the string to ASCII lower case:
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged.
#[inline]
pub
fn
to_ascii_lower
(
string
:
&
str
)
->
~
str
{
map_bytes
(
string
,
ASCII_LOWER_MAP
)
}
#[inline]
priv
fn
map_bytes
(
string
:
&
str
,
map
:
&
'static
[
u8
])
->
~
str
{
let
len
=
string
.len
();
let
mut
result
=
str
::
with_capacity
(
len
);
unsafe
{
do
result
.as_mut_buf
|
mut
buf
,
_
|
{
for
c
in
string
.as_bytes
()
.iter
()
{
*
buf
=
map
[
*
c
];
buf
=
ptr
::
mut_offset
(
buf
,
1
)
}
}
str
::
raw
::
set_len
(
&
mut
result
,
len
);
}
result
}
/// Check that two strings are an ASCII case-insensitive match.
/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
/// but without allocating and copying temporary strings.
#[inline]
pub
fn
eq_ignore_ascii_case
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
a
.len
()
==
b
.len
()
&&
a
.as_bytes
()
.iter
()
.zip
(
b
.as_bytes
()
.iter
())
.all
(
|(
byte_a
,
byte_b
)|
ASCII_LOWER_MAP
[
*
byte_a
]
==
ASCII_LOWER_MAP
[
*
byte_b
])
}
priv
static
ASCII_LOWER_MAP
:
&
'static
[
u8
]
=
&
[
0x00
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x06
,
0x07
,
0x08
,
0x09
,
0x0a
,
0x0b
,
0x0c
,
0x0d
,
0x0e
,
0x0f
,
0x10
,
0x11
,
0x12
,
0x13
,
0x14
,
0x15
,
0x16
,
0x17
,
0x18
,
0x19
,
0x1a
,
0x1b
,
0x1c
,
0x1d
,
0x1e
,
0x1f
,
0x20
,
0x21
,
0x22
,
0x23
,
0x24
,
0x25
,
0x26
,
0x27
,
0x28
,
0x29
,
0x2a
,
0x2b
,
0x2c
,
0x2d
,
0x2e
,
0x2f
,
0x30
,
0x31
,
0x32
,
0x33
,
0x34
,
0x35
,
0x36
,
0x37
,
0x38
,
0x39
,
0x3a
,
0x3b
,
0x3c
,
0x3d
,
0x3e
,
0x3f
,
0x40
,
0x61
,
0x62
,
0x63
,
0x64
,
0x65
,
0x66
,
0x67
,
0x68
,
0x69
,
0x6a
,
0x6b
,
0x6c
,
0x6d
,
0x6e
,
0x6f
,
0x70
,
0x71
,
0x72
,
0x73
,
0x74
,
0x75
,
0x76
,
0x77
,
0x78
,
0x79
,
0x7a
,
0x5b
,
0x5c
,
0x5d
,
0x5e
,
0x5f
,
0x60
,
0x61
,
0x62
,
0x63
,
0x64
,
0x65
,
0x66
,
0x67
,
0x68
,
0x69
,
0x6a
,
0x6b
,
0x6c
,
0x6d
,
0x6e
,
0x6f
,
0x70
,
0x71
,
0x72
,
0x73
,
0x74
,
0x75
,
0x76
,
0x77
,
0x78
,
0x79
,
0x7a
,
0x7b
,
0x7c
,
0x7d
,
0x7e
,
0x7f
,
0x80
,
0x81
,
0x82
,
0x83
,
0x84
,
0x85
,
0x86
,
0x87
,
0x88
,
0x89
,
0x8a
,
0x8b
,
0x8c
,
0x8d
,
0x8e
,
0x8f
,
0x90
,
0x91
,
0x92
,
0x93
,
0x94
,
0x95
,
0x96
,
0x97
,
0x98
,
0x99
,
0x9a
,
0x9b
,
0x9c
,
0x9d
,
0x9e
,
0x9f
,
0xa0
,
0xa1
,
0xa2
,
0xa3
,
0xa4
,
0xa5
,
0xa6
,
0xa7
,
0xa8
,
0xa9
,
0xaa
,
0xab
,
0xac
,
0xad
,
0xae
,
0xaf
,
0xb0
,
0xb1
,
0xb2
,
0xb3
,
0xb4
,
0xb5
,
0xb6
,
0xb7
,
0xb8
,
0xb9
,
0xba
,
0xbb
,
0xbc
,
0xbd
,
0xbe
,
0xbf
,
0xc0
,
0xc1
,
0xc2
,
0xc3
,
0xc4
,
0xc5
,
0xc6
,
0xc7
,
0xc8
,
0xc9
,
0xca
,
0xcb
,
0xcc
,
0xcd
,
0xce
,
0xcf
,
0xd0
,
0xd1
,
0xd2
,
0xd3
,
0xd4
,
0xd5
,
0xd6
,
0xd7
,
0xd8
,
0xd9
,
0xda
,
0xdb
,
0xdc
,
0xdd
,
0xde
,
0xdf
,
0xe0
,
0xe1
,
0xe2
,
0xe3
,
0xe4
,
0xe5
,
0xe6
,
0xe7
,
0xe8
,
0xe9
,
0xea
,
0xeb
,
0xec
,
0xed
,
0xee
,
0xef
,
0xf0
,
0xf1
,
0xf2
,
0xf3
,
0xf4
,
0xf5
,
0xf6
,
0xf7
,
0xf8
,
0xf9
,
0xfa
,
0xfb
,
0xfc
,
0xfd
,
0xfe
,
0xff
,
];
priv
static
ASCII_UPPER_MAP
:
&
'static
[
u8
]
=
&
[
0x00
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x06
,
0x07
,
0x08
,
0x09
,
0x0a
,
0x0b
,
0x0c
,
0x0d
,
0x0e
,
0x0f
,
0x10
,
0x11
,
0x12
,
0x13
,
0x14
,
0x15
,
0x16
,
0x17
,
0x18
,
0x19
,
0x1a
,
0x1b
,
0x1c
,
0x1d
,
0x1e
,
0x1f
,
0x20
,
0x21
,
0x22
,
0x23
,
0x24
,
0x25
,
0x26
,
0x27
,
0x28
,
0x29
,
0x2a
,
0x2b
,
0x2c
,
0x2d
,
0x2e
,
0x2f
,
0x30
,
0x31
,
0x32
,
0x33
,
0x34
,
0x35
,
0x36
,
0x37
,
0x38
,
0x39
,
0x3a
,
0x3b
,
0x3c
,
0x3d
,
0x3e
,
0x3f
,
0x40
,
0x41
,
0x42
,
0x43
,
0x44
,
0x45
,
0x46
,
0x47
,
0x48
,
0x49
,
0x4a
,
0x4b
,
0x4c
,
0x4d
,
0x4e
,
0x4f
,
0x50
,
0x51
,
0x52
,
0x53
,
0x54
,
0x55
,
0x56
,
0x57
,
0x58
,
0x59
,
0x5a
,
0x5b
,
0x5c
,
0x5d
,
0x5e
,
0x5f
,
0x60
,
0x41
,
0x42
,
0x43
,
0x44
,
0x45
,
0x46
,
0x47
,
0x48
,
0x49
,
0x4a
,
0x4b
,
0x4c
,
0x4d
,
0x4e
,
0x4f
,
0x50
,
0x51
,
0x52
,
0x53
,
0x54
,
0x55
,
0x56
,
0x57
,
0x58
,
0x59
,
0x5a
,
0x7b
,
0x7c
,
0x7d
,
0x7e
,
0x7f
,
0x80
,
0x81
,
0x82
,
0x83
,
0x84
,
0x85
,
0x86
,
0x87
,
0x88
,
0x89
,
0x8a
,
0x8b
,
0x8c
,
0x8d
,
0x8e
,
0x8f
,
0x90
,
0x91
,
0x92
,
0x93
,
0x94
,
0x95
,
0x96
,
0x97
,
0x98
,
0x99
,
0x9a
,
0x9b
,
0x9c
,
0x9d
,
0x9e
,
0x9f
,
0xa0
,
0xa1
,
0xa2
,
0xa3
,
0xa4
,
0xa5
,
0xa6
,
0xa7
,
0xa8
,
0xa9
,
0xaa
,
0xab
,
0xac
,
0xad
,
0xae
,
0xaf
,
0xb0
,
0xb1
,
0xb2
,
0xb3
,
0xb4
,
0xb5
,
0xb6
,
0xb7
,
0xb8
,
0xb9
,
0xba
,
0xbb
,
0xbc
,
0xbd
,
0xbe
,
0xbf
,
0xc0
,
0xc1
,
0xc2
,
0xc3
,
0xc4
,
0xc5
,
0xc6
,
0xc7
,
0xc8
,
0xc9
,
0xca
,
0xcb
,
0xcc
,
0xcd
,
0xce
,
0xcf
,
0xd0
,
0xd1
,
0xd2
,
0xd3
,
0xd4
,
0xd5
,
0xd6
,
0xd7
,
0xd8
,
0xd9
,
0xda
,
0xdb
,
0xdc
,
0xdd
,
0xde
,
0xdf
,
0xe0
,
0xe1
,
0xe2
,
0xe3
,
0xe4
,
0xe5
,
0xe6
,
0xe7
,
0xe8
,
0xe9
,
0xea
,
0xeb
,
0xec
,
0xed
,
0xee
,
0xef
,
0xf0
,
0xf1
,
0xf2
,
0xf3
,
0xf4
,
0xf5
,
0xf6
,
0xf7
,
0xf8
,
0xf9
,
0xfa
,
0xfb
,
0xfc
,
0xfd
,
0xfe
,
0xff
,
];
#[cfg(test)]
mod
tests
{
use
super
::
*
;
use
to_bytes
::
ToBytes
;
use
str
::
from_char
;
macro_rules!
v2ascii
(
(
[
$
(
$e:expr
),
*
])
=>
(
[
$
(
Ascii
{
chr
:
$e
}),
*
]);
...
...
@@ -378,4 +487,53 @@ fn test_ascii_to_bytes() {
#[test]
#[should_fail]
fn
test_ascii_fail_char_slice
()
{
'λ'
.to_ascii
();
}
#[test]
fn
test_to_ascii_upper
()
{
assert_eq!
(
to_ascii_upper
(
"url()URL()uRl()ürl"
),
~
"URL()URL()URL()üRL"
);
assert_eq!
(
to_ascii_upper
(
"hıKß"
),
~
"HıKß"
);
let
mut
i
=
0
;
while
i
<=
500
{
let
c
=
i
as
char
;
let
upper
=
if
'a'
<=
c
&&
c
<=
'z'
{
c
+
'A'
-
'a'
}
else
{
c
};
assert_eq!
(
to_ascii_upper
(
from_char
(
i
as
char
)),
from_char
(
upper
))
i
+=
1
;
}
}
#[test]
fn
test_to_ascii_lower
()
{
assert_eq!
(
to_ascii_lower
(
"url()URL()uRl()Ürl"
),
~
"url()url()url()Ürl"
);
// Dotted capital I, Kelvin sign, Sharp S.
assert_eq!
(
to_ascii_lower
(
"HİKß"
),
~
"hİKß"
);
let
mut
i
=
0
;
while
i
<=
500
{
let
c
=
i
as
char
;
let
lower
=
if
'A'
<=
c
&&
c
<=
'Z'
{
c
+
'a'
-
'A'
}
else
{
c
};
assert_eq!
(
to_ascii_lower
(
from_char
(
i
as
char
)),
from_char
(
lower
))
i
+=
1
;
}
}
#[test]
fn
test_eq_ignore_ascii_case
()
{
assert
!
(
eq_ignore_ascii_case
(
"url()URL()uRl()Ürl"
,
"url()url()url()Ürl"
));
assert
!
(
!
eq_ignore_ascii_case
(
"Ürl"
,
"ürl"
));
// Dotted capital I, Kelvin sign, Sharp S.
assert
!
(
eq_ignore_ascii_case
(
"HİKß"
,
"hİKß"
));
assert
!
(
!
eq_ignore_ascii_case
(
"İ"
,
"i"
));
assert
!
(
!
eq_ignore_ascii_case
(
"K"
,
"k"
));
assert
!
(
!
eq_ignore_ascii_case
(
"ß"
,
"s"
));
let
mut
i
=
0
;
while
i
<=
500
{
let
c
=
i
as
char
;
let
lower
=
if
'A'
<=
c
&&
c
<=
'Z'
{
c
+
'a'
-
'A'
}
else
{
c
};
assert
!
(
eq_ignore_ascii_case
(
from_char
(
i
as
char
),
from_char
(
lower
)));
i
+=
1
;
}
}
}
src/libstd/unstable/intrinsics.rs
浏览文件 @
a54476b0
...
...
@@ -317,12 +317,21 @@ fn visit_leave_fn(&self, purity: uint, proto: uint,
/// Get the address of the `__morestack` stack growth function.
pub
fn
morestack_addr
()
->
*
();
///
Adjust a pointer by an offset
.
///
Calculates the offset from a pointer
.
///
/// 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
;
/// 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
/// undefined behaviour.
///
/// This intrinsic should be preferred over `offset` when the guarantee can
/// be satisfied, to enable better optimization.
#[cfg(not(stage0))]
pub
fn
offset_inbounds
<
T
>
(
dst
:
*
T
,
offset
:
int
)
->
*
T
;
/// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
pub
fn
memcpy32
<
T
>
(
dst
:
*
mut
T
,
src
:
*
T
,
count
:
u32
);
...
...
src/libstd/vec.rs
浏览文件 @
a54476b0
...
...
@@ -849,10 +849,15 @@ fn slice_to(&self, end: uint) -> &'self [T] {
fn
iter
(
self
)
->
VecIterator
<
'self
,
T
>
{
unsafe
{
let
p
=
vec
::
raw
::
to_ptr
(
self
);
VecIterator
{
ptr
:
p
,
end
:
(
p
as
uint
+
self
.len
()
*
sys
::
nonzero_size_of
::
<
T
>
())
as
*
T
,
lifetime
:
cast
::
transmute
(
p
)}
if
sys
::
size_of
::
<
T
>
()
==
0
{
VecIterator
{
ptr
:
p
,
end
:
(
p
as
uint
+
self
.len
())
as
*
T
,
lifetime
:
cast
::
transmute
(
p
)}
}
else
{
VecIterator
{
ptr
:
p
,
end
:
p
.offset_inbounds
(
self
.len
()
as
int
),
lifetime
:
cast
::
transmute
(
p
)}
}
}
}
...
...
@@ -1826,10 +1831,15 @@ fn mut_split(self, mid: uint) -> (&'self mut [T], &'self mut [T]) {
fn
mut_iter
(
self
)
->
VecMutIterator
<
'self
,
T
>
{
unsafe
{
let
p
=
vec
::
raw
::
to_mut_ptr
(
self
);
VecMutIterator
{
ptr
:
p
,
end
:
(
p
as
uint
+
self
.len
()
*
sys
::
nonzero_size_of
::
<
T
>
())
as
*
mut
T
,
lifetime
:
cast
::
transmute
(
p
)}
if
sys
::
size_of
::
<
T
>
()
==
0
{
VecMutIterator
{
ptr
:
p
,
end
:
(
p
as
uint
+
self
.len
())
as
*
mut
T
,
lifetime
:
cast
::
transmute
(
p
)}
}
else
{
VecMutIterator
{
ptr
:
p
,
end
:
p
.offset_inbounds
(
self
.len
()
as
int
),
lifetime
:
cast
::
transmute
(
p
)}
}
}
}
...
...
@@ -2183,7 +2193,7 @@ fn next(&mut self) -> Option<$elem> {
// same pointer.
cast
::
transmute
(
self
.ptr
as
uint
+
1
)
}
else
{
self
.ptr
.offset
(
1
)
self
.ptr
.offset
_inbounds
(
1
)
};
Some
(
cast
::
transmute
(
old
))
...
...
@@ -2215,7 +2225,7 @@ fn next_back(&mut self) -> Option<$elem> {
// See above for why 'ptr.offset' isn't used
cast
::
transmute
(
self
.end
as
uint
-
1
)
}
else
{
self
.end
.offset
(
-
1
)
self
.end
.offset
_inbounds
(
-
1
)
};
Some
(
cast
::
transmute
(
self
.end
))
}
...
...
src/libsyntax/ext/deriving/cmp/totalord.rs
浏览文件 @
a54476b0
...
...
@@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
ast
;
use
ast
::{
MetaItem
,
item
,
expr
};
use
codemap
::
span
;
use
ext
::
base
::
ExtCtxt
;
...
...
@@ -40,40 +41,70 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt,
}
pub
fn
ordering_const
(
cx
:
@
ExtCtxt
,
span
:
span
,
cnst
:
Ordering
)
->
@
expr
{
pub
fn
ordering_const
(
cx
:
@
ExtCtxt
,
span
:
span
,
cnst
:
Ordering
)
->
ast
::
Path
{
let
cnst
=
match
cnst
{
Less
=>
"Less"
,
Equal
=>
"Equal"
,
Greater
=>
"Greater"
};
cx
.expr_path
(
cx
.path_global
(
span
,
~
[
cx
.ident_of
(
"std"
),
cx
.ident_of
(
"cmp"
),
cx
.ident_of
(
cnst
)]))
cx
.path_global
(
span
,
~
[
cx
.ident_of
(
"std"
),
cx
.ident_of
(
"cmp"
),
cx
.ident_of
(
cnst
)])
}
pub
fn
cs_cmp
(
cx
:
@
ExtCtxt
,
span
:
span
,
substr
:
&
Substructure
)
->
@
expr
{
let
test_id
=
cx
.ident_of
(
"__test"
);
let
equals_path
=
ordering_const
(
cx
,
span
,
Equal
);
/*
Builds:
let __test = self_field1.cmp(&other_field2);
if other == ::std::cmp::Equal {
let __test = self_field2.cmp(&other_field2);
if __test == ::std::cmp::Equal {
...
} else {
__test
}
} else {
__test
}
FIXME #6449: These `if`s could/should be `match`es.
*/
cs_same_method_fold
(
// foldr (possibly) nests the matches in lexical_ordering better
// foldr nests the if-elses correctly, leaving the first field
// as the outermost one, and the last as the innermost.
false
,
|
cx
,
span
,
old
,
new
|
{
cx
.expr_call_global
(
span
,
~
[
cx
.ident_of
(
"std"
),
cx
.ident_of
(
"cmp"
),
cx
.ident_of
(
"lexical_ordering"
)],
~
[
old
,
new
])
// let __test = new;
// if __test == ::std::cmp::Equal {
// old
// } else {
// __test
// }
let
assign
=
cx
.stmt_let
(
span
,
false
,
test_id
,
new
);
let
cond
=
cx
.expr_binary
(
span
,
ast
::
eq
,
cx
.expr_ident
(
span
,
test_id
),
cx
.expr_path
(
equals_path
.clone
()));
let
if_
=
cx
.expr_if
(
span
,
cond
,
old
,
Some
(
cx
.expr_ident
(
span
,
test_id
)));
cx
.expr_block
(
cx
.block
(
span
,
~
[
assign
],
Some
(
if_
)))
},
ordering_const
(
cx
,
span
,
Equal
),
cx
.expr_path
(
equals_path
.clone
()
),
|
cx
,
span
,
list
,
_
|
{
match
list
{
// an earlier nonmatching variant is Less than a
// later one
// later one
.
[(
self_var
,
_
,
_
),
(
other_var
,
_
,
_
)]
=>
ordering_const
(
cx
,
span
,
self_var
.cmp
(
&
other_var
)),
(
other_var
,
_
,
_
)]
=>
cx
.expr_path
(
ordering_const
(
cx
,
span
,
self_var
.cmp
(
&
other_var
)
)),
_
=>
cx
.span_bug
(
span
,
"Not exactly 2 arguments in `deriving(TotalOrd)`"
)
}
},
...
...
src/test/bench/core-set.rs
浏览文件 @
a54476b0
...
...
@@ -59,7 +59,7 @@ pub fn bench_int<T:MutableSet<uint>,
{
let
mut
set
=
f
();
do
timed
(
&
mut
self
.random_ints
)
{
do
num_keys
.times
{
for
_
in
range
(
0
,
num_keys
)
{
set
.insert
((
rng
.next
()
as
uint
)
%
rand_cap
);
}
}
...
...
@@ -103,7 +103,7 @@ pub fn bench_str<T:MutableSet<~str>,
{
let
mut
set
=
f
();
do
timed
(
&
mut
self
.random_strings
)
{
do
num_keys
.times
{
for
_
in
range
(
0
,
num_keys
)
{
let
s
=
uint
::
to_str
(
rng
.next
()
as
uint
);
set
.insert
(
s
);
}
...
...
src/test/bench/noise.rs
浏览文件 @
a54476b0
...
...
@@ -105,7 +105,7 @@ fn main() {
let
symbols
=
[
" "
,
"░"
,
"▒"
,
"▓"
,
"█"
,
"█"
];
let
mut
pixels
=
[
0f32
,
..
256
*
256
];
let
n2d
=
~
Noise2DContext
::
new
();
do
100
.times
{
for
_
in
range
(
0
,
100u
)
{
for
y
in
range
(
0
,
256
)
{
for
x
in
range
(
0
,
256
)
{
let
v
=
n2d
.get
(
...
...
src/test/bench/shootout-chameneos-redux.rs
浏览文件 @
a54476b0
...
...
@@ -169,7 +169,7 @@ fn rendezvous(nn: uint, set: ~[color]) {
let
mut
creatures_met
=
0
;
// set up meetings...
do
nn
.times
{
for
_
in
range
(
0
,
nn
)
{
let
fst_creature
:
CreatureInfo
=
from_creatures
.recv
();
let
snd_creature
:
CreatureInfo
=
from_creatures
.recv
();
...
...
src/test/bench/shootout-fasta-redux.rs
浏览文件 @
a54476b0
...
...
@@ -164,7 +164,7 @@ fn make(&mut self, n: uint) {
let
chars_left
=
n
%
LINE_LEN
;
let
mut
buf
=
[
0
,
..
LINE_LEN
+
1
];
do
lines
.times
{
for
_
in
range
(
0
,
lines
)
{
for
i
in
range
(
0u
,
LINE_LEN
)
{
buf
[
i
]
=
self
.nextc
();
}
...
...
src/test/bench/shootout-k-nucleotide.rs
浏览文件 @
a54476b0
...
...
@@ -54,7 +54,7 @@ fn pack(string: &str) -> Code {
fn
unpack
(
&
self
,
frame
:
i32
)
->
~
str
{
let
mut
key
=
**
self
;
let
mut
result
=
~
[];
do
(
frame
as
uint
)
.times
{
for
_
in
range
(
0
,
frame
)
{
result
.push
(
unpack_symbol
((
key
as
u8
)
&
3
));
key
>>=
2
;
}
...
...
@@ -251,7 +251,7 @@ fn generate_frequencies(frequencies: &mut Table,
let
mut
code
=
Code
(
0
);
// Pull first frame.
do
(
frame
as
uint
)
.times
{
for
_
in
range
(
0
,
frame
)
{
code
=
code
.push_char
(
input
[
0
]);
input
=
next_char
(
input
);
}
...
...
src/test/bench/shootout-nbody.rs
浏览文件 @
a54476b0
...
...
@@ -79,7 +79,7 @@ struct Planet {
fn
advance
(
bodies
:
&
mut
[
Planet
,
..
N_BODIES
],
dt
:
f64
,
steps
:
i32
)
{
let
mut
d
=
[
0.0
,
..
3
];
do
(
steps
as
uint
)
.times
{
for
_
in
range
(
0
,
steps
)
{
for
i
in
range
(
0u
,
N_BODIES
)
{
for
j
in
range
(
i
+
1
,
N_BODIES
)
{
d
[
0
]
=
bodies
[
i
]
.x
[
0
]
-
bodies
[
j
]
.x
[
0
];
...
...
src/test/bench/shootout-spectralnorm.rs
浏览文件 @
a54476b0
...
...
@@ -56,7 +56,7 @@ fn main() {
let
mut
u
=
vec
::
from_elem
(
n
,
1f64
);
let
mut
v
=
u
.clone
();
let
mut
tmp
=
u
.clone
();
do
8
.times
{
for
_
in
range
(
0
,
8u
)
{
mult_AtAv
(
u
,
v
,
tmp
);
mult_AtAv
(
v
,
u
,
tmp
);
}
...
...
src/test/bench/task-perf-alloc-unwind.rs
浏览文件 @
a54476b0
...
...
@@ -32,7 +32,7 @@ fn main() {
}
fn
run
(
repeat
:
int
,
depth
:
int
)
{
do
(
repeat
as
uint
)
.times
{
for
_
in
range
(
0
,
repeat
)
{
info!
(
"starting %.4f"
,
precise_time_s
());
do
task
::
try
{
recurse_or_fail
(
depth
,
None
)
...
...
src/test/bench/task-perf-linked-failure.rs
浏览文件 @
a54476b0
...
...
@@ -32,7 +32,7 @@ fn grandchild_group(num_tasks: uint) {
let
(
po
,
ch
)
=
stream
();
let
ch
=
SharedChan
::
new
(
ch
);
do
num_tasks
.times
{
for
_
in
range
(
0
,
num_tasks
)
{
let
ch
=
ch
.clone
();
do
task
::
spawn
{
// linked
ch
.send
(());
...
...
@@ -41,7 +41,7 @@ fn grandchild_group(num_tasks: uint) {
}
}
error!
(
"Grandchild group getting started"
);
do
num_tasks
.times
{
for
_
in
range
(
0
,
num_tasks
)
{
// Make sure all above children are fully spawned; i.e., enlisted in
// their ancestor groups.
po
.recv
();
...
...
src/test/run-pass/class-impl-parameterized-trait.rs
已删除
100644 → 0
浏览文件 @
aababbba
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-test FIXME #7307
// xfail-fast
extern
mod
extra
;
use
extra
::
oldmap
::
*
;
class
cat
:
map
<
int
,
bool
>
{
priv
{
// Yes, you can have negative meows
let
mut
meows
:
int
;
fn
meow
()
{
self
.meows
+=
1
;
error!
(
"Meow %d"
,
self
.meows
);
if
self
.meows
%
5
==
0
{
self
.how_hungry
+=
1
;
}
}
}
let
mut
how_hungry
:
int
;
let
name
:
str
;
new
(
in_x
:
int
,
in_y
:
int
,
in_name
:
str
)
{
self
.meows
=
in_x
;
self
.how_hungry
=
in_y
;
self
.name
=
in_name
;
}
fn
speak
()
{
self
.meow
();
}
fn
eat
()
->
bool
{
if
self
.how_hungry
>
0
{
error!
(
"OM NOM NOM"
);
self
.how_hungry
-=
2
;
return
true
;
}
else
{
error!
(
"Not hungry!"
);
return
false
;
}
}
fn
size
()
->
uint
{
self
.meows
as
uint
}
fn
insert
(
+
k
:
int
,
+
v
:
bool
)
->
bool
{
if
v
{
self
.meows
+=
k
;
}
else
{
self
.meows
-=
k
;
};
true
}
fn
contains_key
(
&&
k
:
int
)
->
bool
{
k
<=
self
.meows
}
fn
get
(
&&
k
:
int
)
->
bool
{
k
<=
self
.meows
}
fn
[](
&&
k
:
int
)
->
bool
{
k
<=
self
.meows
}
fn
find
(
&&
k
:
int
)
->
Option
<
bool
>
{
Some
(
self
.get
(
k
))
}
fn
remove
(
&&
k
:
int
)
->
Option
<
bool
>
{
self
.meows
-=
k
;
Some
(
true
)
}
fn
each
(
f
:
&
fn
(
&&
int
,
&&
bool
)
->
bool
)
{
let
mut
n
=
num
::
abs
(
self
.meows
);
while
n
>
0
{
if
!
f
(
n
,
true
)
{
break
;
}
n
-=
1
;
}
}
fn
each_key
(
&&
f
:
&
fn
(
&&
int
)
->
bool
)
{
for
self
.each
|
k
,
_
v
|
{
if
!
f
(
k
)
{
break
;
}
again
;};
}
fn
each_value
(
&&
f
:
&
fn
(
&&
bool
)
->
bool
)
{
for
self
.each
|
_
k
,
v
|
{
if
!
f
(
v
)
{
break
;
}
again
;};
}
fn
clear
()
{
}
}
pub
fn
main
()
{
let
nyan
:
cat
=
cat
(
0
,
2
,
"nyan"
);
for
_
in
range
(
1u
,
5u
)
{
nyan
.speak
();
}
// cat returns true if uint input is greater than
// the number of meows so far
assert
!
((
nyan
.get
(
1
)));
assert
!
((
!
nyan
.get
(
10
)));
}
src/test/run-pass/class-implements-multiple-traits.rs
已删除
100644 → 0
浏览文件 @
aababbba
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-test FIXME #7305
extern
mod
extra
;
use
extra
::
oldmap
::
*
;
use
vec
::
*
;
use
dvec
::{
dvec
,
extensions
};
enum
furniture
{
chair
,
couch
,
bed
}
enum
body_part
{
finger
,
toe
,
nose
,
ear
}
trait
noisy
{
fn
speak
()
->
int
;
}
trait
scratchy
{
fn
scratch
()
->
Option
<
furniture
>
;
}
trait
bitey
{
fn
bite
()
->
body_part
;
}
fn
vec_includes
<
T
>
(
xs
:
~
[
T
],
x
:
T
)
->
bool
{
for
each
(
xs
)
|
y
|
{
if
y
==
x
{
return
true
;
}}
return
false
;
}
// vtables other than the 1st one don't seem to work
class
cat
:
noisy
,
scratchy
,
bitey
{
priv
{
let
meows
:
@
mut
uint
;
let
scratched
:
dvec
<
furniture
>
;
let
bite_counts
:
hashmap
<
body_part
,
uint
>
;
fn
meow
()
->
uint
{
info!
(
"Meow: %u"
,
*
self
.meows
);
*
self
.meows
+=
1u
;
if
*
self
.meows
%
5u
==
0u
{
*
self
.how_hungry
+=
1
;
}
*
self
.meows
}
}
let
how_hungry
:
@
mut
int
;
let
name
:
str
;
new
(
in_x
:
uint
,
in_y
:
int
,
in_name
:
str
)
{
self
.meows
=
@
mut
in_x
;
self
.how_hungry
=
@
mut
in_y
;
self
.name
=
in_name
;
self
.scratched
=
dvec
();
let
hsher
:
hashfn
<
body_part
>
=
|
p
|
int
::
hash
(
p
as
int
);
let
eqer
:
eqfn
<
body_part
>
=
|
p
,
q
|
p
==
q
;
let
t
:
hashmap
<
body_part
,
uint
>
=
hashmap
::
<
body_part
,
uint
>
(
hsher
,
eqer
);
self
.bite_counts
=
t
;
do
iter
(
~
[
finger
,
toe
,
nose
,
ear
])
|
p
|
{
self
.bite_counts
.insert
(
p
,
0u
);
};
}
fn
speak
()
->
int
{
self
.meow
()
as
int
}
fn
meow_count
()
->
uint
{
*
self
.meows
}
fn
scratch
()
->
Option
<
furniture
>
{
let
all
=
~
[
chair
,
couch
,
bed
];
log
(
error
,
self
.scratched
);
let
mut
rslt
=
None
;
for
each
(
all
)
|
thing
|
{
if
!
self
.scratched
.contains
(
thing
)
{
self
.scratched
.push
(
thing
);
return
Some
(
thing
);
}}
rslt
}
fn
bite
()
->
body_part
{
error!
(
"In bite()"
);
let
all
=
~
[
toe
,
nose
,
ear
];
let
mut
min
=
finger
;
do
iter
(
all
)
|
next
|
{
info!
(
"min = %?"
,
min
);
if
self
.bite_counts
.get
(
next
)
<
self
.bite_counts
.get
(
min
)
{
min
=
next
;
}};
self
.bite_counts
.insert
(
min
,
self
.bite_counts
.get
(
min
)
+
1u
);
info!
(
"Bit %?"
,
min
);
min
}
}
fn
annoy_neighbors
<
T
:
noisy
>
(
critter
:
T
)
{
for
i
in
range
(
0u
,
10u
)
{
let
what
=
critter
.speak
();
info!
(
"%u %d"
,
i
,
what
);
}
}
fn
bite_everything
<
T
:
bitey
>
(
critter
:
T
)
->
bool
{
let
mut
left
:
~
[
body_part
]
=
~
[
finger
,
toe
,
nose
,
ear
];
while
left
.len
()
>
0u
{
let
part
=
critter
.bite
();
info!
(
"%? %?"
,
left
,
part
);
if
vec_includes
(
left
,
part
)
{
left
=
vec
::
filter
(
left
,
|
p
|
p
!=
part
);
}
else
{
return
false
;
}
}
true
}
fn
scratched_something
<
T
:
scratchy
>
(
critter
:
T
)
->
bool
{
option
::
is_some
(
critter
.scratch
())
}
pub
fn
main
()
{
let
nyan
:
cat
=
cat
(
0u
,
2
,
"nyan"
);
annoy_neighbors
(
nyan
as
noisy
);
assert_eq!
(
nyan
.meow_count
(),
10u
);
assert
!
((
bite_everything
(
nyan
as
bitey
)));
assert
!
((
scratched_something
(
nyan
as
scratchy
)));
}
src/test/run-pass/coerce-reborrow-imm-vec-arg.rs
浏览文件 @
a54476b0
...
...
@@ -12,10 +12,4 @@ fn sum_imm(y: &[int]) -> int {
sum
(
y
)
}
/* FIXME #7304
fn sum_const(y: &const [int]) -> int {
sum(y)
}
*/
pub
fn
main
()
{}
src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs
浏览文件 @
a54476b0
/* FIXME #7302
fn foo(v: &const [uint]) -> ~[uint] {
v.to_owned()
}
*/
fn
bar
(
v
:
&
mut
[
uint
])
->
~
[
uint
]
{
v
.to_owned
()
}
...
...
@@ -14,7 +8,6 @@ fn bip(v: &[uint]) -> ~[uint] {
pub
fn
main
()
{
let
mut
the_vec
=
~
[
1u
,
2
,
3
,
100
];
// assert_eq!(the_vec.clone(), foo(the_vec));
assert_eq!
(
the_vec
.clone
(),
bar
(
the_vec
));
assert_eq!
(
the_vec
.clone
(),
bip
(
the_vec
));
}
src/test/run-pass/deriving-cmp-shortcircuit.rs
0 → 100644
浏览文件 @
a54476b0
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// check that the derived impls for the comparison traits shortcircuit
// where possible, by having a type that fails when compared as the
// second element, so this passes iff the instances shortcircuit.
pub
struct
FailCmp
;
impl
Eq
for
FailCmp
{
fn
eq
(
&
self
,
_
:
&
FailCmp
)
->
bool
{
fail
!
(
"eq"
)
}
}
impl
Ord
for
FailCmp
{
fn
lt
(
&
self
,
_
:
&
FailCmp
)
->
bool
{
fail
!
(
"lt"
)
}
}
impl
TotalEq
for
FailCmp
{
fn
equals
(
&
self
,
_
:
&
FailCmp
)
->
bool
{
fail
!
(
"equals"
)
}
}
impl
TotalOrd
for
FailCmp
{
fn
cmp
(
&
self
,
_
:
&
FailCmp
)
->
Ordering
{
fail
!
(
"cmp"
)
}
}
#[deriving(Eq,Ord,TotalEq,TotalOrd)]
struct
ShortCircuit
{
x
:
int
,
y
:
FailCmp
}
fn
main
()
{
let
a
=
ShortCircuit
{
x
:
1
,
y
:
FailCmp
};
let
b
=
ShortCircuit
{
x
:
2
,
y
:
FailCmp
};
assert
!
(
a
!=
b
);
assert
!
(
a
<
b
);
assert
!
(
!
a
.equals
(
&
b
));
assert_eq!
(
a
.cmp
(
&
b
),
::
std
::
cmp
::
Less
);
}
src/test/run-pass/rcvr-borrowed-to-region.rs
浏览文件 @
a54476b0
...
...
@@ -12,7 +12,9 @@ trait get {
fn
get
(
self
)
->
int
;
}
// FIXME #7302: Note: impl on a slice
// Note: impl on a slice; we're checking that the pointers below
// correctly get borrowed to `&`. (similar to impling for `int`, with
// `&self` instead of `self`.)
impl
<
'self
>
get
for
&
'self
int
{
fn
get
(
self
)
->
int
{
return
*
self
;
...
...
@@ -34,11 +36,6 @@ pub fn main() {
info!
(
"y=%d"
,
y
);
assert_eq!
(
y
,
6
);
let
x
=
~
6
;
let
y
=
x
.get
();
info!
(
"y=%d"
,
y
);
assert_eq!
(
y
,
6
);
let
x
=
&
6
;
let
y
=
x
.get
();
info!
(
"y=%d"
,
y
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录