core: convert vec::{last,last_opt} to return references
This commit is contained in:
parent
a18bf8c67d
commit
743cfce703
@ -212,7 +212,7 @@ pub pure fn build_sized_opt<A>(size: Option<uint>,
|
||||
|
||||
/// Returns the first element of a vector
|
||||
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]
|
||||
}
|
||||
|
||||
@ -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.
|
||||
pub pure fn last<T:Copy>(v: &[const T]) -> T {
|
||||
if len(v) == 0u { fail!(~"last_unsafe: empty vector") }
|
||||
v[len(v) - 1u]
|
||||
pub pure fn last<T>(v: &r/[T]) -> &r/T {
|
||||
if v.len() == 0 { fail!(~"last: empty vector") }
|
||||
&v[v.len() - 1]
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `Some(x)` where `x` is the last element of the slice `v`,
|
||||
* or `none` if the vector is empty.
|
||||
*/
|
||||
pub pure fn last_opt<T:Copy>(v: &[const T]) -> Option<T> {
|
||||
if len(v) == 0u { return None; }
|
||||
Some(v[len(v) - 1u])
|
||||
/// Returns `Some(x)` where `x` is the last element of the slice `v`, 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]) }
|
||||
}
|
||||
|
||||
/// Return a slice that points into another slice.
|
||||
@ -1696,16 +1693,11 @@ impl<T> Container for &[const T] {
|
||||
}
|
||||
|
||||
pub trait CopyableVector<T> {
|
||||
pure fn last(&self) -> T;
|
||||
pure fn slice(&self, start: uint, end: uint) -> ~[T];
|
||||
}
|
||||
|
||||
/// Extension methods for vectors
|
||||
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`.
|
||||
#[inline]
|
||||
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 init(&self) -> &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 map<U>(&self, f: fn(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]
|
||||
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
|
||||
#[inline]
|
||||
pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
|
||||
@ -2679,12 +2681,27 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_last() {
|
||||
let mut n = last_opt(~[]);
|
||||
assert (n.is_none());
|
||||
n = last_opt(~[1, 2, 3]);
|
||||
assert (n == Some(3));
|
||||
n = last_opt(~[1, 2, 3, 4, 5]);
|
||||
assert (n == Some(5));
|
||||
let mut a = ~[11];
|
||||
assert a.last() == &11;
|
||||
a = ~[11, 12];
|
||||
assert a.last() == &12;
|
||||
}
|
||||
|
||||
#[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]
|
||||
|
@ -81,7 +81,9 @@ fn warn_if_multiple_versions(e: @mut Env,
|
||||
|
||||
if crate_cache.len() != 0u {
|
||||
let name = loader::crate_name_from_metas(
|
||||
/*bad*/copy *crate_cache.last().metas);
|
||||
*crate_cache[crate_cache.len() - 1].metas
|
||||
);
|
||||
|
||||
let (matches, non_matches) =
|
||||
partition(crate_cache.map_to_vec(|&entry| {
|
||||
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 {
|
||||
let name_items = attr::find_meta_items_by_name(metas, ~"name");
|
||||
match vec::last_opt(name_items) {
|
||||
match name_items.last_opt() {
|
||||
Some(i) => {
|
||||
match attr::get_meta_item_value_str(i) {
|
||||
match attr::get_meta_item_value_str(*i) {
|
||||
Some(n) => n,
|
||||
// FIXME (#2406): Probably want a warning here since the user
|
||||
// is using the wrong type of meta item.
|
||||
|
@ -1438,7 +1438,7 @@ pub impl Resolver {
|
||||
type_value_ns => AnyNS
|
||||
};
|
||||
|
||||
let source_ident = full_path.idents.last();
|
||||
let source_ident = *full_path.idents.last();
|
||||
let subclass = @SingleImport(binding,
|
||||
source_ident,
|
||||
ns);
|
||||
@ -4087,7 +4087,7 @@ pub impl Resolver {
|
||||
|
||||
// First, check to see whether the name is a primitive type.
|
||||
if path.idents.len() == 1 {
|
||||
let name = path.idents.last();
|
||||
let name = *path.idents.last();
|
||||
|
||||
match self.primitive_type_table
|
||||
.primitive_types
|
||||
@ -4110,7 +4110,7 @@ pub impl Resolver {
|
||||
debug!("(resolving type) resolved `%s` to \
|
||||
type %?",
|
||||
*self.session.str_of(
|
||||
path.idents.last()),
|
||||
*path.idents.last()),
|
||||
def);
|
||||
result_def = Some(def);
|
||||
}
|
||||
@ -4296,7 +4296,7 @@ pub impl Resolver {
|
||||
path.span,
|
||||
fmt!("not an enum variant: %s",
|
||||
*self.session.str_of(
|
||||
path.idents.last())));
|
||||
*path.idents.last())));
|
||||
}
|
||||
None => {
|
||||
self.session.span_err(path.span,
|
||||
@ -4418,7 +4418,7 @@ pub impl Resolver {
|
||||
namespace);
|
||||
}
|
||||
|
||||
return self.resolve_identifier(path.idents.last(),
|
||||
return self.resolve_identifier(*path.idents.last(),
|
||||
namespace,
|
||||
check_ribs,
|
||||
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,
|
||||
name,
|
||||
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,
|
||||
name,
|
||||
namespace,
|
||||
|
@ -2207,7 +2207,7 @@ pub fn register_fn_fuller(ccx: @CrateContext,
|
||||
ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
|
||||
|
||||
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 {
|
||||
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 {
|
||||
ast::pat_ident(_, path, _) => {
|
||||
// XXX: This is wrong; it should work for multiple bindings.
|
||||
let mdnode = create_var(tg,
|
||||
context.node,
|
||||
*cx.sess.str_of(path.idents.last()),
|
||||
filemd.node,
|
||||
loc.line as int,
|
||||
tymd.node);
|
||||
let mdnode = create_var(
|
||||
tg,
|
||||
context.node,
|
||||
*cx.sess.str_of(*path.idents.last()),
|
||||
filemd.node,
|
||||
loc.line as int,
|
||||
tymd.node
|
||||
);
|
||||
|
||||
let mdval = @Metadata {
|
||||
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 {
|
||||
@ -516,9 +516,11 @@ pub fn get_pkg(id: ~str,
|
||||
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
|
||||
}).last())
|
||||
});
|
||||
|
||||
result::Ok(copy *possibs.last())
|
||||
}
|
||||
|
||||
pub fn add_pkg(pkg: &Package) -> bool {
|
||||
|
@ -346,7 +346,7 @@ pub impl BigUint {
|
||||
}
|
||||
|
||||
let mut shift = 0;
|
||||
let mut n = other.data.last();
|
||||
let mut n = *other.data.last();
|
||||
while n < (1 << BigDigit::bits - 2) {
|
||||
n <<= 1;
|
||||
shift += 1;
|
||||
@ -384,7 +384,7 @@ pub impl BigUint {
|
||||
}
|
||||
|
||||
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 carry = 0;
|
||||
for vec::rev_each(an) |elt| {
|
||||
|
@ -759,7 +759,7 @@ pub fn Decoder(json: Json) -> Decoder {
|
||||
priv impl Decoder {
|
||||
fn peek(&self) -> &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 {
|
||||
|
@ -197,7 +197,7 @@ mod tests {
|
||||
let mut sorted = merge_sort(data, le);
|
||||
let mut heap = from_vec(data);
|
||||
while !heap.is_empty() {
|
||||
assert *heap.top() == sorted.last();
|
||||
assert heap.top() == sorted.last();
|
||||
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 {
|
||||
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> {
|
||||
|
||||
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)
|
||||
|
@ -167,7 +167,7 @@ pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan {
|
||||
while r.cur.idx >= r.cur.readme.len() {
|
||||
/* done with this set; pop or repeat? */
|
||||
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 {
|
||||
None => {
|
||||
|
@ -93,7 +93,7 @@ fn recurse_or_fail(depth: int, st: Option<State>) {
|
||||
fn_box: || @Cons((), fn_box()),
|
||||
tuple: (@Cons((), st.tuple.first()),
|
||||
~Cons((), @*st.tuple.second())),
|
||||
vec: st.vec + ~[@Cons((), st.vec.last())],
|
||||
vec: st.vec + ~[@Cons((), *st.vec.last())],
|
||||
res: r(@Cons((), st.res._l))
|
||||
}
|
||||
}
|
||||
|
@ -35,5 +35,5 @@ pub fn main() {
|
||||
let ps = vec::zip(chars, ints);
|
||||
|
||||
assert (ps.head() == &('a', 1u));
|
||||
assert (ps.last() == (j as char, 10u));
|
||||
assert (ps.last() == &(j as char, 10u));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user