Skip to content

Commit 359bb3e

Browse files
committed
core: convert vec::{head,head_opt} to return references
1 parent 431e756 commit 359bb3e

File tree

6 files changed

+68
-31
lines changed

6 files changed

+68
-31
lines changed

src/libcore/vec.rs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,16 @@ pub pure fn build_sized_opt<A>(size: Option<uint>,
211211
// Accessors
212212

213213
/// Returns the first element of a vector
214-
pub pure fn head<T:Copy>(v: &[const T]) -> T { v[0] }
214+
pub pure fn head<T>(v: &r/[T]) -> &r/T {
215+
if v.len() == 0 { fail!(~"last_unsafe: empty vector") }
216+
&v[0]
217+
}
218+
219+
/// Returns `Some(x)` where `x` is the first element of the slice `v`,
220+
/// or `None` if the vector is empty.
221+
pub pure fn head_opt<T>(v: &r/[T]) -> Option<&r/T> {
222+
if v.len() == 0 { None } else { Some(&v[0]) }
223+
}
215224
216225
/// Returns a vector containing all but the first element of a slice
217226
pub pure fn tail<T:Copy>(v: &[const T]) -> ~[T] {
@@ -1692,7 +1701,6 @@ impl<T> Container for &[const T] {
16921701
}
16931702

16941703
pub trait CopyableVector<T> {
1695-
pure fn head(&self) -> T;
16961704
pure fn init(&self) -> ~[T];
16971705
pure fn last(&self) -> T;
16981706
pure fn slice(&self, start: uint, end: uint) -> ~[T];
@@ -1701,10 +1709,6 @@ pub trait CopyableVector<T> {
17011709

17021710
/// Extension methods for vectors
17031711
impl<T:Copy> CopyableVector<T> for &[const T] {
1704-
/// Returns the first element of a vector
1705-
#[inline]
1706-
pure fn head(&self) -> T { head(*self) }
1707-
17081712
/// Returns all but the last elemnt of a vector
17091713
#[inline]
17101714
pure fn init(&self) -> ~[T] { init(*self) }
@@ -1726,7 +1730,9 @@ impl<T:Copy> CopyableVector<T> for &[const T] {
17261730

17271731
pub trait ImmutableVector<T> {
17281732
pure fn view(&self, start: uint, end: uint) -> &self/[T];
1729-
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
1733+
pure fn head(&self) -> &self/T;
1734+
pure fn head_opt(&self) -> Option<&self/T>;
1735+
pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
17301736
pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U];
17311737
pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U];
17321738
fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U];
@@ -1743,6 +1749,14 @@ impl<T> ImmutableVector<T> for &[T] {
17431749
slice(*self, start, end)
17441750
}
17451751

1752+
/// Returns the first element of a vector, failing if the vector is empty.
1753+
#[inline]
1754+
pure fn head(&self) -> &self/T { head(*self) }
1755+
1756+
/// Returns the first element of a vector
1757+
#[inline]
1758+
pure fn head_opt(&self) -> Option<&self/T> { head_opt(*self) }
1759+
17461760
/// Reduce a vector from right to left
17471761
#[inline]
17481762
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
@@ -2570,8 +2584,28 @@ mod tests {
25702584

25712585
#[test]
25722586
fn test_head() {
2573-
let a = ~[11, 12];
2574-
assert (head(a) == 11);
2587+
let mut a = ~[11];
2588+
assert a.head() == &11;
2589+
a = ~[11, 12];
2590+
assert a.head() == &11;
2591+
}
2592+
2593+
#[test]
2594+
#[should_fail]
2595+
#[ignore(cfg(windows))]
2596+
fn test_head_empty() {
2597+
let a: ~[int] = ~[];
2598+
a.head();
2599+
}
2600+
2601+
#[test]
2602+
fn test_head_opt() {
2603+
let mut a = ~[];
2604+
assert a.head_opt() == None;
2605+
a = ~[11];
2606+
assert a.head_opt().unwrap() == &11;
2607+
a = ~[11, 12];
2608+
assert a.head_opt().unwrap() == &11;
25752609
}
25762610

25772611
#[test]

src/librust/rust.rc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ fn cmd_help(args: &[~str]) -> ValidUsage {
130130
UsgExec(commandline) => {
131131
let words = str::words(commandline);
132132
let (prog, args) = (words.head(), words.tail());
133-
run::run_program(prog, args);
133+
run::run_program(*prog, args);
134134
}
135135
}
136136
Valid
@@ -186,7 +186,10 @@ fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
186186
Exec(commandline) => {
187187
let words = str::words(commandline);
188188
let (prog, prog_args) = (words.head(), words.tail());
189-
let exitstatus = run::run_program(prog, prog_args + args);
189+
let exitstatus = run::run_program(
190+
*prog,
191+
vec::append(vec::from_slice(prog_args), args)
192+
);
190193
os::set_exit_status(exitstatus);
191194
Valid
192195
}
@@ -221,11 +224,12 @@ fn usage() {
221224
}
222225

223226
pub fn main() {
224-
let args = os::args().tail();
227+
let os_args = os::args();
228+
let args = os_args.tail();
225229

226230
if !args.is_empty() {
227231
for commands.each |command| {
228-
if command.cmd == args.head() {
232+
if command.cmd == *args.head() {
229233
let result = do_command(command, args.tail());
230234
if result.is_valid() { return; }
231235
}

src/librustdoc/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub fn parse_config_(
132132
match getopts::getopts(args, opts) {
133133
result::Ok(matches) => {
134134
if matches.free.len() == 1 {
135-
let input_crate = Path(vec::head(matches.free));
135+
let input_crate = Path(copy *matches.free.head());
136136
config_from_opts(&input_crate, &matches, program_output)
137137
} else if matches.free.is_empty() {
138138
result::Err(~"no crates specified")

src/librustdoc/desc_to_brief_pass.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,14 @@ fn parse_desc(desc: ~str) -> Option<~str> {
144144
fn first_sentence(s: ~str) -> Option<~str> {
145145
let paras = paragraphs(s);
146146
if !paras.is_empty() {
147-
let first_para = vec::head(paras);
148-
Some(str::replace(first_sentence_(first_para), ~"\n", ~" "))
147+
let first_para = paras.head();
148+
Some(str::replace(first_sentence_(*first_para), ~"\n", ~" "))
149149
} else {
150150
None
151151
}
152152
}
153153
154-
fn first_sentence_(s: ~str) -> ~str {
154+
fn first_sentence_(s: &str) -> ~str {
155155
let mut dotcount = 0;
156156
// The index of the character following a single dot. This allows
157157
// Things like [0..1) to appear in the brief description
@@ -169,16 +169,16 @@ fn first_sentence_(s: ~str) -> ~str {
169169
}
170170
};
171171
match idx {
172-
Some(idx) if idx > 2u => {
173-
str::slice(s, 0u, idx - 1u)
174-
}
175-
_ => {
176-
if str::ends_with(s, ~".") {
177-
str::slice(s, 0u, str::len(s))
178-
} else {
179-
copy s
172+
Some(idx) if idx > 2u => {
173+
str::from_slice(str::view(s, 0, idx - 1))
174+
}
175+
_ => {
176+
if str::ends_with(s, ~".") {
177+
str::from_slice(s)
178+
} else {
179+
str::from_slice(s)
180+
}
180181
}
181-
}
182182
}
183183
}
184184

src/librustdoc/unindent_pass.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fn unindent(s: &str) -> ~str {
7878
};
7979

8080
if !lines.is_empty() {
81-
let unindented = ~[str::trim(vec::head(lines))]
81+
let unindented = ~[lines.head().trim()]
8282
+ do vec::tail(lines).map |line| {
8383
if str::is_whitespace(*line) {
8484
copy *line

src/test/run-pass/zip-same-length.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
// In this case, the code should compile and should
1212
// succeed at runtime
13-
use core::vec::{head, last, same_length, zip};
1413

1514
fn enum_chars(start: u8, end: u8) -> ~[char] {
1615
assert start < end;
@@ -33,8 +32,8 @@ pub fn main() {
3332
let chars = enum_chars(a, j);
3433
let ints = enum_uints(k, l);
3534

36-
let ps = zip(chars, ints);
35+
let ps = vec::zip(chars, ints);
3736

38-
assert (head(ps) == ('a', 1u));
39-
assert (last(ps) == (j as char, 10u));
37+
assert (ps.head() == &('a', 1u));
38+
assert (ps.last() == (j as char, 10u));
4039
}

0 commit comments

Comments
 (0)