From 5d54defce478c0ffc01ab1199069623624ad2788 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 17 Mar 2012 18:02:45 -0700 Subject: [PATCH] core: Add extension methods for vec --- src/libcore/core.rs | 5 +- src/libcore/vec.rs | 177 ++++++++++++++++++++++++++++++- src/test/run-pass/static-impl.rs | 12 +-- 3 files changed, 181 insertions(+), 13 deletions(-) diff --git a/src/libcore/core.rs b/src/libcore/core.rs index cf06ad1b158..92310166426 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -5,10 +5,11 @@ import option::{some, none}; import option = option::option; import path = path::path; -import vec::vec_len; import str::extensions; +import vec::extensions; import option::extensions; -export path, option, some, none, vec_len, unreachable; + +export path, option, some, none, unreachable; export extensions; // Export the log levels as global constants. Higher levels mean diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 5b18610c61b..ded7ca92ba3 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -71,9 +71,9 @@ export permute; export windowed; export as_buf; export as_mut_buf; -export vec_len; export unsafe; export u8; +export extensions; #[abi = "cdecl"] native mod rustrt { @@ -954,13 +954,180 @@ fn as_mut_buf(v: [mut E], f: fn(*mut E) -> T) -> T unsafe { let buf = unsafe::to_ptr(v) as *mut E; f(buf) } -#[doc = "An extension implementation providing a `len` method"] -impl vec_len for [const T] { - #[doc = "Return the length of the vector"] - #[inline(always)] +#[doc = "Extension methods for vectors"] +impl extensions for [const T] { + #[doc = " + Return true if a vector contains an element with the given value + "] + #[inline] + fn contains(x: T) -> bool { contains(self, x) } + #[doc = "Returns the number of elements that are equal to a given value"] + #[inline] + fn count(x: T) -> uint { count(self, x) } + #[doc = "Reduce a vector from left to right"] + #[inline] + fn foldl(z: U, p: fn(U, T) -> U) -> U { foldl(z, self, p) } + #[doc = "Reduce a vector from right to left"] + #[inline] + fn foldr(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) } + #[doc = "Returns true if a vector contains no elements"] + #[inline] + fn is_empty() -> bool { is_empty(self) } + #[doc = "Returns true if a vector contains some elements"] + #[inline] + fn is_not_empty() -> bool { is_not_empty(self) } + #[doc = " + Iterates over a vector + + Iterates over vector `v` and, for each element, calls function `f` with + the element's value. + "] + #[inline] + fn iter(f: fn(T)) { iter(self, f) } + #[doc = " + Iterates over a vector's elements and indexes + + Iterates over vector `v` and, for each element, calls function `f` with + the element's value and index. + "] + #[inline] + fn iteri(f: fn(uint, T)) { iteri(self, f) } + #[doc = "Returns the length of a vector"] + #[inline] fn len() -> uint { len(self) } + #[doc = " + Find the first index matching some predicate + + Apply function `f` to each element of `v`. When function `f` returns true + then an option containing the index is returned. If `f` matches no + elements then none is returned. + "] + #[inline] + fn position(f: fn(T) -> bool) -> option { position(self, f) } + #[doc = "Find the first index containing a matching value"] + #[inline] + fn position_elem(x: T) -> option { position_elem(self, x) } + #[doc = " + Iterates over a vector in reverse + + Iterates over vector `v` and, for each element, calls function `f` with + the element's value. + "] + #[inline] + fn riter(f: fn(T)) { riter(self, f) } + #[doc =" + Iterates over a vector's elements and indexes in reverse + + Iterates over vector `v` and, for each element, calls function `f` with + the element's value and index. + "] + #[inline] + fn riteri(f: fn(uint, T)) { riteri(self, f) } + #[doc = " + Find the last index matching some predicate + + Apply function `f` to each element of `v` in reverse order. When function + `f` returns true then an option containing the index is returned. If `f` + matches no elements then none is returned. + "] + #[inline] + fn rposition(f: fn(T) -> bool) -> option { rposition(self, f) } + #[doc = "Find the last index containing a matching value"] + #[inline] + fn rposition_elem(x: T) -> option { rposition_elem(self, x) } } +#[doc = "Extension methods for vectors"] +impl extensions for [const T] { + #[doc = " + Search for the first element that matches a given predicate + + Apply function `f` to each element of `v`, starting from the first. + When function `f` returns true then an option containing the element + is returned. If `f` matches no elements then none is returned. + "] + #[inline] + fn find(f: fn(T) -> bool) -> option { find(self, f) } + #[doc = "Returns the first element of a vector"] + #[inline] + fn head() -> T { head(self) } + #[doc = "Returns all but the last elemnt of a vector"] + #[inline] + fn init() -> [T] { init(self) } + #[doc = " + Returns the last element of a `v`, failing if the vector is empty. + "] + #[inline] + fn last() -> T { last(self) } + #[doc = " + Search for the last element that matches a given predicate + + Apply function `f` to each element of `v` in reverse order. When function + `f` returns true then an option containing the element is returned. If `f` + matches no elements then none is returned. + "] + #[inline] + fn rfind(f: fn(T) -> bool) -> option { rfind(self, f) } + #[doc = "Returns a copy of the elements from [`start`..`end`) from `v`."] + #[inline] + fn slice(start: uint, end: uint) -> [T] { slice(self, start, end) } + #[doc = "Returns all but the first element of a vector"] + #[inline] + fn tail() -> [T] { tail(self) } +} + +#[doc = "Extension methods for vectors"] +impl extensions for [T] { + #[doc = " + Return true if a predicate matches all elements + + If the vector contains no elements then true is returned. + "] + #[inline] + fn all(f: fn(T) -> bool) -> bool { all(self, f) } + #[doc = " + Return true if a predicate matches any elements + + If the vector contains no elements then false is returned. + "] + #[inline] + fn any(f: fn(T) -> bool) -> bool { any(self, f) } + #[doc = " + Apply a function to each element of a vector and return the results + + If function `f` returns `none` then that element is excluded from + the resulting vector. + "] + #[inline] + fn filter_map(f: fn(T) -> option) -> [U] { + filter_map(self, f) + } + #[doc = " + Apply a function eo each element of a vector and return a concatenation + of each result vector + "] + #[inline] + fn flat_map(f: fn(T) -> [U]) -> [U] { flat_map(self, f) } + #[doc = " + Apply a function to each element of a vector and return the results + "] + #[inline] + fn map(f: fn(T) -> U) -> [U] { map(self, f) } +} + +#[doc = "Extension methods for vectors"] +impl extensions for [T] { + #[doc = " + Construct a new vector from the elements of a vector for which some + predicate holds. + + Apply function `f` to each element of `v` and return a vector containing + only those elements for which `f` returned true. + "] + #[inline] + fn filter(f: fn(T) -> bool) -> [T] { filter(self, f) } + } + #[doc = "Unsafe operations"] mod unsafe { // FIXME: This should have crate visibility diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index c7eb7ae4a34..fe184b874df 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -18,9 +18,9 @@ impl util for uint { } impl util for [T] { - fn length() -> uint { vec::len(self) } - fn iter(f: fn(T)) { for x in self { f(x); } } - fn map(f: fn(T) -> U) -> [U] { + fn length_() -> uint { vec::len(self) } + fn iter_(f: fn(T)) { for x in self { f(x); } } + fn map_(f: fn(T) -> U) -> [U] { let mut r = []; for elt in self { r += [f(elt)]; } r @@ -33,9 +33,9 @@ fn main() { assert 10u.plus() == 30; assert "hi".plus() == 200; - assert [1].length().str() == "1"; - assert [3, 4].map({|a| a + 4})[0] == 7; - assert [3, 4].map::({|a| a as uint + 4u})[0] == 7u; + assert [1].length_().str() == "1"; + assert [3, 4].map_({|a| a + 4})[0] == 7; + assert [3, 4].map_::({|a| a as uint + 4u})[0] == 7u; let mut x = 0u; 10u.times {|_n| x += 2u;} assert x == 20u;