use element count in slices, not size in bytes
This allows the indexing bounds check or other comparisons against an element length to avoid a multiplication by the size.
This commit is contained in:
parent
aa93381e14
commit
e1a26ad271
10 changed files with 154 additions and 76 deletions
|
|
@ -52,6 +52,8 @@ fn main () {
|
|||
```
|
||||
*/
|
||||
|
||||
use sys::size_of;
|
||||
use unstable::raw::Slice;
|
||||
use cast;
|
||||
use container::Container;
|
||||
use iter::{Iterator, range};
|
||||
|
|
@ -133,10 +135,10 @@ pub trait Rng {
|
|||
/// println!("{:?}", v);
|
||||
/// }
|
||||
/// ```
|
||||
fn fill_bytes(&mut self, mut dest: &mut [u8]) {
|
||||
// this relies on the lengths being transferred correctly when
|
||||
// transmuting between vectors like this.
|
||||
let as_u64: &mut &mut [u64] = unsafe { cast::transmute(&mut dest) };
|
||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
||||
let mut slice: Slice<u64> = unsafe { cast::transmute_copy(&dest) };
|
||||
slice.len /= size_of::<u64>();
|
||||
let as_u64: &mut [u64] = unsafe { cast::transmute(slice) };
|
||||
for dest in as_u64.mut_iter() {
|
||||
*dest = self.next_u64();
|
||||
}
|
||||
|
|
@ -147,7 +149,9 @@ pub trait Rng {
|
|||
|
||||
// space for a u32
|
||||
if remaining >= 4 {
|
||||
let as_u32: &mut &mut [u32] = unsafe { cast::transmute(&mut dest) };
|
||||
let mut slice: Slice<u32> = unsafe { cast::transmute_copy(&dest) };
|
||||
slice.len /= size_of::<u32>();
|
||||
let as_u32: &mut [u32] = unsafe { cast::transmute(slice) };
|
||||
as_u32[as_u32.len() - 1] = self.next_u32();
|
||||
remaining -= 4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,12 +186,7 @@ impl<'self> ReprVisitor<'self> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn write_vec_range(&mut self,
|
||||
_mtbl: uint,
|
||||
ptr: *(),
|
||||
len: uint,
|
||||
inner: *TyDesc)
|
||||
-> bool {
|
||||
pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
|
||||
let mut p = ptr as *u8;
|
||||
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
|
||||
self.writer.write(['[' as u8]);
|
||||
|
|
@ -213,13 +208,8 @@ impl<'self> ReprVisitor<'self> {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn write_unboxed_vec_repr(&mut self,
|
||||
mtbl: uint,
|
||||
v: &raw::Vec<()>,
|
||||
inner: *TyDesc)
|
||||
-> bool {
|
||||
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
|
||||
v.fill, inner)
|
||||
pub fn write_unboxed_vec_repr(&mut self, _: uint, v: &raw::Vec<()>, inner: *TyDesc) -> bool {
|
||||
self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner)
|
||||
}
|
||||
|
||||
fn write_escaped_char(&mut self, ch: char, is_str: bool) {
|
||||
|
|
@ -377,19 +367,32 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
do self.get::<raw::Slice<()>> |this, s| {
|
||||
this.writer.write(['&' as u8]);
|
||||
this.write_mut_qualifier(mtbl);
|
||||
this.write_vec_range(mtbl, s.data, s.len, inner);
|
||||
this.write_vec_range(s.data, s.len, inner);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
|
||||
do self.get::<raw::Slice<()>> |this, s| {
|
||||
this.writer.write(['&' as u8]);
|
||||
this.write_mut_qualifier(mtbl);
|
||||
let size = unsafe {
|
||||
if (*inner).size == 0 { 1 } else { (*inner).size }
|
||||
};
|
||||
this.write_vec_range(s.data, s.len * size, inner);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
|
||||
mtbl: uint, inner: *TyDesc) -> bool {
|
||||
_: uint, inner: *TyDesc) -> bool {
|
||||
let assumed_size = if sz == 0 { n } else { sz };
|
||||
do self.get::<()> |this, b| {
|
||||
this.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), assumed_size, inner);
|
||||
this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -974,6 +974,7 @@ pub trait ImmutableVector<'self, T> {
|
|||
|
||||
impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
fn slice(&self, start: uint, end: uint) -> &'self [T] {
|
||||
assert!(start <= end);
|
||||
assert!(end <= self.len());
|
||||
|
|
@ -986,10 +987,27 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
fn slice(&self, start: uint, end: uint) -> &'self [T] {
|
||||
assert!(start <= end);
|
||||
assert!(end <= self.len());
|
||||
do self.as_imm_buf |p, _len| {
|
||||
unsafe {
|
||||
cast::transmute(Slice {
|
||||
data: ptr::offset(p, start as int),
|
||||
len: (end - start)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_from(&self, start: uint) -> &'self [T] {
|
||||
self.slice(start, self.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_to(&self, end: uint) -> &'self [T] {
|
||||
self.slice(0, end)
|
||||
|
|
@ -1130,10 +1148,18 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
|
||||
let s = self.repr();
|
||||
f(s.data, s.len / sys::nonzero_size_of::<T>())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U {
|
||||
let s = self.repr();
|
||||
f(s.data, s.len)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension methods for vectors contain `Eq` elements.
|
||||
|
|
@ -1899,6 +1925,7 @@ pub trait MutableVector<'self, T> {
|
|||
|
||||
impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
|
||||
assert!(start <= end);
|
||||
assert!(end <= self.len());
|
||||
|
|
@ -1912,6 +1939,21 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] {
|
||||
assert!(start <= end);
|
||||
assert!(end <= self.len());
|
||||
do self.as_mut_buf |p, _len| {
|
||||
unsafe {
|
||||
cast::transmute(Slice {
|
||||
data: ptr::mut_offset(p, start as int) as *T,
|
||||
len: (end - start)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mut_slice_from(self, start: uint) -> &'self mut [T] {
|
||||
let len = self.len();
|
||||
|
|
@ -1991,11 +2033,18 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U {
|
||||
let Slice{ data, len } = self.repr();
|
||||
f(data as *mut T, len / sys::nonzero_size_of::<T>())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U {
|
||||
let Slice{ data, len } = self.repr();
|
||||
f(data as *mut T, len)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for &[T] where T is Cloneable
|
||||
|
|
@ -2083,6 +2132,7 @@ pub mod raw {
|
|||
* not bytes).
|
||||
*/
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub unsafe fn buf_as_slice<T,U>(p: *T,
|
||||
len: uint,
|
||||
f: &fn(v: &[T]) -> U) -> U {
|
||||
|
|
@ -2097,6 +2147,22 @@ pub mod raw {
|
|||
* not bytes).
|
||||
*/
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub unsafe fn buf_as_slice<T,U>(p: *T,
|
||||
len: uint,
|
||||
f: &fn(v: &[T]) -> U) -> U {
|
||||
f(cast::transmute(Slice {
|
||||
data: p,
|
||||
len: len
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Form a slice from a pointer and length (as a number of units,
|
||||
* not bytes).
|
||||
*/
|
||||
#[inline]
|
||||
#[cfg(stage0)]
|
||||
pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
|
||||
len: uint,
|
||||
f: &fn(v: &mut [T]) -> U) -> U {
|
||||
|
|
@ -2106,6 +2172,21 @@ pub mod raw {
|
|||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Form a slice from a pointer and length (as a number of units,
|
||||
* not bytes).
|
||||
*/
|
||||
#[inline]
|
||||
#[cfg(not(stage0))]
|
||||
pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T,
|
||||
len: uint,
|
||||
f: &fn(v: &mut [T]) -> U) -> U {
|
||||
f(cast::transmute(Slice {
|
||||
data: p as *T,
|
||||
len: len
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Unchecked vector indexing.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue