iterate only over immutable vectors; use newer region notation
Unfortunately, right now iterating over const vectors is not safe. This is because the callback expects an *immutable* reference (in region terms: &T), not a const reference (&const T). This was not being caught by the type system due to the use of unsafe operations. To fix this, we need to either (1) find a way to parameterize over mutability or (2) add each_const, each_mut etc
This commit is contained in:
parent
7f3bbd57c0
commit
eb0a34c398
4 changed files with 21 additions and 20 deletions
|
@ -56,7 +56,7 @@ fn arc<T: const send>(-data: T) -> arc<T> {
|
|||
* Access the underlying data in an atomically reference counted
|
||||
* wrapper.
|
||||
*/
|
||||
fn get<T: const send>(rc: &a.arc<T>) -> &a.T {
|
||||
fn get<T: const send>(rc: &arc<T>) -> &T {
|
||||
unsafe {
|
||||
let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
|
||||
// Cast us back into the correct region
|
||||
|
|
|
@ -229,7 +229,7 @@ pure fn from_char(ch: char) -> ~str {
|
|||
}
|
||||
|
||||
/// Convert a vector of chars to a string
|
||||
pure fn from_chars(chs: &[const char]) -> ~str {
|
||||
pure fn from_chars(chs: &[char]) -> ~str {
|
||||
let mut buf = ~"";
|
||||
unchecked {
|
||||
reserve(buf, chs.len());
|
||||
|
@ -283,14 +283,14 @@ pure fn append(+lhs: ~str, rhs: &str) -> ~str {
|
|||
|
||||
|
||||
/// Concatenate a vector of strings
|
||||
pure fn concat(v: &[const ~str]) -> ~str {
|
||||
pure fn concat(v: &[~str]) -> ~str {
|
||||
let mut s: ~str = ~"";
|
||||
for vec::each(v) |ss| { unchecked { push_str(s, ss) }; }
|
||||
ret s;
|
||||
}
|
||||
|
||||
/// Concatenate a vector of strings, placing a given separator between each
|
||||
pure fn connect(v: &[const ~str], sep: ~str) -> ~str {
|
||||
pure fn connect(v: &[~str], sep: ~str) -> ~str {
|
||||
let mut s = ~"", first = true;
|
||||
for vec::each(v) |ss| {
|
||||
if first { first = false; } else { unchecked { push_str(s, sep); } }
|
||||
|
@ -1288,7 +1288,7 @@ Section: Misc
|
|||
*/
|
||||
|
||||
/// Determines if a vector of bytes contains valid UTF-8
|
||||
pure fn is_utf8(v: &[const u8]) -> bool {
|
||||
pure fn is_utf8(v: &[u8]) -> bool {
|
||||
let mut i = 0u;
|
||||
let total = vec::len::<u8>(v);
|
||||
while i < total {
|
||||
|
@ -1306,7 +1306,7 @@ pure fn is_utf8(v: &[const u8]) -> bool {
|
|||
}
|
||||
|
||||
/// Determines if a vector of `u16` contains valid UTF-16
|
||||
pure fn is_utf16(v: &[const u16]) -> bool {
|
||||
pure fn is_utf16(v: &[u16]) -> bool {
|
||||
let len = vec::len(v);
|
||||
let mut i = 0u;
|
||||
while (i < len) {
|
||||
|
@ -1349,7 +1349,7 @@ pure fn to_utf16(s: &str) -> ~[u16] {
|
|||
ret u;
|
||||
}
|
||||
|
||||
pure fn utf16_chars(v: &[const u16], f: fn(char)) {
|
||||
pure fn utf16_chars(v: &[u16], f: fn(char)) {
|
||||
let len = vec::len(v);
|
||||
let mut i = 0u;
|
||||
while (i < len && v[i] != 0u16) {
|
||||
|
@ -1374,7 +1374,7 @@ pure fn utf16_chars(v: &[const u16], f: fn(char)) {
|
|||
}
|
||||
|
||||
|
||||
pure fn from_utf16(v: &[const u16]) -> ~str {
|
||||
pure fn from_utf16(v: &[u16]) -> ~str {
|
||||
let mut buf = ~"";
|
||||
unchecked {
|
||||
reserve(buf, vec::len(v));
|
||||
|
|
|
@ -314,7 +314,7 @@ pure fn slice<T: copy>(v: &[const T], start: uint, end: uint) -> ~[T] {
|
|||
}
|
||||
|
||||
#[doc = "Return a slice that points into another slice."]
|
||||
pure fn view<T>(v: &a.[T], start: uint, end: uint) -> &a.[T] {
|
||||
pure fn view<T>(v: &[T], start: uint, end: uint) -> &[T] {
|
||||
assert (start <= end);
|
||||
assert (end <= len(v));
|
||||
do unpack_slice(v) |p, _len| {
|
||||
|
@ -1054,7 +1054,7 @@ pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
|
|||
* Return true to continue, false to break.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
|
||||
pure fn each<T>(v: &[T], f: fn(T) -> bool) {
|
||||
do vec::unpack_slice(v) |p, n| {
|
||||
let mut n = n;
|
||||
let mut p = p;
|
||||
|
@ -1074,7 +1074,7 @@ pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
|
|||
* Return true to continue, false to break.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
|
||||
pure fn eachi<T>(v: &[T], f: fn(uint, T) -> bool) {
|
||||
do vec::unpack_slice(v) |p, n| {
|
||||
let mut i = 0u;
|
||||
let mut p = p;
|
||||
|
@ -1331,7 +1331,7 @@ impl extensions/&<T: copy> of copyable_vector<T> for &[const T] {
|
|||
pure fn tail() -> ~[T] { tail(self) }
|
||||
}
|
||||
|
||||
trait immutable_vector/&<T> {
|
||||
trait immutable_vector<T> {
|
||||
pure fn foldr<U: copy>(z: U, p: fn(T, U) -> U) -> U;
|
||||
pure fn iter(f: fn(T));
|
||||
pure fn iteri(f: fn(uint, T));
|
||||
|
@ -1343,7 +1343,7 @@ trait immutable_vector/&<T> {
|
|||
pure fn rposition_elem(x: T) -> option<uint>;
|
||||
pure fn map<U>(f: fn(T) -> U) -> ~[U];
|
||||
pure fn mapi<U>(f: fn(uint, T) -> U) -> ~[U];
|
||||
fn map_r<U>(f: fn(x: &self.T) -> U) -> ~[U];
|
||||
fn map_r<U>(f: fn(x: &T) -> U) -> ~[U];
|
||||
pure fn alli(f: fn(uint, T) -> bool) -> bool;
|
||||
pure fn flat_map<U>(f: fn(T) -> ~[U]) -> ~[U];
|
||||
pure fn filter_map<U: copy>(f: fn(T) -> option<U>) -> ~[U];
|
||||
|
@ -1422,7 +1422,7 @@ impl extensions/&<T> of immutable_vector<T> for &[T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn map_r<U>(f: fn(x: &self.T) -> U) -> ~[U] {
|
||||
fn map_r<U>(f: fn(x: &T) -> U) -> ~[U] {
|
||||
let mut r = ~[];
|
||||
let mut i = 0;
|
||||
while i < self.len() {
|
||||
|
@ -1570,7 +1570,7 @@ mod unsafe {
|
|||
#[inline(always)]
|
||||
unsafe fn form_slice<T,U>(p: *T, len: uint, f: fn(&& &[T]) -> U) -> U {
|
||||
let pair = (p, len * sys::size_of::<T>());
|
||||
let v : *(&blk.[T]) =
|
||||
let v : *(&blk/[T]) =
|
||||
::unsafe::reinterpret_cast(ptr::addr_of(pair));
|
||||
f(*v)
|
||||
}
|
||||
|
@ -1638,12 +1638,13 @@ mod u8 {
|
|||
//
|
||||
// This cannot be used with iter-trait.rs because of the region pointer
|
||||
// required in the slice.
|
||||
impl extensions/&<A> of iter::base_iter<A> for &[const A] {
|
||||
|
||||
impl extensions/&<A> of iter::base_iter<A> for &[A] {
|
||||
fn each(blk: fn(A) -> bool) { each(self, blk) }
|
||||
fn size_hint() -> option<uint> { some(len(self)) }
|
||||
}
|
||||
|
||||
impl extensions/&<A> of iter::extended_iter<A> for &[const A] {
|
||||
impl extensions/&<A> of iter::extended_iter<A> for &[A] {
|
||||
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) }
|
||||
|
@ -1663,7 +1664,7 @@ trait iter_trait_extensions<A> {
|
|||
fn max() -> A;
|
||||
}
|
||||
|
||||
impl extensions/&<A:copy> of iter_trait_extensions<A> for &[const A] {
|
||||
impl extensions/&<A:copy> of iter_trait_extensions<A> for &[A] {
|
||||
fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
|
||||
iter::filter_to_vec(self, pred)
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ iface iterable<A> {
|
|||
fn iterate(blk: fn(A) -> bool);
|
||||
}
|
||||
|
||||
impl vec<A> of iterable<A> for &[const A] {
|
||||
impl vec<A> of iterable<A> for &[A] {
|
||||
fn iterate(f: fn(A) -> bool) {
|
||||
vec::each(self, f);
|
||||
}
|
||||
}
|
||||
|
||||
impl vec<A> of iterable<A> for ~[const A] {
|
||||
impl vec<A> of iterable<A> for ~[A] {
|
||||
fn iterate(f: fn(A) -> bool) {
|
||||
vec::each(self, f);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue