Skip to content

Commit d57704a

Browse files
committed
---
yaml --- r: 93819 b: refs/heads/try c: 0fade3a h: refs/heads/master i: 93817: f6c4a3a 93815: 00f7bae v: v3
1 parent 133bb5e commit d57704a

File tree

5 files changed

+318
-69
lines changed

5 files changed

+318
-69
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 0da105a8b7b6b1e0568e8ff20f6ff4b13cc7ecc2
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
5-
refs/heads/try: 6cbc57cadbf8dfb2053893c917fb89ccbca0f253
5+
refs/heads/try: 0fade3a714f7a7f9bff5c11f9f37528d0ab168a1
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libstd/ascii.rs

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -55,74 +55,6 @@ impl Ascii {
5555
pub fn eq_ignore_case(self, other: Ascii) -> bool {
5656
ASCII_LOWER_MAP[self.chr] == ASCII_LOWER_MAP[other.chr]
5757
}
58-
59-
// the following methods are like ctype, and the implementation is inspired by musl
60-
61-
/// Check if the character is a letter (a-z, A-Z)
62-
#[inline]
63-
pub fn is_alpha(&self) -> bool {
64-
(self.chr >= 0x41 && self.chr <= 0x5A) || (self.chr >= 0x61 && self.chr <= 0x7A)
65-
}
66-
67-
/// Check if the character is a number (0-9)
68-
#[inline]
69-
pub fn is_digit(&self) -> bool {
70-
self.chr >= 0x31 && self.chr <= 0x39
71-
}
72-
73-
/// Check if the character is a letter or number
74-
#[inline]
75-
pub fn is_alnum(&self) -> bool {
76-
self.is_alpha() || self.is_digit()
77-
}
78-
79-
/// Check if the character is a space or horizontal tab
80-
#[inline]
81-
pub fn is_blank(&self) -> bool {
82-
self.chr == ' ' as u8 || self.chr == '\t' as u8
83-
}
84-
85-
/// Check if the character is a control character
86-
#[inline]
87-
pub fn is_control(&self) -> bool {
88-
self.chr <= 0x20 || self.chr == 0x7F
89-
}
90-
91-
/// Checks if the character is printable (except space)
92-
#[inline]
93-
pub fn is_graph(&self) -> bool {
94-
(self.chr - 0x21) < 0x5E
95-
}
96-
97-
/// Checks if the character is printable (including space)
98-
#[inline]
99-
pub fn is_print(&self) -> bool {
100-
(self.chr - 0x20) < 0x5F
101-
}
102-
103-
/// Checks if the character is lowercase
104-
#[inline]
105-
pub fn is_lower(&self) -> bool {
106-
(self.chr - 'a' as u8) < 26
107-
}
108-
109-
/// Checks if the character is uppercase
110-
#[inline]
111-
pub fn is_upper(&self) -> bool {
112-
(self.chr - 'A' as u8) < 26
113-
}
114-
115-
/// Checks if the character is punctuation
116-
#[inline]
117-
pub fn is_punctuation(&self) -> bool {
118-
self.is_graph() && !self.is_alnum()
119-
}
120-
121-
/// Checks if the character is a valid hex digit
122-
#[inline]
123-
pub fn is_hex(&self) -> bool {
124-
self.is_digit() || ((self.chr | 32u8) - 'a' as u8) < 6
125-
}
12658
}
12759

