Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0fade3a7
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,发现更多精彩内容 >>
提交
0fade3a7
编写于
11月 13, 2013
作者:
S
Steven Fackler
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduce Mut<T> to libstd
Based off of blake2-ppc's work in #9429.
上级
fb279aa0
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
317 addition
and
0 deletion
+317
-0
src/libstd/lib.rs
src/libstd/lib.rs
+1
-0
src/libstd/mutable.rs
src/libstd/mutable.rs
+298
-0
src/test/compile-fail/mut-not-freeze.rs
src/test/compile-fail/mut-not-freeze.rs
+18
-0
未找到文件。
src/libstd/lib.rs
浏览文件 @
0fade3a7
...
...
@@ -164,6 +164,7 @@ pub mod linkhack {
pub
mod
either
;
pub
mod
hashmap
;
pub
mod
cell
;
pub
mod
mutable
;
pub
mod
trie
;
...
...
src/libstd/mutable.rs
0 → 100644
浏览文件 @
0fade3a7
// 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.
//! A mutable memory location with dynamically checked borrow rules
use
prelude
::
*
;
use
cast
;
use
util
::
NonCopyable
;
/// A mutable memory location with dynamically checked borrow rules
#[no_freeze]
pub
struct
Mut
<
T
>
{
priv
value
:
T
,
priv
borrow
:
BorrowFlag
,
priv
nc
:
NonCopyable
}
// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type
BorrowFlag
=
uint
;
static
UNUSED
:
BorrowFlag
=
0
;
static
WRITING
:
BorrowFlag
=
-
1
;
impl
<
T
>
Mut
<
T
>
{
/// Create a new `Mut` containing `value`
pub
fn
new
(
value
:
T
)
->
Mut
<
T
>
{
Mut
{
value
:
value
,
borrow
:
UNUSED
,
nc
:
NonCopyable
}
}
/// Consumes the `Mut`, returning the wrapped value.
pub
fn
unwrap
(
self
)
->
T
{
assert
!
(
self
.borrow
==
UNUSED
);
self
.value
}
unsafe
fn
as_mut
<
'a
>
(
&
'a
self
)
->
&
'a
mut
Mut
<
T
>
{
cast
::
transmute_mut
(
self
)
}
/// Attempts to immutably borrow the wrapped value.
///
/// The borrow lasts until the returned `Ref` exits scope. Multiple
/// immutable borrows can be taken out at the same time.
///
/// Returns `None` if the value is currently mutably borrowed.
pub
fn
try_borrow
<
'a
>
(
&
'a
self
)
->
Option
<
Ref
<
'a
,
T
>>
{
match
self
.borrow
{
WRITING
=>
None
,
_
=>
{
unsafe
{
self
.as_mut
()
.borrow
+=
1
;
}
Some
(
Ref
{
parent
:
self
})
}
}
}
/// Immutably borrows the wrapped value.
///
/// The borrow lasts until the returned `Ref` exits scope. Multiple
/// immutable borrows can be taken out at the same time.
///
/// # Failure
///
/// Fails if the value is currently mutably borrowed.
pub
fn
borrow
<
'a
>
(
&
'a
self
)
->
Ref
<
'a
,
T
>
{
match
self
.try_borrow
()
{
Some
(
ptr
)
=>
ptr
,
None
=>
fail
!
(
"Mut<T> already mutably borrowed"
)
}
}
/// Mutably borrows the wrapped value.
///
/// The borrow lasts untile the returned `MutRef` exits scope. The value
/// cannot be borrowed while this borrow is active.
///
/// Returns `None` if the value is currently borrowed.
pub
fn
try_borrow_mut
<
'a
>
(
&
'a
self
)
->
Option
<
MutRef
<
'a
,
T
>>
{
match
self
.borrow
{
UNUSED
=>
unsafe
{
let
mut_self
=
self
.as_mut
();
mut_self
.borrow
=
WRITING
;
Some
(
MutRef
{
parent
:
mut_self
})
},
_
=>
None
}
}
/// Mutably borrows the wrapped value.
///
/// The borrow lasts untile the returned `MutRef` exits scope. The value
/// cannot be borrowed while this borrow is active.
///
/// # Failure
///
/// Fails if the value is currently borrowed.
pub
fn
borrow_mut
<
'a
>
(
&
'a
self
)
->
MutRef
<
'a
,
T
>
{
match
self
.try_borrow_mut
()
{
Some
(
ptr
)
=>
ptr
,
None
=>
fail
!
(
"Mut<T> already borrowed"
)
}
}
/// Immutably borrows the wrapped value and applies `blk` to it.
///
/// # Failure
///
/// Fails if the value is currently mutably borrowed.
#[inline]
pub
fn
map
<
U
>
(
&
self
,
blk
:
|
&
T
|
->
U
)
->
U
{
let
ptr
=
self
.borrow
();
blk
(
ptr
.get
())
}
/// Mutably borrows the wrapped value and applies `blk` to it.
///
/// # Failure
///
/// Fails if the value is currently borrowed.
#[inline]
pub
fn
map_mut
<
U
>
(
&
self
,
blk
:
|
&
mut
T
|
->
U
)
->
U
{
let
mut
ptr
=
self
.borrow_mut
();
blk
(
ptr
.get
())
}
}
impl
<
T
:
Clone
>
Clone
for
Mut
<
T
>
{
fn
clone
(
&
self
)
->
Mut
<
T
>
{
let
x
=
self
.borrow
();
Mut
::
new
(
x
.get
()
.clone
())
}
}
impl
<
T
:
DeepClone
>
DeepClone
for
Mut
<
T
>
{
fn
deep_clone
(
&
self
)
->
Mut
<
T
>
{
let
x
=
self
.borrow
();
Mut
::
new
(
x
.get
()
.deep_clone
())
}
}
impl
<
T
:
Eq
>
Eq
for
Mut
<
T
>
{
fn
eq
(
&
self
,
other
:
&
Mut
<
T
>
)
->
bool
{
let
a
=
self
.borrow
();
let
b
=
other
.borrow
();
a
.get
()
==
b
.get
()
}
}
/// Wraps a borrowed reference to a value in a `Mut` box.
pub
struct
Ref
<
'box
,
T
>
{
priv
parent
:
&
'box
Mut
<
T
>
}
#[unsafe_destructor]
impl
<
'box
,
T
>
Drop
for
Ref
<
'box
,
T
>
{
fn
drop
(
&
mut
self
)
{
assert
!
(
self
.parent.borrow
!=
WRITING
&&
self
.parent.borrow
!=
UNUSED
);
unsafe
{
self
.parent
.as_mut
()
.borrow
-=
1
;
}
}
}
impl
<
'box
,
T
>
Ref
<
'box
,
T
>
{
/// Retrieve an immutable reference to the stored value.
#[inline]
pub
fn
get
<
'a
>
(
&
'a
self
)
->
&
'a
T
{
&
self
.parent.value
}
}
/// Wraps a mutable borrowed reference to a value in a `Mut` box.
pub
struct
MutRef
<
'box
,
T
>
{
priv
parent
:
&
'box
mut
Mut
<
T
>
}
#[unsafe_destructor]
impl
<
'box
,
T
>
Drop
for
MutRef
<
'box
,
T
>
{
fn
drop
(
&
mut
self
)
{
assert
!
(
self
.parent.borrow
==
WRITING
);
unsafe
{
self
.parent
.as_mut
()
.borrow
=
UNUSED
;
}
}
}
impl
<
'box
,
T
>
MutRef
<
'box
,
T
>
{
/// Retrieve a mutable reference to the stored value.
#[inline]
pub
fn
get
<
'a
>
(
&
'a
mut
self
)
->
&
'a
mut
T
{
&
mut
self
.parent.value
}
}
#[cfg(test)]
mod
test
{
use
super
::
*
;
#[test]
fn
double_imm_borrow
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow
();
x
.borrow
();
}
#[test]
fn
no_mut_then_imm_borrow
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow_mut
();
assert
!
(
x
.try_borrow
()
.is_none
());
}
#[test]
fn
no_imm_then_borrow_mut
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow
();
assert
!
(
x
.try_borrow_mut
()
.is_none
());
}
#[test]
fn
no_double_borrow_mut
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow_mut
();
assert
!
(
x
.try_borrow_mut
()
.is_none
());
}
#[test]
fn
imm_release_borrow_mut
()
{
let
x
=
Mut
::
new
(
0
);
{
let
_
b1
=
x
.borrow
();
}
x
.borrow_mut
();
}
#[test]
fn
mut_release_borrow_mut
()
{
let
x
=
Mut
::
new
(
0
);
{
let
_
b1
=
x
.borrow_mut
();
}
x
.borrow
();
}
#[test]
fn
double_borrow_single_release_no_borrow_mut
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow
();
{
let
_
b2
=
x
.borrow
();
}
assert
!
(
x
.try_borrow_mut
()
.is_none
());
}
#[test]
fn
map_ok
()
{
let
x
=
Mut
::
new
(
0
);
assert_eq!
(
1
,
x
.map
(|
x
|
*
x
+
1
));
}
#[test]
#[should_fail]
fn
mut_borrow_map
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow_mut
();
x
.map
(|
x
|
*
x
+
1
);
}
#[test]
fn
borrow_map
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b1
=
x
.borrow
();
assert_eq!
(
1
,
x
.map
(|
x
|
*
x
+
1
));
}
#[test]
fn
map_mut_ok
()
{
let
x
=
Mut
::
new
(
0
);
x
.map_mut
(|
x
|
*
x
+=
1
);
let
b
=
x
.borrow
();
assert_eq!
(
1
,
*
b
.get
());
}
#[test]
#[should_fail]
fn
borrow_map_mut
()
{
let
x
=
Mut
::
new
(
0
);
let
_
b
=
x
.borrow
();
x
.map_mut
(|
x
|
*
x
+=
1
);
}
}
src/test/compile-fail/mut-not-freeze.rs
0 → 100644
浏览文件 @
0fade3a7
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
std
::
mutable
::
Mut
;
fn
f
<
T
:
Freeze
>
(
_
:
T
)
{}
fn
main
()
{
let
x
=
Mut
::
new
(
0
);
f
(
x
);
//~ ERROR: which does not fulfill `Freeze`
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录