diff options
| author | Jed Davis <jld@panix.com> | 2013-01-08 00:24:43 -0800 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2013-01-13 14:37:59 -0800 |
| commit | 1b01629f189f1c4050bd5c7eac81e44ba2c7a76f (patch) | |
| tree | a958ba05b82b2948ca24891931c704f69ad9014f /src/libcore | |
| parent | ea53c48ca23ec4e46454d48936c209d2a67cf892 (diff) | |
Make vectors (& old ports) of zero-size types allocate one byte each.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/oldcomm.rs | 3 | ||||
| -rw-r--r-- | src/libcore/sys.rs | 21 | ||||
| -rw-r--r-- | src/libcore/vec.rs | 32 |
3 files changed, 44 insertions, 12 deletions
diff --git a/src/libcore/oldcomm.rs b/src/libcore/oldcomm.rs index 65aaf1fe428..ae3116b08f0 100644 --- a/src/libcore/oldcomm.rs +++ b/src/libcore/oldcomm.rs @@ -91,7 +91,8 @@ pub enum Chan<T: Owned> { /// Constructs a port pub fn Port<T: Owned>() -> Port<T> { unsafe { - Port_(@PortPtr(rustrt::new_port(sys::size_of::<T>() as size_t))) + Port_(@PortPtr(rustrt::new_port(sys::nonzero_size_of::<T>() + as size_t))) } } diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index ad9c3d1e51d..322aa895eb4 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -88,6 +88,17 @@ pub pure fn size_of<T>() -> uint { } /** + * Returns the size of a type, or 1 if the actual size is zero. + * + * Useful for building structures containing variable-length arrays. + */ +#[inline(always)] +pub pure fn nonzero_size_of<T>() -> uint { + let s = size_of::<T>(); + if s == 0 { 1 } else { s } +} + +/** * Returns the ABI-required minimum alignment of a type * * This is the alignment used for struct fields. It may be smaller @@ -146,7 +157,7 @@ pub pure fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { #[cfg(test)] pub mod tests { use cast; - use sys::{Closure, pref_align_of, size_of}; + use sys::{Closure, pref_align_of, size_of, nonzero_size_of}; #[test] pub fn size_of_basic() { @@ -172,6 +183,14 @@ pub mod tests { } #[test] + pub fn nonzero_size_of_basic() { + type Z = [i8 * 0]; + assert size_of::<Z>() == 0u; + assert nonzero_size_of::<Z>() == 1u; + assert nonzero_size_of::<uint>() == size_of::<uint>(); + } + + #[test] pub fn align_of_basic() { assert pref_align_of::<u8>() == 1u; assert pref_align_of::<u16>() == 2u; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index b9cefa89aa7..29767f3c1e0 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -103,7 +103,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) { pub pure fn capacity<T>(v: &const ~[T]) -> uint { unsafe { let repr: **raw::VecRepr = ::cast::transmute(v); - (**repr).unboxed.alloc / sys::size_of::<T>() + (**repr).unboxed.alloc / sys::nonzero_size_of::<T>() } } @@ -276,7 +276,7 @@ pub pure fn view<T>(v: &r/[T], start: uint, end: uint) -> &r/[T] { unsafe { ::cast::reinterpret_cast( &(ptr::offset(p, start), - (end - start) * sys::size_of::<T>())) + (end - start) * sys::nonzero_size_of::<T>())) } } } @@ -289,7 +289,7 @@ pub pure fn mut_view<T>(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] { unsafe { ::cast::reinterpret_cast( &(ptr::mut_offset(p, start), - (end - start) * sys::size_of::<T>())) + (end - start) * sys::nonzero_size_of::<T>())) } } } @@ -303,7 +303,7 @@ pub pure fn const_view<T>(v: &r/[const T], start: uint, unsafe { ::cast::reinterpret_cast( &(ptr::const_offset(p, start), - (end - start) * sys::size_of::<T>())) + (end - start) * sys::nonzero_size_of::<T>())) } } } @@ -608,7 +608,7 @@ pub fn push<T>(v: &mut ~[T], initval: T) { unsafe fn push_fast<T>(v: &mut ~[T], initval: T) { let repr: **raw::VecRepr = ::cast::transmute(v); let fill = (**repr).unboxed.fill; - (**repr).unboxed.fill += sys::size_of::<T>(); + (**repr).unboxed.fill += sys::nonzero_size_of::<T>(); let p = addr_of(&((**repr).unboxed.data)); let p = ptr::offset(p, fill) as *mut T; rusti::move_val_init(&mut(*p), move initval); @@ -1449,7 +1449,7 @@ pub pure fn as_imm_buf<T,U>(s: &[T], let v : *(*T,uint) = ::cast::reinterpret_cast(&addr_of(&s)); let (buf,len) = *v; - f(buf, len / sys::size_of::<T>()) + f(buf, len / sys::nonzero_size_of::<T>()) } } @@ -1462,7 +1462,7 @@ pub pure fn as_const_buf<T,U>(s: &[const T], let v : *(*const T,uint) = ::cast::reinterpret_cast(&addr_of(&s)); let (buf,len) = *v; - f(buf, len / sys::size_of::<T>()) + f(buf, len / sys::nonzero_size_of::<T>()) } } @@ -1475,7 +1475,7 @@ pub pure fn as_mut_buf<T,U>(s: &[mut T], let v : *(*mut T,uint) = ::cast::reinterpret_cast(&addr_of(&s)); let (buf,len) = *v; - f(buf, len / sys::size_of::<T>()) + f(buf, len / sys::nonzero_size_of::<T>()) } } @@ -1992,7 +1992,7 @@ pub mod raw { #[inline(always)] pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) { let repr: **VecRepr = ::cast::transmute(v); - (**repr).unboxed.fill = new_len * sys::size_of::<T>(); + (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>(); } /** @@ -2032,7 +2032,7 @@ pub mod raw { pub unsafe fn buf_as_slice<T,U>(p: *T, len: uint, f: fn(v: &[T]) -> U) -> U { - let pair = (p, len * sys::size_of::<T>()); + let pair = (p, len * sys::nonzero_size_of::<T>()); let v : *(&blk/[T]) = ::cast::reinterpret_cast(&addr_of(&pair)); f(*v) @@ -2502,6 +2502,18 @@ mod tests { } #[test] + fn test_len_divzero() { + type Z = [i8 * 0]; + let v0 : &[Z] = &[]; + let v1 : &[Z] = &[[]]; + let v2 : &[Z] = &[[], []]; + assert(sys::size_of::<Z>() == 0); + assert(len(v0) == 0); + assert(len(v1) == 1); + assert(len(v2) == 2); + } + + #[test] fn test_head() { let a = ~[11, 12]; assert (head(a) == 11); |