12860
impl ToStr for Ascii {

branches/try/src/libstd/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ pub mod result;
164164
pub mod either;
165165
pub mod hashmap;
166166
pub mod cell;
167+
pub mod mutable;
167168
pub mod trie;
168169

169170

branches/try/src/libstd/mutable.rs

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! A mutable memory location with dynamically checked borrow rules
12+
13+
use prelude::*;
14+
15+
use cast;
16+
use util::NonCopyable;
17+
18+
/// A mutable memory location with dynamically checked borrow rules
19+
#[no_freeze]
20+
pub struct Mut<T> {
21+
priv value: T,
22+
priv borrow: BorrowFlag,
23+
priv nc: NonCopyable
24+
}
25+
26+
// Values [1, MAX-1] represent the number of `Ref` active
27+
// (will not outgrow its range since `uint` is the size of the address space)
28+
type BorrowFlag = uint;
29+
static UNUSED: BorrowFlag = 0;
30+
static WRITING: BorrowFlag = -1;
31+
32+
impl<T> Mut<T> {
33+
/// Create a new `Mut` containing `value`
34+
pub fn new(value: T) -> Mut<T> {
35+
Mut {
36+
value: value,
37+
borrow: UNUSED,
38+
nc: NonCopyable
39+
}
40+
}
41+
42+
/// Consumes the `Mut`, returning the wrapped value.
43+
pub fn unwrap(self) -> T {
44+
assert!(self.borrow == UNUSED);
45+
self.value
46+
}
47+
48+
unsafe fn as_mut<'a>(&'a self) -> &'a mut Mut<T> {
49+
cast::transmute_mut(self)
50+
}
51+
52+
/// Attempts to immutably borrow the wrapped value.
53+
///
54+
/// The borrow lasts until the returned `Ref` exits scope. Multiple
55+
/// immutable borrows can be taken out at the same time.
56+
///
57+
/// Returns `None` if the value is currently mutably borrowed.
58+
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
59+
match self.borrow {
60+
WRITING => None,
61+
_ => {
62+
unsafe { self.as_mut().borrow += 1; }
63+
Some(Ref { parent: self })
64+
}
65+
}
66+
}
67+
68+
/// Immutably borrows the wrapped value.
69+
///
70+
/// The borrow lasts until the returned `Ref` exits scope. Multiple
71+
/// immutable borrows can be taken out at the same time.
72+
///
73+
/// # Failure
74+
///
75+
/// Fails if the value is currently mutably borrowed.
76+
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
77+
match self.try_borrow() {
78+
Some(ptr) => ptr,
79+
None => fail!("Mut<T> already mutably borrowed")
80+
}
81+
}
82+
83+
/// Mutably borrows the wrapped value.
84+
///
85+
/// The borrow lasts untile the returned `MutRef` exits scope. The value
86+
/// cannot be borrowed while this borrow is active.
87+
///
88+
/// Returns `None` if the value is currently borrowed.
89+
pub fn try_borrow_mut<'a>(&'a self) -> Option<MutRef<'a, T>> {
90+
match self.borrow {
91+
UNUSED => unsafe {
92+
let mut_self = self.as_mut();
93+
mut_self.borrow = WRITING;
94+
Some(MutRef { parent: mut_self })
95+
},
96+
_ => None
97+
}
98+
}
99+
100+
/// Mutably borrows the wrapped value.
101+
///
102+
/// The borrow lasts untile the returned `MutRef` exits scope. The value
103+
/// cannot be borrowed while this borrow is active.
104+
///
105+
/// # Failure
106+
///
107+
/// Fails if the value is currently borrowed.
108+
pub fn borrow_mut<'a>(&'a self) -> MutRef<'a, T> {
109+
match self.try_borrow_mut() {
110+
Some(ptr) => ptr,
111+
None => fail!("Mut<T> already borrowed")
112+
}
113+
}
114+
115+
/// Immutably borrows the wrapped value and applies `blk` to it.
116+
///
117+
/// # Failure
118+
///
119+
/// Fails if the value is currently mutably borrowed.
120+
#[inline]
121+
pub fn map<U>(&self, blk: |&T| -> U) -> U {
122+
let ptr = self.borrow();
123+
blk(ptr.get())
124+
}
125+
126+
/// Mutably borrows the wrapped value and applies `blk` to it.
127+
///
128+
/// # Failure
129+
///
130+
/// Fails if the value is currently borrowed.
131+
#[inline]
132+
pub fn map_mut<U>(&self, blk: |&mut T| -> U) -> U {
133+
let mut ptr = self.borrow_mut();
134+
blk(ptr.get())
135+
}
136+
}
137+
138+
impl<T: Clone> Clone for Mut<T> {
139+
fn clone(&self) -> Mut<T> {
140+
let x = self.borrow();
141+
Mut::new(x.get().clone())
142+
}
143+
}
144+
145+
impl<T: DeepClone> DeepClone for Mut<T> {
146+
fn deep_clone(&self) -> Mut<T> {
147+
let x = self.borrow();
148+
Mut::new(x.get().deep_clone())
149+
}
150+
}
151+
152+
impl<T: Eq> Eq for Mut<T> {
153+
fn eq(&self, other: &Mut<T>) -> bool {
154+
let a = self.borrow();
155+
let b = other.borrow();
156+
a.get() == b.get()
157+
}
158+
}
159+
160+
/// Wraps a borrowed reference to a value in a `Mut` box.
161+
pub struct Ref<'box, T> {
162+
priv parent: &'box Mut<T>
163+
}
164+
165+
#[unsafe_destructor]
166+
impl<'box, T> Drop for Ref<'box, T> {
167+
fn drop(&mut self) {
168+
assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
169+
unsafe { self.parent.as_mut().borrow -= 1; }
170+
}
171+
}
172+
173+
impl<'box, T> Ref<'box, T> {
174+
/// Retrieve an immutable reference to the stored value.
175+
#[inline]
176+
pub fn get<'a>(&'a self) -> &'a T {
177+
&self.parent.value
178+
}
179+
}
180+
181+
/// Wraps a mutable borrowed reference to a value in a `Mut` box.
182+
pub struct MutRef<'box, T> {
183+
priv parent: &'box mut Mut<T>
184+
}
185+
186+
#[unsafe_destructor]
187+
impl<'box, T> Drop for MutRef<'box, T> {
188+
fn drop(&mut self) {
189+
assert!(self.parent.borrow == WRITING);
190+
unsafe { self.parent.as_mut().borrow = UNUSED; }
191+
}
192+
}
193+
194+
impl<'box, T> MutRef<'box, T> {
195+
/// Retrieve a mutable reference to the stored value.
196+
#[inline]
197+
pub fn get<'a>(&'a mut self) -> &'a mut T {
198+
&mut self.parent.value
199+
}
200+
}
201+
202+
#[cfg(test)]
203+
mod test {
204+
use super::*;
205+
206+
#[test]
207+
fn double_imm_borrow() {
208+
let x = Mut::new(0);
209+
let _b1 = x.borrow();
210+
x.borrow();
211+
}
212+
213+
#[test]
214+
fn no_mut_then_imm_borrow() {
215+
let x = Mut::new(0);
216+
let _b1 = x.borrow_mut();
217+
assert!(x.try_borrow().is_none());
218+
}
219+
220+
#[test]
221+
fn no_imm_then_borrow_mut() {
222+
let x = Mut::new(0);
223+
let _b1 = x.borrow();
224+
assert!(x.try_borrow_mut().is_none());
225+
}
226+
227+
#[test]
228+
fn no_double_borrow_mut() {
229+
let x = Mut::new(0);
230+
let _b1 = x.borrow_mut();
231+
assert!(x.try_borrow_mut().is_none());
232+
}
233+
234+
#[test]
235+
fn imm_release_borrow_mut() {
236+
let x = Mut::new(0);
237+
{
238+
let _b1 = x.borrow();
239+
}
240+
x.borrow_mut();
241+
}
242+
243+
#[test]
244+
fn mut_release_borrow_mut() {
245+
let x = Mut::new(0);
246+
{
247+
let _b1 = x.borrow_mut();
248+
}
249+
x.borrow();
250+
}
251+
252+
#[test]
253+
fn double_borrow_single_release_no_borrow_mut() {
254+
let x = Mut::new(0);
255+
let _b1 = x.borrow();
256+
{
257+
let _b2 = x.borrow();
258+
}
259+
assert!(x.try_borrow_mut().is_none());
260+
}
261+
262+
#[test]
263+
fn map_ok() {
264+
let x = Mut::new(0);
265+
assert_eq!(1, x.map(|x| *x+1));
266+
}
267+
268+
#[test]
269+
#[should_fail]
270+
fn mut_borrow_map() {
271+
let x = Mut::new(0);
272+
let _b1 = x.borrow_mut();
273+
x.map(|x| *x+1);
274+
}
275+
276+
#[test]
277+
fn borrow_map() {
278+
let x = Mut::new(0);
279+
let _b1 = x.borrow();
280+
assert_eq!(1, x.map(|x| *x+1));
281+
}
282+
283+
#[test]
284+
fn map_mut_ok() {
285+
let x = Mut::new(0);
286+
x.map_mut(|x| *x += 1);
287+
let b = x.borrow();
288+
assert_eq!(1, *b.get());
289+
}
290+
291+
#[test]
292+
#[should_fail]
293+
fn borrow_map_mut() {
294+
let x = Mut::new(0);
295+
let _b = x.borrow();
296+
x.map_mut(|x| *x += 1);
297+
}
298+
}

0 commit comments

Comments
 (0)