diff --git a/doc/tutorial.md b/doc/tutorial.md index cc87376d25b..c7b94c8e155 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -908,14 +908,13 @@ for the parameter list, as in `{|| ...}`. Partial application is done using the `bind` keyword in Rust. ~~~~ -let daynum = bind vec::position_elem(["mo", "tu", "we", "th", - "fr", "sa", "su"], _); +let findx = bind str::find_char(_, 'x'); ~~~~ Binding a function produces a boxed closure (`fn@` type) in which some of the arguments to the bound function have already been provided. -`daynum` will be a function taking a single string argument, and -returning the day of the week that string corresponds to (if any). +`findx` will be a function taking a single string argument, and +returning the position where the letter `x` occurs. ## Iteration diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 13a54ddfcb6..6aa24b9b651 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -45,7 +45,7 @@ export swappable; export dvec, dvec_iter; // NDM seems to be necessary for resolve to work -export vec_iter, option_iter; +export option_iter; // FIXME: This creates some APIs that I do not want to commit to. It is // currently exported for the uv code in std, but when that code moves into @@ -146,11 +146,6 @@ mod f64; mod str; mod ptr; mod vec; -#[path="iter-trait"] -mod vec_iter { - #[path = "vec.rs"] - mod inst; -} mod bool; mod tuple; diff --git a/src/libcore/core.rs b/src/libcore/core.rs index 4b07e2b29b7..2522a98609c 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -7,7 +7,6 @@ import option = option::option; import path = path::path; import str::extensions; import vec::extensions; -import vec_iter::extensions; import option::extensions; import option_iter::extensions; import ptr::extensions; diff --git a/src/libcore/io.rs b/src/libcore/io.rs index e210ab0944c..937aa5976ef 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -331,7 +331,7 @@ impl of writer for {base: T, cleanup: C} { impl of writer for *libc::FILE { fn write(v: [const u8]/&) unsafe { - vec::unpack_slice(v) {|vbuf, len| + vec::unpack_const_slice(v) {|vbuf, len| let nout = libc::fwrite(vbuf as *c_void, len, 1u, self); if nout < 1 as size_t { #error("error writing buffer"); @@ -359,9 +359,9 @@ fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer { impl of writer for fd_t { fn write(v: [const u8]/&) unsafe { let mut count = 0u; - vec::unpack_slice(v) {|vbuf, len| + vec::unpack_const_slice(v) {|vbuf, len| while count < len { - let vb = ptr::offset(vbuf, count) as *c_void; + let vb = ptr::const_offset(vbuf, count) as *c_void; let nout = libc::write(self, vb, len); if nout < 0 as ssize_t { #error("error writing buffer"); diff --git a/src/libcore/iter-trait/vec.rs b/src/libcore/iter-trait/vec.rs deleted file mode 100644 index 62f9458303b..00000000000 --- a/src/libcore/iter-trait/vec.rs +++ /dev/null @@ -1,9 +0,0 @@ -type IMPL_T = [const A]; - -fn EACH(self: IMPL_T, f: fn(A) -> bool) { - vec::each(self, f) -} - -fn SIZE_HINT(self: IMPL_T) -> option { - some(vec::len(self)) -} diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index eac3ed27934..e83c35f5ed8 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -3,6 +3,7 @@ export addr_of; export mut_addr_of; export offset; +export const_offset; export mut_offset; export null; export is_null; @@ -45,6 +46,12 @@ fn offset(ptr: *T, count: uint) -> *T unsafe { (ptr as uint + count * sys::size_of::()) as *T } +#[doc = "Calculate the offset from a const pointer"] +#[inline(always)] +fn const_offset(ptr: *const T, count: uint) -> *const T unsafe { + (ptr as uint + count * sys::size_of::()) as *T +} + #[doc = "Calculate the offset from a mut pointer"] #[inline(always)] fn mut_offset(ptr: *mut T, count: uint) -> *mut T { diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index d818a9d7077..8613f378d7a 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -75,6 +75,7 @@ export windowed; export as_buf; export as_mut_buf; export unpack_slice; +export unpack_const_slice; export unsafe; export u8; export extensions; @@ -93,16 +94,18 @@ native mod rustrt { type init_op = fn(uint) -> T; #[doc = "Returns true if a vector contains no elements"] -pure fn is_empty(v: [const T]) -> bool { - len(v) == 0u +pure fn is_empty(v: [const T]/&) -> bool { + unpack_const_slice(v) {|_p, len| len == 0u} } #[doc = "Returns true if a vector contains some elements"] -pure fn is_not_empty(v: [const T]) -> bool { ret !is_empty(v); } +pure fn is_not_empty(v: [const T]/&) -> bool { + unpack_const_slice(v) {|_p, len| len > 0u} +} #[doc = "Returns true if two vectors have the same length"] -pure fn same_length(xs: [const T], ys: [const U]) -> bool { - vec::len(xs) == vec::len(ys) +pure fn same_length(xs: [const T]/&, ys: [const U]/&) -> bool { + len(xs) == len(ys) } #[doc = " @@ -154,7 +157,7 @@ pure fn capacity(&&v: [const T]) -> uint unsafe { #[doc = "Returns the length of a vector"] #[inline(always)] pure fn len(&&v: [const T]/&) -> uint unsafe { - unpack_slice(v) {|_p, len| len} + unpack_const_slice(v) {|_p, len| len} } #[doc = " @@ -202,43 +205,44 @@ fn from_mut(+v: [mut T]) -> [T] unsafe { // Accessors #[doc = "Returns the first element of a vector"] -pure fn head(v: [const T]) -> T { v[0] } +pure fn head(v: [const T]/&) -> T { v[0] } -#[doc = "Returns all but the first element of a vector"] -fn tail(v: [const T]) -> [T] { +#[doc = "Returns a vector containing all but the first element of a slice"] +fn tail(v: [const T]/&) -> [T] { ret slice(v, 1u, len(v)); } -#[doc = "Returns all but the first `n` elements of a vector"] -fn tailn(v: [const T], n: uint) -> [T] { +#[doc = "Returns a vector containing all but the first `n` \ + elements of a slice"] +fn tailn(v: [const T]/&, n: uint) -> [T] { slice(v, n, len(v)) } -#[doc = "Returns all but the last elemnt of a vector"] -fn init(v: [const T]) -> [T] { +#[doc = "Returns a vector containing all but the last element of a slice"] +fn init(v: [const T]/&) -> [T] { assert len(v) != 0u; slice(v, 0u, len(v) - 1u) } #[doc = " -Returns the last element of a `v`, failing if the vector is empty. +Returns the last element of the slice `v`, failing if the slice is empty. "] -pure fn last(v: [const T]) -> T { +pure fn last(v: [const T]/&) -> T { if len(v) == 0u { fail "last_unsafe: empty vector" } v[len(v) - 1u] } #[doc = " -Returns some(x) where `x` is the last element of a vector `v`, -or none if the vector is empty. +Returns `some(x)` where `x` is the last element of the slice `v`, +or `none` if the vector is empty. "] -pure fn last_opt(v: [const T]) -> option { - if len(v) == 0u { ret none; } +pure fn last_opt(v: [const T]/&) -> option { + if len(v) == 0u { ret none; } some(v[len(v) - 1u]) } #[doc = "Returns a copy of the elements from [`start`..`end`) from `v`."] -pure fn slice(v: [const T], start: uint, end: uint) -> [T] { +pure fn slice(v: [const T]/&, start: uint, end: uint) -> [T] { assert (start <= end); assert (end <= len(v)); let mut result = []; @@ -249,7 +253,7 @@ pure fn slice(v: [const T], start: uint, end: uint) -> [T] { } #[doc = "Return a slice that points into another slice."] -pure fn view(v: [const T]/&, start: uint, end: uint) -> [T]/&a { +pure fn view(v: [T]/&, start: uint, end: uint) -> [T]/&a { assert (start <= end); assert (end <= len(v)); unpack_slice(v) {|p, _len| @@ -263,7 +267,7 @@ pure fn view(v: [const T]/&, start: uint, end: uint) -> [T]/&a { #[doc = " Split the vector `v` by applying each element against the predicate `f`. "] -fn split(v: [const T], f: fn(T) -> bool) -> [[T]] { +fn split(v: [T], f: fn(T) -> bool) -> [[T]] { let ln = len(v); if (ln == 0u) { ret [] } @@ -286,7 +290,7 @@ fn split(v: [const T], f: fn(T) -> bool) -> [[T]] { Split the vector `v` by applying each element against the predicate `f` up to `n` times. "] -fn splitn(v: [const T], n: uint, f: fn(T) -> bool) -> [[T]] { +fn splitn(v: [T], n: uint, f: fn(T) -> bool) -> [[T]] { let ln = len(v); if (ln == 0u) { ret [] } @@ -312,7 +316,7 @@ fn splitn(v: [const T], n: uint, f: fn(T) -> bool) -> [[T]] { Reverse split the vector `v` by applying each element against the predicate `f`. "] -fn rsplit(v: [const T], f: fn(T) -> bool) -> [[T]] { +fn rsplit(v: [T], f: fn(T) -> bool) -> [[T]] { let ln = len(v); if (ln == 0u) { ret [] } @@ -335,7 +339,7 @@ fn rsplit(v: [const T], f: fn(T) -> bool) -> [[T]] { Reverse split the vector `v` by applying each element against the predicate `f` up to `n times. "] -fn rsplitn(v: [const T], n: uint, f: fn(T) -> bool) -> [[T]] { +fn rsplitn(v: [T], n: uint, f: fn(T) -> bool) -> [[T]] { let ln = len(v); if (ln == 0u) { ret [] } @@ -447,7 +451,7 @@ fn grow_set(&v: [mut T], index: uint, initval: T, val: T) { #[doc = " Apply a function to each element of a vector and return the results "] -pure fn map(v: [const T]/&, f: fn(T) -> U) -> [U] { +pure fn map(v: [T]/&, f: fn(T) -> U) -> [U] { let mut result = []; unchecked{reserve(result, len(v));} for each(v) {|elem| result += [f(elem)]; } @@ -457,7 +461,7 @@ pure fn map(v: [const T]/&, f: fn(T) -> U) -> [U] { #[doc = " Apply a function to each element of a vector and return the results "] -pure fn mapi(v: [const T]/&, f: fn(uint, T) -> U) -> [U] { +pure fn mapi(v: [T]/&, f: fn(uint, T) -> U) -> [U] { let mut result = []; unchecked{reserve(result, len(v));} for eachi(v) {|i, elem| result += [f(i, elem)]; } @@ -468,7 +472,7 @@ pure fn mapi(v: [const T]/&, f: fn(uint, T) -> U) -> [U] { Apply a function to each element of a vector and return a concatenation of each result vector "] -pure fn flat_map(v: [T], f: fn(T) -> [U]) -> [U] { +pure fn flat_map(v: [T]/&, f: fn(T) -> [U]) -> [U] { let mut result = []; for each(v) {|elem| result += f(elem); } ret result; @@ -477,7 +481,7 @@ pure fn flat_map(v: [T], f: fn(T) -> [U]) -> [U] { #[doc = " Apply a function to each pair of elements and return the results "] -pure fn map2(v0: [const T], v1: [const U], +pure fn map2(v0: [T]/&, v1: [U]/&, f: fn(T, U) -> V) -> [V] { let v0_len = len(v0); if v0_len != len(v1) { fail; } @@ -493,7 +497,7 @@ 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. "] -pure fn filter_map(v: [T], f: fn(T) -> option) +pure fn filter_map(v: [T]/&, f: fn(T) -> option) -> [U] { let mut result = []; for each(v) {|elem| @@ -512,7 +516,7 @@ holds. Apply function `f` to each element of `v` and return a vector containing only those elements for which `f` returned true. "] -pure fn filter(v: [const T], f: fn(T) -> bool) -> [T] { +pure fn filter(v: [T]/&, f: fn(T) -> bool) -> [T] { let mut result = []; for each(v) {|elem| if f(elem) { result += [elem]; } @@ -525,7 +529,7 @@ Concatenate a vector of vectors. Flattens a vector of vectors of T into a single vector of T. "] -pure fn concat(v: [const [const T]]) -> [T] { +pure fn concat(v: [[T]]/&) -> [T] { let mut r = []; for each(v) {|inner| r += inner; } ret r; @@ -534,7 +538,7 @@ pure fn concat(v: [const [const T]]) -> [T] { #[doc = " Concatenate a vector of vectors, placing a given separator between each "] -pure fn connect(v: [const [const T]], sep: T) -> [T] { +pure fn connect(v: [[T]]/&, sep: T) -> [T] { let mut r: [T] = []; let mut first = true; for each(v) {|inner| @@ -545,7 +549,7 @@ pure fn connect(v: [const [const T]], sep: T) -> [T] { } #[doc = "Reduce a vector from left to right"] -pure fn foldl(z: T, v: [const U], p: fn(T, U) -> T) -> T { +pure fn foldl(z: T, v: [U]/&, p: fn(T, U) -> T) -> T { let mut accum = z; iter(v) { |elt| accum = p(accum, elt); @@ -554,7 +558,7 @@ pure fn foldl(z: T, v: [const U], p: fn(T, U) -> T) -> T { } #[doc = "Reduce a vector from right to left"] -pure fn foldr(v: [const T]/&, z: U, p: fn(T, U) -> U) -> U { +pure fn foldr(v: [T]/&, z: U, p: fn(T, U) -> U) -> U { let mut accum = z; riter(v) { |elt| accum = p(elt, accum); @@ -567,7 +571,7 @@ Return true if a predicate matches any elements If the vector contains no elements then false is returned. "] -pure fn any(v: [const T]/&, f: fn(T) -> bool) -> bool { +pure fn any(v: [T]/&, f: fn(T) -> bool) -> bool { for each(v) {|elem| if f(elem) { ret true; } } ret false; } @@ -577,7 +581,7 @@ Return true if a predicate matches any elements in both vectors. If the vectors contains no elements then false is returned. "] -pure fn any2(v0: [const T]/&, v1: [const U]/&, +pure fn any2(v0: [T]/&, v1: [U]/&, f: fn(T, U) -> bool) -> bool { let v0_len = len(v0); let v1_len = len(v1); @@ -594,7 +598,7 @@ Return true if a predicate matches all elements If the vector contains no elements then true is returned. "] -pure fn all(v: [const T]/&, f: fn(T) -> bool) -> bool { +pure fn all(v: [T]/&, f: fn(T) -> bool) -> bool { for each(v) {|elem| if !f(elem) { ret false; } } ret true; } @@ -604,7 +608,7 @@ Return true if a predicate matches all elements If the vector contains no elements then true is returned. "] -pure fn alli(v: [const T]/&, f: fn(uint, T) -> bool) -> bool { +pure fn alli(v: [T]/&, f: fn(uint, T) -> bool) -> bool { for eachi(v) {|i, elem| if !f(i, elem) { ret false; } } ret true; } @@ -614,7 +618,7 @@ Return true if a predicate matches all elements in both vectors. If the vectors are not the same size then false is returned. "] -pure fn all2(v0: [const T]/&, v1: [const U]/&, +pure fn all2(v0: [T]/&, v1: [U]/&, f: fn(T, U) -> bool) -> bool { let v0_len = len(v0); if v0_len != len(v1) { ret false; } @@ -624,13 +628,13 @@ pure fn all2(v0: [const T]/&, v1: [const U]/&, } #[doc = "Return true if a vector contains an element with the given value"] -pure fn contains(v: [const T], x: T) -> bool { +pure fn contains(v: [T]/&, x: T) -> bool { for each(v) {|elt| if x == elt { ret true; } } ret false; } #[doc = "Returns the number of elements that are equal to a given value"] -pure fn count(v: [const T], x: T) -> uint { +pure fn count(v: [T]/&, x: T) -> uint { let mut cnt = 0u; for each(v) {|elt| if x == elt { cnt += 1u; } } ret cnt; @@ -643,7 +647,7 @@ 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. "] -pure fn find(v: [const T], f: fn(T) -> bool) -> option { +pure fn find(v: [T]/&, f: fn(T) -> bool) -> option { find_between(v, 0u, len(v), f) } @@ -654,7 +658,7 @@ Apply function `f` to each element of `v` within the range [`start`, `end`). When function `f` returns true then an option containing the element is returned. If `f` matches no elements then none is returned. "] -pure fn find_between(v: [const T], start: uint, end: uint, +pure fn find_between(v: [T]/&, start: uint, end: uint, f: fn(T) -> bool) -> option { option::map(position_between(v, start, end, f)) { |i| v[i] } } @@ -666,7 +670,7 @@ 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. "] -pure fn rfind(v: [const T], f: fn(T) -> bool) -> option { +pure fn rfind(v: [T]/&, f: fn(T) -> bool) -> option { rfind_between(v, 0u, len(v), f) } @@ -677,13 +681,13 @@ Apply function `f` to each element of `v` in reverse order within the range [`start`, `end`). When function `f` returns true then an option containing the element is returned. If `f` matches no elements then none is returned. "] -pure fn rfind_between(v: [const T], start: uint, end: uint, +pure fn rfind_between(v: [T]/&, start: uint, end: uint, f: fn(T) -> bool) -> option { option::map(rposition_between(v, start, end, f)) { |i| v[i] } } #[doc = "Find the first index containing a matching value"] -pure fn position_elem(v: [const T], x: T) -> option { +pure fn position_elem(v: [T]/&, x: T) -> option { position(v) { |y| x == y } } @@ -694,7 +698,7 @@ 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. "] -pure fn position(v: [const T], f: fn(T) -> bool) -> option { +pure fn position(v: [T]/&, f: fn(T) -> bool) -> option { position_between(v, 0u, len(v), f) } @@ -705,7 +709,7 @@ Apply function `f` to each element of `v` between the range [`start`, `end`). When function `f` returns true then an option containing the index is returned. If `f` matches no elements then none is returned. "] -pure fn position_between(v: [const T], start: uint, end: uint, +pure fn position_between(v: [T]/&, start: uint, end: uint, f: fn(T) -> bool) -> option { assert start <= end; assert end <= len(v); @@ -715,7 +719,7 @@ pure fn position_between(v: [const T], start: uint, end: uint, } #[doc = "Find the last index containing a matching value"] -pure fn rposition_elem(v: [const T], x: T) -> option { +pure fn rposition_elem(v: [T]/&, x: T) -> option { rposition(v) { |y| x == y } } @@ -726,7 +730,7 @@ 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. "] -pure fn rposition(v: [const T], f: fn(T) -> bool) -> option { +pure fn rposition(v: [T]/&, f: fn(T) -> bool) -> option { rposition_between(v, 0u, len(v), f) } @@ -737,7 +741,7 @@ Apply function `f` to each element of `v` in reverse order between the range [`start`, `end`). When function `f` returns true then an option containing the index is returned. If `f` matches no elements then none is returned. "] -pure fn rposition_between(v: [const T], start: uint, end: uint, +pure fn rposition_between(v: [T]/&, start: uint, end: uint, f: fn(T) -> bool) -> option { assert start <= end; assert end <= len(v); @@ -761,7 +765,7 @@ vector contains the first element of the i-th tuple of the input vector, and the i-th element of the second vector contains the second element of the i-th tuple of the input vector. "] -pure fn unzip(v: [const (T, U)]) -> ([T], [U]) { +pure fn unzip(v: [(T, U)]/&) -> ([T], [U]) { let mut as = [], bs = []; for each(v) {|p| let (a, b) = p; as += [a]; bs += [b]; } ret (as, bs); @@ -804,7 +808,7 @@ fn reverse(v: [mut T]) { #[doc = "Returns a vector with the order of elements reversed"] -fn reversed(v: [const T]) -> [T] { +fn reversed(v: [const T]/&) -> [T] { let mut rs: [T] = []; let mut i = len::(v); if i == 0u { ret rs; } else { i -= 1u; } @@ -814,36 +818,38 @@ fn reversed(v: [const T]) -> [T] { } #[doc = " -Iterates over a vector +Iterates over a slice -Iterates over vector `v` and, for each element, calls function `f` with the +Iterates over slice `v` and, for each element, calls function `f` with the element's value. "] #[inline(always)] -pure fn iter(v: [const T], f: fn(T)) { +pure fn iter(v: [T]/&, f: fn(T)) { iter_between(v, 0u, vec::len(v), f) } /* Function: iter_between -Iterates over a vector +Iterates over a slice -Iterates over vector `v` and, for each element, calls function `f` with the +Iterates over slice `v` and, for each element, calls function `f` with the element's value. */ #[inline(always)] -pure fn iter_between(v: [const T], start: uint, end: uint, f: fn(T)) { - assert start <= end; - assert end <= vec::len(v); - unsafe { - let mut n = end; - let mut p = ptr::offset(unsafe::to_ptr(v), start); - while n > start { - f(*p); - p = ptr::offset(p, 1u); - n -= 1u; +pure fn iter_between(v: [T]/&, start: uint, end: uint, f: fn(T)) { + unpack_slice(v) { |base_ptr, len| + assert start <= end; + assert end <= len; + unsafe { + let mut n = end; + let mut p = ptr::offset(base_ptr, start); + while n > start { + f(*p); + p = ptr::offset(p, 1u); + n -= 1u; + } } } } @@ -854,7 +860,7 @@ Iterates over a vector, with option to break Return true to continue, false to break. "] #[inline(always)] -pure fn each(v: [const T]/&, f: fn(T) -> bool) unsafe { +pure fn each(v: [T]/&, f: fn(T) -> bool) unsafe { vec::unpack_slice(v) {|p, n| let mut n = n; let mut p = p; @@ -872,7 +878,7 @@ Iterates over a vector's elements and indices Return true to continue, false to break. "] #[inline(always)] -pure fn eachi(v: [const T]/&, f: fn(uint, T) -> bool) unsafe { +pure fn eachi(v: [T]/&, f: fn(uint, T) -> bool) unsafe { vec::unpack_slice(v) {|p, n| let mut i = 0u; let mut p = p; @@ -892,7 +898,7 @@ Iterates over two vectors simultaneously Both vectors must have the same length "] #[inline] -fn iter2(v1: [const U], v2: [const T], f: fn(U, T)) { +fn iter2(v1: [U]/&, v2: [T]/&, f: fn(U, T)) { assert len(v1) == len(v2); for uint::range(0u, len(v1)) {|i| f(v1[i], v2[i]) @@ -906,7 +912,7 @@ Iterates over vector `v` and, for each element, calls function `f` with the element's value and index. "] #[inline(always)] -pure fn iteri(v: [const T], f: fn(uint, T)) { +pure fn iteri(v: [T]/&, f: fn(uint, T)) { let mut i = 0u; let l = len(v); while i < l { f(i, v[i]); i += 1u; } @@ -918,7 +924,7 @@ Iterates over a vector in reverse Iterates over vector `v` and, for each element, calls function `f` with the element's value. "] -pure fn riter(v: [const T]/&, f: fn(T)) { +pure fn riter(v: [T]/&, f: fn(T)) { riteri(v) { |_i, v| f(v) } } @@ -928,7 +934,7 @@ 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. "] -pure fn riteri(v: [const T]/&, f: fn(uint, T)) { +pure fn riteri(v: [T]/&, f: fn(uint, T)) { let mut i = len(v); while 0u < i { i -= 1u; @@ -946,7 +952,7 @@ lexicographically sorted). The total number of permutations produced is `len(v)!`. If `v` contains repeated elements, then some permutations are repeated. "] -pure fn permute(v: [T], put: fn([T])) { +pure fn permute(v: [T]/&, put: fn([T])) { let ln = len(v); if ln == 0u { put([]); @@ -961,7 +967,7 @@ pure fn permute(v: [T], put: fn([T])) { } } -pure fn windowed(nn: uint, xx: [const TT]) -> [[TT]] { +pure fn windowed(nn: uint, xx: [TT]/&) -> [[TT]] { let mut ww = []; assert 1u <= nn; vec::iteri (xx, {|ii, _x| @@ -979,35 +985,86 @@ Work with the buffer of a vector. Allows for unsafe manipulation of vector contents, which is useful for native interop. "] -fn as_buf(v: [const E], f: fn(*E) -> T) -> T unsafe { - let buf = unsafe::to_ptr(v); f(buf) +fn as_buf(v: [E]/&, f: fn(*E) -> T) -> T unsafe { + unpack_slice(v) { |buf, _len| f(buf) } } -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) +fn as_mut_buf(v: [mut E]/&, f: fn(*mut E) -> T) -> T unsafe { + unpack_mut_slice(v) { |buf, _len| f(buf) } } #[doc = " Work with the buffer and length of a slice. "] #[inline(always)] -pure fn unpack_slice(s: [const T]/&, f: fn(*T, uint) -> U) -> U unsafe { +pure fn unpack_slice(s: [T]/&, + f: fn(*T, uint) -> U) -> U unsafe { let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s)); let (buf,len) = *v; f(buf, len / sys::size_of::()) } +#[doc = " +Work with the buffer and length of a slice. +"] +#[inline(always)] +pure fn unpack_const_slice(s: [const T]/&, + f: fn(*const T, uint) -> U) -> U unsafe { + let v : *(*const T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s)); + let (buf,len) = *v; + f(buf, len / sys::size_of::()) +} + +#[doc = " +Work with the buffer and length of a slice. +"] +#[inline(always)] +pure fn unpack_mut_slice(s: [mut T]/&, + f: fn(*mut T, uint) -> U) -> U unsafe { + let v : *(*const T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s)); + let (buf,len) = *v; + f(buf, len / sys::size_of::()) +} + #[doc = "Extension methods for vectors"] -impl extensions for [const T] { - #[doc = "Reduce a vector from right to left"] - #[inline] - fn foldr(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) } +impl extensions/& for [const T]/& { #[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 = "Returns the length of a vector"] + #[inline] + pure fn len() -> uint { len(self) } +} + +#[doc = "Extension methods for vectors"] +impl extensions/& for [const T]/& { + #[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 = "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 = "Reduce a vector from right to left"] + #[inline] + fn foldr(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) } #[doc = " Iterates over a vector @@ -1024,9 +1081,6 @@ impl extensions for [const T] { "] #[inline] fn iteri(f: fn(uint, T)) { iteri(self, f) } - #[doc = "Returns the length of a vector"] - #[inline] - pure fn len() -> uint { len(self) } #[doc = " Find the first index matching some predicate @@ -1067,58 +1121,6 @@ impl extensions for [const T] { #[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 = " - 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 = " - 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 = " Apply a function to each element of a vector and return the results "] @@ -1155,6 +1157,37 @@ impl extensions for [T] { } } +#[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 = " + 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 = " + 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 = "Unsafe operations"] mod unsafe { // FIXME: This should have crate visibility (#1893 blocks that) @@ -1277,6 +1310,40 @@ mod u8 { } } +// ___________________________________________________________________________ +// ITERATION TRAIT METHODS +// +// This cannot be used with iter-trait.rs because of the region pointer +// required in the slice. +impl extensions/& of iter::base_iter for [A]/& { + fn each(blk: fn(A) -> bool) { each(self, blk) } + fn size_hint() -> option { some(len(self)) } + fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) } + fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) } + fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) } + fn foldl(+b0: B, blk: fn(B, A) -> B) -> B { + iter::foldl(self, b0, blk) + } + fn contains(x: A) -> bool { iter::contains(self, x) } + fn count(x: A) -> uint { iter::count(self, x) } +} +impl extensions/& for [A]/& { + fn filter_to_vec(pred: fn(A) -> bool) -> [A] { + iter::filter_to_vec(self, pred) + } + fn map_to_vec(op: fn(A) -> B) -> [B] { iter::map_to_vec(self, op) } + fn to_vec() -> [A] { iter::to_vec(self) } + + // FIXME--bug in resolve prevents this from working + // fn flat_map_to_vec>(op: fn(A) -> IB) -> [B] { + // iter::flat_map_to_vec(self, op) + // } + + fn min() -> A { iter::min(self) } + fn max() -> A { iter::max(self) } +} +// ___________________________________________________________________________ + #[cfg(test)] mod tests { diff --git a/src/libstd/list.rs b/src/libstd/list.rs index cc582d370bf..5a468df4c88 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -10,7 +10,7 @@ enum list { } #[doc = "Create a list from a vector"] -fn from_vec(v: [const T]) -> @list { +fn from_vec(v: [T]) -> @list { vec::foldr(v, @nil::, { |h, t| @cons(h, t) }) } @@ -167,19 +167,6 @@ mod tests { assert (empty == @list::nil::); } - #[test] - fn test_from_vec_mut() { - let l = from_vec([mut 0, 1, 2]); - - assert (head(l) == 0); - - let tail_l = tail(l); - assert (head(tail_l) == 1); - - let tail_tail_l = tail(tail_l); - assert (head(tail_tail_l) == 2); - } - #[test] fn test_foldl() { fn add(&&a: uint, &&b: int) -> uint { ret a + (b as uint); } diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 5db344713a7..d12a7e71a63 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -20,7 +20,7 @@ This is used to build most of the other parallel vector functions, like map or alli."] fn map_slices( xs: [A], - f: fn() -> fn~(uint, [const A]/&) -> B) + f: fn() -> fn~(uint, [A]/&) -> B) -> [B] { let len = xs.len(); @@ -48,7 +48,7 @@ fn map_slices( let slice = (ptr::offset(p, base), len * sys::size_of::()); log(info, #fmt("pre-slice: %?", (base, slice))); - let slice : [const A]/& = + let slice : [A]/& = unsafe::reinterpret_cast(slice); log(info, #fmt("slice: %?", (base, vec::len(slice), end - base))); @@ -75,7 +75,7 @@ fn map_slices( #[doc="A parallel version of map."] fn map(xs: [A], f: fn~(A) -> B) -> [B] { vec::concat(map_slices(xs) {|| - fn~(_base: uint, slice : [const A]/&, copy f) -> [B] { + fn~(_base: uint, slice : [A]/&, copy f) -> [B] { vec::map(slice, f) } }) @@ -84,7 +84,7 @@ fn map(xs: [A], f: fn~(A) -> B) -> [B] { #[doc="A parallel version of mapi."] fn mapi(xs: [A], f: fn~(uint, A) -> B) -> [B] { let slices = map_slices(xs) {|| - fn~(base: uint, slice : [const A]/&, copy f) -> [B] { + fn~(base: uint, slice : [A]/&, copy f) -> [B] { vec::mapi(slice) {|i, x| f(i + base, x) } @@ -104,7 +104,7 @@ fn mapi_factory( xs: [A], f: fn() -> fn~(uint, A) -> B) -> [B] { let slices = map_slices(xs) {|| let f = f(); - fn~(base: uint, slice : [const A]/&, move f) -> [B] { + fn~(base: uint, slice : [A]/&, move f) -> [B] { vec::mapi(slice) {|i, x| f(i + base, x) } @@ -119,7 +119,7 @@ fn mapi_factory( #[doc="Returns true if the function holds for all elements in the vector."] fn alli(xs: [A], f: fn~(uint, A) -> bool) -> bool { vec::all(map_slices(xs) {|| - fn~(base: uint, slice : [const A]/&, copy f) -> bool { + fn~(base: uint, slice : [A]/&, copy f) -> bool { vec::alli(slice) {|i, x| f(i + base, x) } @@ -130,7 +130,7 @@ fn alli(xs: [A], f: fn~(uint, A) -> bool) -> bool { #[doc="Returns true if the function holds for any elements in the vector."] fn any(xs: [A], f: fn~(A) -> bool) -> bool { vec::any(map_slices(xs) {|| - fn~(_base : uint, slice: [const A]/&, copy f) -> bool { + fn~(_base : uint, slice: [A]/&, copy f) -> bool { vec::any(slice, f) } }) {|x| x } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 77423a993d4..f9393890f3c 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -272,14 +272,9 @@ fn sort_meta_items(items: [@ast::meta_item]) -> [@ast::meta_item] { } // This is sort of stupid here, converting to a vec of mutables and back - let mut v: [mut @ast::meta_item] = [mut]; - for items.each {|mi| v += [mut mi]; } - + let v: [mut @ast::meta_item] = vec::to_mut(items); std::sort::quick_sort(lteq, v); - - let mut v2: [@ast::meta_item] = []; - for v.each {|mi| v2 += [mi]; } - ret v2; + ret vec::from_mut(v); } fn remove_meta_items_by_name(items: [@ast::meta_item], name: str) -> diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index 884ced0a7f6..a92db033c22 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -1512,7 +1512,8 @@ fn lookup_in_globs(e: env, globs: [glob_imp_def], sp: span, id: ident, none { none } } } - let matches = vec::filter_map(copy globs, + let g = copy globs; // FIXME #2405 + let matches = vec::filter_map(g, {|x| lookup_in_mod_(e, x, sp, id, ns, dr)}); if vec::len(matches) == 0u { ret none; diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs index 98c5dc567bd..445f300cb02 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -120,7 +120,7 @@ fn classify_ty(ty: TypeRef) -> [x86_64_reg_class] { } fn all_mem(cls: [mut x86_64_reg_class]) { - vec::iteri(cls) {|i, _c| + for uint::range(0u, cls.len()) { |i| cls[i] = memory_class; } }