core: convert vec::{head,head_opt} to return references
This commit is contained in:
@@ -211,7 +211,16 @@ pub pure fn build_sized_opt<A>(size: Option<uint>,
|
|||||||
// Accessors
|
// Accessors
|
||||||
|
|
||||||
/// Returns the first element of a vector
|
/// Returns the first element of a vector
|
||||||
pub pure fn head<T:Copy>(v: &[const T]) -> T { v[0] }
|
pub pure fn head<T>(v: &r/[T]) -> &r/T {
|
||||||
|
if v.len() == 0 { fail!(~"last_unsafe: empty vector") }
|
||||||
|
&v[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `Some(x)` where `x` is the first element of the slice `v`,
|
||||||
|
/// or `None` if the vector is empty.
|
||||||
|
pub pure fn head_opt<T>(v: &r/[T]) -> Option<&r/T> {
|
||||||
|
if v.len() == 0 { None } else { Some(&v[0]) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a vector containing all but the first element of a slice
|
/// Returns a vector containing all but the first element of a slice
|
||||||
pub pure fn tail<T:Copy>(v: &[const T]) -> ~[T] {
|
pub pure fn tail<T:Copy>(v: &[const T]) -> ~[T] {
|
||||||
@@ -1692,7 +1701,6 @@ impl<T> Container for &[const T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait CopyableVector<T> {
|
pub trait CopyableVector<T> {
|
||||||
pure fn head(&self) -> T;
|
|
||||||
pure fn init(&self) -> ~[T];
|
pure fn init(&self) -> ~[T];
|
||||||
pure fn last(&self) -> T;
|
pure fn last(&self) -> T;
|
||||||
pure fn slice(&self, start: uint, end: uint) -> ~[T];
|
pure fn slice(&self, start: uint, end: uint) -> ~[T];
|
||||||
@@ -1701,10 +1709,6 @@ pub trait CopyableVector<T> {
|
|||||||
|
|
||||||
/// Extension methods for vectors
|
/// Extension methods for vectors
|
||||||
impl<T:Copy> CopyableVector<T> for &[const T] {
|
impl<T:Copy> CopyableVector<T> for &[const T] {
|
||||||
/// Returns the first element of a vector
|
|
||||||
#[inline]
|
|
||||||
pure fn head(&self) -> T { head(*self) }
|
|
||||||
|
|
||||||
/// Returns all but the last elemnt of a vector
|
/// Returns all but the last elemnt of a vector
|
||||||
#[inline]
|
#[inline]
|
||||||
pure fn init(&self) -> ~[T] { init(*self) }
|
pure fn init(&self) -> ~[T] { init(*self) }
|
||||||
@@ -1726,7 +1730,9 @@ impl<T:Copy> CopyableVector<T> for &[const T] {
|
|||||||
|
|
||||||
pub trait ImmutableVector<T> {
|
pub trait ImmutableVector<T> {
|
||||||
pure fn view(&self, start: uint, end: uint) -> &self/[T];
|
pure fn view(&self, start: uint, end: uint) -> &self/[T];
|
||||||
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
|
pure fn head(&self) -> &self/T;
|
||||||
|
pure fn head_opt(&self) -> Option<&self/T>;
|
||||||
|
pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
|
||||||
pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U];
|
pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U];
|
||||||
pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U];
|
pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U];
|
||||||
fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U];
|
fn map_r<U>(&self, f: fn(x: &T) -> U) -> ~[U];
|
||||||
@@ -1743,6 +1749,14 @@ impl<T> ImmutableVector<T> for &[T] {
|
|||||||
slice(*self, start, end)
|
slice(*self, start, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the first element of a vector, failing if the vector is empty.
|
||||||
|
#[inline]
|
||||||
|
pure fn head(&self) -> &self/T { head(*self) }
|
||||||
|
|
||||||
|
/// Returns the first element of a vector
|
||||||
|
#[inline]
|
||||||
|
pure fn head_opt(&self) -> Option<&self/T> { head_opt(*self) }
|
||||||
|
|
||||||
/// Reduce a vector from right to left
|
/// Reduce a vector from right to left
|
||||||
#[inline]
|
#[inline]
|
||||||
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
|
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
|
||||||
@@ -2570,8 +2584,28 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_head() {
|
fn test_head() {
|
||||||
let a = ~[11, 12];
|
let mut a = ~[11];
|
||||||
assert (head(a) == 11);
|
assert a.head() == &11;
|
||||||
|
a = ~[11, 12];
|
||||||
|
assert a.head() == &11;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_fail]
|
||||||
|
#[ignore(cfg(windows))]
|
||||||
|
fn test_head_empty() {
|
||||||
|
let a: ~[int] = ~[];
|
||||||
|
a.head();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_head_opt() {
|
||||||
|
let mut a = ~[];
|
||||||
|
assert a.head_opt() == None;
|
||||||
|
a = ~[11];
|
||||||
|
assert a.head_opt().unwrap() == &11;
|
||||||
|
a = ~[11, 12];
|
||||||
|
assert a.head_opt().unwrap() == &11;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ fn cmd_help(args: &[~str]) -> ValidUsage {
|
|||||||
UsgExec(commandline) => {
|
UsgExec(commandline) => {
|
||||||
let words = str::words(commandline);
|
let words = str::words(commandline);
|
||||||
let (prog, args) = (words.head(), words.tail());
|
let (prog, args) = (words.head(), words.tail());
|
||||||
run::run_program(prog, args);
|
run::run_program(*prog, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Valid
|
Valid
|
||||||
@@ -186,7 +186,10 @@ fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
|
|||||||
Exec(commandline) => {
|
Exec(commandline) => {
|
||||||
let words = str::words(commandline);
|
let words = str::words(commandline);
|
||||||
let (prog, prog_args) = (words.head(), words.tail());
|
let (prog, prog_args) = (words.head(), words.tail());
|
||||||
let exitstatus = run::run_program(prog, prog_args + args);
|
let exitstatus = run::run_program(
|
||||||
|
*prog,
|
||||||
|
vec::append(vec::from_slice(prog_args), args)
|
||||||
|
);
|
||||||
os::set_exit_status(exitstatus);
|
os::set_exit_status(exitstatus);
|
||||||
Valid
|
Valid
|
||||||
}
|
}
|
||||||
@@ -221,11 +224,12 @@ fn usage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let args = os::args().tail();
|
let os_args = os::args();
|
||||||
|
let args = os_args.tail();
|
||||||
|
|
||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
for commands.each |command| {
|
for commands.each |command| {
|
||||||
if command.cmd == args.head() {
|
if command.cmd == *args.head() {
|
||||||
let result = do_command(command, args.tail());
|
let result = do_command(command, args.tail());
|
||||||
if result.is_valid() { return; }
|
if result.is_valid() { return; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ pub fn parse_config_(
|
|||||||
match getopts::getopts(args, opts) {
|
match getopts::getopts(args, opts) {
|
||||||
result::Ok(matches) => {
|
result::Ok(matches) => {
|
||||||
if matches.free.len() == 1 {
|
if matches.free.len() == 1 {
|
||||||
let input_crate = Path(vec::head(matches.free));
|
let input_crate = Path(copy *matches.free.head());
|
||||||
config_from_opts(&input_crate, &matches, program_output)
|
config_from_opts(&input_crate, &matches, program_output)
|
||||||
} else if matches.free.is_empty() {
|
} else if matches.free.is_empty() {
|
||||||
result::Err(~"no crates specified")
|
result::Err(~"no crates specified")
|
||||||
|
|||||||
@@ -144,14 +144,14 @@ fn parse_desc(desc: ~str) -> Option<~str> {
|
|||||||
fn first_sentence(s: ~str) -> Option<~str> {
|
fn first_sentence(s: ~str) -> Option<~str> {
|
||||||
let paras = paragraphs(s);
|
let paras = paragraphs(s);
|
||||||
if !paras.is_empty() {
|
if !paras.is_empty() {
|
||||||
let first_para = vec::head(paras);
|
let first_para = paras.head();
|
||||||
Some(str::replace(first_sentence_(first_para), ~"\n", ~" "))
|
Some(str::replace(first_sentence_(*first_para), ~"\n", ~" "))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn first_sentence_(s: ~str) -> ~str {
|
fn first_sentence_(s: &str) -> ~str {
|
||||||
let mut dotcount = 0;
|
let mut dotcount = 0;
|
||||||
// The index of the character following a single dot. This allows
|
// The index of the character following a single dot. This allows
|
||||||
// Things like [0..1) to appear in the brief description
|
// Things like [0..1) to appear in the brief description
|
||||||
@@ -169,16 +169,16 @@ fn first_sentence_(s: ~str) -> ~str {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
match idx {
|
match idx {
|
||||||
Some(idx) if idx > 2u => {
|
Some(idx) if idx > 2u => {
|
||||||
str::slice(s, 0u, idx - 1u)
|
str::from_slice(str::view(s, 0, idx - 1))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if str::ends_with(s, ~".") {
|
if str::ends_with(s, ~".") {
|
||||||
str::slice(s, 0u, str::len(s))
|
str::from_slice(s)
|
||||||
} else {
|
} else {
|
||||||
copy s
|
str::from_slice(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ fn unindent(s: &str) -> ~str {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !lines.is_empty() {
|
if !lines.is_empty() {
|
||||||
let unindented = ~[str::trim(vec::head(lines))]
|
let unindented = ~[lines.head().trim()]
|
||||||
+ do vec::tail(lines).map |line| {
|
+ do vec::tail(lines).map |line| {
|
||||||
if str::is_whitespace(*line) {
|
if str::is_whitespace(*line) {
|
||||||
copy *line
|
copy *line
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
// In this case, the code should compile and should
|
// In this case, the code should compile and should
|
||||||
// succeed at runtime
|
// succeed at runtime
|
||||||
use core::vec::{head, last, same_length, zip};
|
|
||||||
|
|
||||||
fn enum_chars(start: u8, end: u8) -> ~[char] {
|
fn enum_chars(start: u8, end: u8) -> ~[char] {
|
||||||
assert start < end;
|
assert start < end;
|
||||||
@@ -33,8 +32,8 @@ pub fn main() {
|
|||||||
let chars = enum_chars(a, j);
|
let chars = enum_chars(a, j);
|
||||||
let ints = enum_uints(k, l);
|
let ints = enum_uints(k, l);
|
||||||
|
|
||||||
let ps = zip(chars, ints);
|
let ps = vec::zip(chars, ints);
|
||||||
|
|
||||||
assert (head(ps) == ('a', 1u));
|
assert (ps.head() == &('a', 1u));
|
||||||
assert (last(ps) == (j as char, 10u));
|
assert (ps.last() == (j as char, 10u));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user