Skip to content

Commit 6720e33

Browse files
committed
---
yaml --- r: 2460 b: refs/heads/master c: e35984b h: refs/heads/master v: v3
1 parent d4d5c12 commit 6720e33

File tree

5 files changed

+59
-8
lines changed

5 files changed

+59
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: dc0aab47a77fbd47354dc6cf64cdb300cb6fd4b3
2+
refs/heads/master: e35984b6c67f2adf1c12d84c48fdf4f01be020e5

trunk/src/lib/Str.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ native "rust" mod rustrt {
1212
fn str_from_cstr(sbuf cstr) -> str;
1313
fn str_from_buf(sbuf buf, uint len) -> str;
1414
fn str_push_byte(str s, uint byte) -> str;
15+
fn str_slice(str s, uint begin, uint end) -> str;
1516
fn refcount[T](str s) -> uint;
1617
}
1718

@@ -384,13 +385,10 @@ fn substr(str s, uint begin, uint len) -> str {
384385
}
385386

386387
fn slice(str s, uint begin, uint end) -> str {
387-
let str accum = "";
388-
let uint i = begin;
389-
while (i < end) {
390-
push_byte(accum, s.(i));
391-
i += 1u;
392-
}
393-
ret accum;
388+
// FIXME: Typestate precondition
389+
assert (begin <= end);
390+
assert (end <= Str.byte_len(s));
391+
ret rustrt.str_slice(s, begin, end);
394392
}
395393

396394
fn shift_byte(&mutable str s) -> u8 {

trunk/src/rt/rust_builtin.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,24 @@ str_push_byte(rust_task* task, rust_str* v, size_t byte)
226226
return v;
227227
}
228228

229+
extern "C" CDECL rust_str*
230+
str_slice(rust_task* task, rust_str* v, size_t begin, size_t end)
231+
{
232+
size_t len = end - begin;
233+
rust_str *st =
234+
vec_alloc_with_data(task,
235+
len + 1, // +1 to fit at least '\0'
236+
len,
237+
1,
238+
len ? v->data + begin : NULL);
239+
if (!st) {
240+
task->fail(2);
241+
return NULL;
242+
}
243+
st->data[st->fill++] = '\0';
244+
return st;
245+
}
246+
229247
extern "C" CDECL char const *
230248
str_buf(rust_task *task, rust_str *s)
231249
{

trunk/src/rt/rustrt.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ str_from_buf
3232
str_from_cstr
3333
str_from_vec
3434
str_push_byte
35+
str_slice
3536
str_vec
3637
task_sleep
3738
unsafe_vec_to_mut

trunk/src/test/run-pass/lib-str.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// xfail-boot
2+
// xfail-stage0
3+
14
use std;
25
import std.Str;
36

@@ -98,6 +101,36 @@ fn test_to_upper() {
98101
assert (Str.eq(expected, actual));
99102
}
100103

104+
fn test_slice() {
105+
assert (Str.eq("ab", Str.slice("abc", 0u, 2u)));
106+
assert (Str.eq("bc", Str.slice("abc", 1u, 3u)));
107+
assert (Str.eq("", Str.slice("abc", 1u, 1u)));
108+
109+
fn a_million_letter_a() -> str {
110+
auto i = 0;
111+
auto res = "";
112+
while (i < 100000) {
113+
res += "aaaaaaaaaa";
114+
i += 1;
115+
}
116+
ret res;
117+
}
118+
119+
fn half_a_million_letter_a() -> str {
120+
auto i = 0;
121+
auto res = "";
122+
while (i < 100000) {
123+
res += "aaaaa";
124+
i += 1;
125+
}
126+
ret res;
127+
}
128+
129+
assert (Str.eq(half_a_million_letter_a(),
130+
Str.slice(a_million_letter_a(),
131+
0u,
132+
500000u)));
133+
}
101134

102135
fn main() {
103136
test_bytes_len();
@@ -108,4 +141,5 @@ fn main() {
108141
test_concat();
109142
test_connect();
110143
test_to_upper();
144+
test_slice();
111145
}

0 commit comments

Comments
 (0)