core: convert vec::{last,last_opt} to return references
This commit is contained in:
parent
a18bf8c67d
commit
743cfce703
15 changed files with 74 additions and 51 deletions
|
@ -212,7 +212,7 @@ pub pure fn build_sized_opt<A>(size: Option<uint>,
|
||||||
|
|
||||||
/// Returns the first element of a vector
|
/// Returns the first element of a vector
|
||||||
pub pure fn head<T>(v: &r/[T]) -> &r/T {
|
pub pure fn head<T>(v: &r/[T]) -> &r/T {
|
||||||
if v.len() == 0 { fail!(~"last_unsafe: empty vector") }
|
if v.len() == 0 { fail!(~"head: empty vector") }
|
||||||
&v[0]
|
&v[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,18 +237,15 @@ pub pure fn initn<T>(v: &r/[T], n: uint) -> &r/[T] {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the last element of the slice `v`, failing if the slice is empty.
|
/// Returns the last element of the slice `v`, failing if the slice is empty.
|
||||||
pub pure fn last<T:Copy>(v: &[const T]) -> T {
|
pub pure fn last<T>(v: &r/[T]) -> &r/T {
|
||||||
if len(v) == 0u { fail!(~"last_unsafe: empty vector") }
|
if v.len() == 0 { fail!(~"last: empty vector") }
|
||||||
v[len(v) - 1u]
|
&v[v.len() - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Returns `Some(x)` where `x` is the last element of the slice `v`, or
|
||||||
* Returns `Some(x)` where `x` is the last element of the slice `v`,
|
/// `None` if the vector is empty.
|
||||||
* or `none` if the vector is empty.
|
pub pure fn last_opt<T>(v: &r/[T]) -> Option<&r/T> {
|
||||||
*/
|
if v.len() == 0 { None } else { Some(&v[v.len() - 1]) }
|
||||||
pub pure fn last_opt<T:Copy>(v: &[const T]) -> Option<T> {
|
|
||||||
if len(v) == 0u { return None; }
|
|
||||||
Some(v[len(v) - 1u])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a slice that points into another slice.
|
/// Return a slice that points into another slice.
|
||||||
|
@ -1696,16 +1693,11 @@ impl<T> Container for &[const T] {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CopyableVector<T> {
|
pub trait CopyableVector<T> {
|
||||||
pure fn last(&self) -> T;
|
|
||||||
pure fn slice(&self, start: uint, end: uint) -> ~[T];
|
pure fn slice(&self, start: uint, end: uint) -> ~[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 last element of a `v`, failing if the vector is empty.
|
|
||||||
#[inline]
|
|
||||||
pure fn last(&self) -> T { last(*self) }
|
|
||||||
|
|
||||||
/// Returns a copy of the elements from [`start`..`end`) from `v`.
|
/// Returns a copy of the elements from [`start`..`end`) from `v`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pure fn slice(&self, start: uint, end: uint) -> ~[T] {
|
pure fn slice(&self, start: uint, end: uint) -> ~[T] {
|
||||||
|
@ -1721,6 +1713,8 @@ pub trait ImmutableVector<T> {
|
||||||
pure fn tailn(&self, n: uint) -> &self/[T];
|
pure fn tailn(&self, n: uint) -> &self/[T];
|
||||||
pure fn init(&self) -> &self/[T];
|
pure fn init(&self) -> &self/[T];
|
||||||
pure fn initn(&self, n: uint) -> &self/[T];
|
pure fn initn(&self, n: uint) -> &self/[T];
|
||||||
|
pure fn last(&self) -> &self/T;
|
||||||
|
pure fn last_opt(&self) -> Option<&self/T>;
|
||||||
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;
|
||||||
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];
|
||||||
|
@ -1762,6 +1756,14 @@ impl<T> ImmutableVector<T> for &[T] {
|
||||||
#[inline]
|
#[inline]
|
||||||
pure fn initn(&self, n: uint) -> &self/[T] { initn(*self, n) }
|
pure fn initn(&self, n: uint) -> &self/[T] { initn(*self, n) }
|
||||||
|
|
||||||
|
/// Returns the last element of a `v`, failing if the vector is empty.
|
||||||
|
#[inline]
|
||||||
|
pure fn last(&self) -> &self/T { last(*self) }
|
||||||
|
|
||||||
|
/// Returns the last element of a `v`, failing if the vector is empty.
|
||||||
|
#[inline]
|
||||||
|
pure fn last_opt(&self) -> Option<&self/T> { last_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 {
|
||||||
|
@ -2679,12 +2681,27 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_last() {
|
fn test_last() {
|
||||||
let mut n = last_opt(~[]);
|
let mut a = ~[11];
|
||||||
assert (n.is_none());
|
assert a.last() == &11;
|
||||||
n = last_opt(~[1, 2, 3]);
|
a = ~[11, 12];
|
||||||
assert (n == Some(3));
|
assert a.last() == &12;
|
||||||
n = last_opt(~[1, 2, 3, 4, 5]);
|
}
|
||||||
assert (n == Some(5));
|
|
||||||
|
#[test]
|
||||||
|
#[should_fail]
|
||||||
|
fn test_last_empty() {
|
||||||
|
let a: ~[int] = ~[];
|
||||||
|
a.last();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_last_opt() {
|
||||||
|
let mut a = ~[];
|
||||||
|
assert a.last_opt() == None;
|
||||||
|
a = ~[11];
|
||||||
|
assert a.last_opt().unwrap() == &11;
|
||||||
|
a = ~[11, 12];
|
||||||
|
assert a.last_opt().unwrap() == &12;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -81,7 +81,9 @@ fn warn_if_multiple_versions(e: @mut Env,
|
||||||
|
|
||||||
if crate_cache.len() != 0u {
|
if crate_cache.len() != 0u {
|
||||||
let name = loader::crate_name_from_metas(
|
let name = loader::crate_name_from_metas(
|
||||||
/*bad*/copy *crate_cache.last().metas);
|
*crate_cache[crate_cache.len() - 1].metas
|
||||||
|
);
|
||||||
|
|
||||||
let (matches, non_matches) =
|
let (matches, non_matches) =
|
||||||
partition(crate_cache.map_to_vec(|&entry| {
|
partition(crate_cache.map_to_vec(|&entry| {
|
||||||
let othername = loader::crate_name_from_metas(
|
let othername = loader::crate_name_from_metas(
|
||||||
|
|
|
@ -143,9 +143,9 @@ fn find_library_crate_aux(
|
||||||
|
|
||||||
pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @~str {
|
pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @~str {
|
||||||
let name_items = attr::find_meta_items_by_name(metas, ~"name");
|
let name_items = attr::find_meta_items_by_name(metas, ~"name");
|
||||||
match vec::last_opt(name_items) {
|
match name_items.last_opt() {
|
||||||
Some(i) => {
|
Some(i) => {
|
||||||
match attr::get_meta_item_value_str(i) {
|
match attr::get_meta_item_value_str(*i) {
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
// FIXME (#2406): Probably want a warning here since the user
|
// FIXME (#2406): Probably want a warning here since the user
|
||||||
// is using the wrong type of meta item.
|
// is using the wrong type of meta item.
|
||||||
|
|
|
@ -1438,7 +1438,7 @@ pub impl Resolver {
|
||||||
type_value_ns => AnyNS
|
type_value_ns => AnyNS
|
||||||
};
|
};
|
||||||
|
|
||||||
let source_ident = full_path.idents.last();
|
let source_ident = *full_path.idents.last();
|
||||||
let subclass = @SingleImport(binding,
|
let subclass = @SingleImport(binding,
|
||||||
source_ident,
|
source_ident,
|
||||||
ns);
|
ns);
|
||||||
|
@ -4087,7 +4087,7 @@ pub impl Resolver {
|
||||||
|
|
||||||
// First, check to see whether the name is a primitive type.
|
// First, check to see whether the name is a primitive type.
|
||||||
if path.idents.len() == 1 {
|
if path.idents.len() == 1 {
|
||||||
let name = path.idents.last();
|
let name = *path.idents.last();
|
||||||
|
|
||||||
match self.primitive_type_table
|
match self.primitive_type_table
|
||||||
.primitive_types
|
.primitive_types
|
||||||
|
@ -4110,7 +4110,7 @@ pub impl Resolver {
|
||||||
debug!("(resolving type) resolved `%s` to \
|
debug!("(resolving type) resolved `%s` to \
|
||||||
type %?",
|
type %?",
|
||||||
*self.session.str_of(
|
*self.session.str_of(
|
||||||
path.idents.last()),
|
*path.idents.last()),
|
||||||
def);
|
def);
|
||||||
result_def = Some(def);
|
result_def = Some(def);
|
||||||
}
|
}
|
||||||
|
@ -4296,7 +4296,7 @@ pub impl Resolver {
|
||||||
path.span,
|
path.span,
|
||||||
fmt!("not an enum variant: %s",
|
fmt!("not an enum variant: %s",
|
||||||
*self.session.str_of(
|
*self.session.str_of(
|
||||||
path.idents.last())));
|
*path.idents.last())));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.session.span_err(path.span,
|
self.session.span_err(path.span,
|
||||||
|
@ -4418,7 +4418,7 @@ pub impl Resolver {
|
||||||
namespace);
|
namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.resolve_identifier(path.idents.last(),
|
return self.resolve_identifier(*path.idents.last(),
|
||||||
namespace,
|
namespace,
|
||||||
check_ribs,
|
check_ribs,
|
||||||
path.span);
|
path.span);
|
||||||
|
@ -4552,7 +4552,7 @@ pub impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = path.idents.last();
|
let name = *path.idents.last();
|
||||||
match self.resolve_definition_of_name_in_module(containing_module,
|
match self.resolve_definition_of_name_in_module(containing_module,
|
||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
|
@ -4601,7 +4601,7 @@ pub impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = path.idents.last();
|
let name = *path.idents.last();
|
||||||
match self.resolve_definition_of_name_in_module(containing_module,
|
match self.resolve_definition_of_name_in_module(containing_module,
|
||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
|
|
|
@ -2207,7 +2207,7 @@ pub fn register_fn_fuller(ccx: @CrateContext,
|
||||||
ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
|
ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
|
||||||
|
|
||||||
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
|
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
|
||||||
path_elt_to_str(path.last(), ccx.sess.parse_sess.interner)
|
path_elt_to_str(*path.last(), ccx.sess.parse_sess.interner)
|
||||||
} else {
|
} else {
|
||||||
mangle_exported_name(ccx, /*bad*/copy path, node_type)
|
mangle_exported_name(ccx, /*bad*/copy path, node_type)
|
||||||
};
|
};
|
||||||
|
|
|
@ -792,12 +792,14 @@ pub fn create_arg(bcx: block, arg: ast::arg, sp: span)
|
||||||
match arg.pat.node {
|
match arg.pat.node {
|
||||||
ast::pat_ident(_, path, _) => {
|
ast::pat_ident(_, path, _) => {
|
||||||
// XXX: This is wrong; it should work for multiple bindings.
|
// XXX: This is wrong; it should work for multiple bindings.
|
||||||
let mdnode = create_var(tg,
|
let mdnode = create_var(
|
||||||
|
tg,
|
||||||
context.node,
|
context.node,
|
||||||
*cx.sess.str_of(path.idents.last()),
|
*cx.sess.str_of(*path.idents.last()),
|
||||||
filemd.node,
|
filemd.node,
|
||||||
loc.line as int,
|
loc.line as int,
|
||||||
tymd.node);
|
tymd.node
|
||||||
|
);
|
||||||
|
|
||||||
let mdval = @Metadata {
|
let mdval = @Metadata {
|
||||||
node: mdnode,
|
node: mdnode,
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub fn parse_name(id: ~str) -> result::Result<~str, ~str> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result::Ok(parts.last())
|
result::Ok(copy *parts.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ListenerFn {
|
struct ListenerFn {
|
||||||
|
@ -516,9 +516,11 @@ pub fn get_pkg(id: ~str,
|
||||||
return result::Err(~"package not found");
|
return result::Err(~"package not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
result::Ok(sort::merge_sort(possibs, |v1, v2| {
|
let possibs = sort::merge_sort(possibs, |v1, v2| {
|
||||||
v1.vers <= v2.vers
|
v1.vers <= v2.vers
|
||||||
}).last())
|
});
|
||||||
|
|
||||||
|
result::Ok(copy *possibs.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_pkg(pkg: &Package) -> bool {
|
pub fn add_pkg(pkg: &Package) -> bool {
|
||||||
|
|
|
@ -346,7 +346,7 @@ pub impl BigUint {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut shift = 0;
|
let mut shift = 0;
|
||||||
let mut n = other.data.last();
|
let mut n = *other.data.last();
|
||||||
while n < (1 << BigDigit::bits - 2) {
|
while n < (1 << BigDigit::bits - 2) {
|
||||||
n <<= 1;
|
n <<= 1;
|
||||||
shift += 1;
|
shift += 1;
|
||||||
|
@ -384,7 +384,7 @@ pub impl BigUint {
|
||||||
}
|
}
|
||||||
|
|
||||||
let an = vec::slice(a.data, a.data.len() - n, a.data.len());
|
let an = vec::slice(a.data, a.data.len() - n, a.data.len());
|
||||||
let bn = b.data.last();
|
let bn = *b.data.last();
|
||||||
let mut d = ~[];
|
let mut d = ~[];
|
||||||
let mut carry = 0;
|
let mut carry = 0;
|
||||||
for vec::rev_each(an) |elt| {
|
for vec::rev_each(an) |elt| {
|
||||||
|
|
|
@ -759,7 +759,7 @@ pub fn Decoder(json: Json) -> Decoder {
|
||||||
priv impl Decoder {
|
priv impl Decoder {
|
||||||
fn peek(&self) -> &self/Json {
|
fn peek(&self) -> &self/Json {
|
||||||
if self.stack.len() == 0 { self.stack.push(&self.json); }
|
if self.stack.len() == 0 { self.stack.push(&self.json); }
|
||||||
vec::last(self.stack)
|
self.stack[self.stack.len() - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop(&self) -> &self/Json {
|
fn pop(&self) -> &self/Json {
|
||||||
|
|
|
@ -197,7 +197,7 @@ mod tests {
|
||||||
let mut sorted = merge_sort(data, le);
|
let mut sorted = merge_sort(data, le);
|
||||||
let mut heap = from_vec(data);
|
let mut heap = from_vec(data);
|
||||||
while !heap.is_empty() {
|
while !heap.is_empty() {
|
||||||
assert *heap.top() == sorted.last();
|
assert heap.top() == sorted.last();
|
||||||
assert heap.pop() == sorted.pop();
|
assert heap.pop() == sorted.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) }
|
pub pure fn path_to_ident(p: @path) -> ident { copy *p.idents.last() }
|
||||||
|
|
||||||
pub pure fn local_def(id: node_id) -> def_id {
|
pub pure fn local_def(id: node_id) -> def_id {
|
||||||
ast::def_id { crate: local_crate, node: id }
|
ast::def_id { crate: local_crate, node: id }
|
||||||
|
|
|
@ -229,7 +229,7 @@ fn last_meta_item_by_name(items: &[@ast::meta_item], name: &str)
|
||||||
-> Option<@ast::meta_item> {
|
-> Option<@ast::meta_item> {
|
||||||
|
|
||||||
let items = attr::find_meta_items_by_name(items, name);
|
let items = attr::find_meta_items_by_name(items, name);
|
||||||
vec::last_opt(items)
|
items.last_opt().map(|item| **item)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_meta_item_value_str_by_name(items: &[@ast::meta_item], name: &str)
|
pub fn last_meta_item_value_str_by_name(items: &[@ast::meta_item], name: &str)
|
||||||
|
|
|
@ -167,7 +167,7 @@ pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan {
|
||||||
while r.cur.idx >= r.cur.readme.len() {
|
while r.cur.idx >= r.cur.readme.len() {
|
||||||
/* done with this set; pop or repeat? */
|
/* done with this set; pop or repeat? */
|
||||||
if ! r.cur.dotdotdoted
|
if ! r.cur.dotdotdoted
|
||||||
|| r.repeat_idx.last() == r.repeat_len.last() - 1 {
|
|| { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } {
|
||||||
|
|
||||||
match r.cur.up {
|
match r.cur.up {
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
|
||||||
fn_box: || @Cons((), fn_box()),
|
fn_box: || @Cons((), fn_box()),
|
||||||
tuple: (@Cons((), st.tuple.first()),
|
tuple: (@Cons((), st.tuple.first()),
|
||||||
~Cons((), @*st.tuple.second())),
|
~Cons((), @*st.tuple.second())),
|
||||||
vec: st.vec + ~[@Cons((), st.vec.last())],
|
vec: st.vec + ~[@Cons((), *st.vec.last())],
|
||||||
res: r(@Cons((), st.res._l))
|
res: r(@Cons((), st.res._l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,5 @@ pub fn main() {
|
||||||
let ps = vec::zip(chars, ints);
|
let ps = vec::zip(chars, ints);
|
||||||
|
|
||||||
assert (ps.head() == &('a', 1u));
|
assert (ps.head() == &('a', 1u));
|
||||||
assert (ps.last() == (j as char, 10u));
|
assert (ps.last() == &(j as char, 10u));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue