diff --git a/doc/rust.md b/doc/rust.md index 0939664fc79..8f742d0d210 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2620,7 +2620,7 @@ assert!(b != "world"); The vector type constructor represents a homogeneous array of values of a given type. A vector has a fixed size. -(Operations like `vec::push` operate solely on owned vectors.) +(Operations like `vec.push` operate solely on owned vectors.) A vector type can be annotated with a _definite_ size, written with a trailing asterisk and integer literal, such as `[int * 10]`. Such a definite-sized vector type is a first-class type, since its size is known statically. diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 39cce41b386..d7c20ed2d50 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -763,8 +763,7 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, if item_method_sort(mth) != 'p' { loop; } - vec::push(&mut result, - @get_method(intr, cdata, did.node, tcx)); + result.push(@get_method(intr, cdata, did.node, tcx)); } return result; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 7cd64e863d2..b839e22f906 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4862,8 +4862,8 @@ impl Resolver { while j != 0 { j -= 1; for this.value_ribs[j].bindings.each_key |&k| { - vec::push(&mut maybes, this.session.str_of(k)); - vec::push(&mut values, uint::max_value); + maybes.push(this.session.str_of(k)); + values.push(uint::max_value); } } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index bd99a8e150b..5d0fbfcb1ba 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -788,7 +788,7 @@ impl CoherenceChecker { `%s` to impl", provided_method.method_info .ident.repr(self.crate_context.tcx)); - vec::push(all_methods, provided_method.method_info); + all_methods.push(provided_method.method_info); } } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 5534c5befc2..165996f935e 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1140,7 +1140,7 @@ pub fn set_exit_status(code: int) { unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] { let mut args = ~[]; for uint::range(0, argc as uint) |i| { - vec::push(&mut args, str::raw::from_c_str(*argv.offset(i))); + args.push(str::raw::from_c_str(*argv.offset(i))); } args } @@ -1186,8 +1186,7 @@ pub fn real_args() -> ~[~str] { while *ptr.offset(len) != 0 { len += 1; } // Push it onto the list. - vec::push(&mut args, - vec::raw::buf_as_slice(ptr, len, + args.push(vec::raw::buf_as_slice(ptr, len, str::from_utf16)); } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index bc933e70b37..f0c81f9c04b 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -438,86 +438,6 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { } } -/// Append an element to a vector -#[inline] -pub fn push(v: &mut ~[T], initval: T) { - unsafe { - let repr: **raw::VecRepr = transmute(&mut *v); - let fill = (**repr).unboxed.fill; - if (**repr).unboxed.alloc > fill { - push_fast(v, initval); - } - else { - push_slow(v, initval); - } - } -} - -// This doesn't bother to make sure we have space. -#[inline] // really pretty please -unsafe fn push_fast(v: &mut ~[T], initval: T) { - let repr: **mut raw::VecRepr = transmute(v); - let fill = (**repr).unboxed.fill; - (**repr).unboxed.fill += sys::nonzero_size_of::(); - let p = to_unsafe_ptr(&((**repr).unboxed.data)); - let p = ptr::offset(p, fill) as *mut T; - intrinsics::move_val_init(&mut(*p), initval); -} - -#[inline(never)] -fn push_slow(v: &mut ~[T], initval: T) { - let new_len = v.len() + 1; - reserve_at_least(&mut *v, new_len); - unsafe { push_fast(v, initval) } -} - -/// Iterates over the slice `rhs`, copies each element, and then appends it to -/// the vector provided `v`. The `rhs` vector is traversed in-order. -/// -/// # Example -/// -/// ~~~ {.rust} -/// let mut a = ~[1]; -/// vec::push_all(&mut a, [2, 3, 4]); -/// assert!(a == ~[1, 2, 3, 4]); -/// ~~~ -#[inline] -pub fn push_all(v: &mut ~[T], rhs: &const [T]) { - let new_len = v.len() + rhs.len(); - reserve(&mut *v, new_len); - - for uint::range(0u, rhs.len()) |i| { - push(&mut *v, unsafe { raw::get(rhs, i) }) - } -} - -/// Takes ownership of the vector `rhs`, moving all elements into the specified -/// vector `v`. This does not copy any elements, and it is illegal to use the -/// `rhs` vector after calling this method (because it is moved here). -/// -/// # Example -/// -/// ~~~ {.rust} -/// let mut a = ~[~1]; -/// vec::push_all_move(&mut a, ~[~2, ~3, ~4]); -/// assert!(a == ~[~1, ~2, ~3, ~4]); -/// ~~~ -#[inline] -pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { - let new_len = v.len() + rhs.len(); - reserve(&mut *v, new_len); - unsafe { - do as_mut_buf(rhs) |p, len| { - for uint::range(0, len) |i| { - let x = ptr::replace_ptr(ptr::mut_offset(p, i), - intrinsics::uninit()); - push(&mut *v, x); - } - } - raw::set_len(&mut rhs, 0); - } -} - /// Shorten a vector, dropping excess elements. pub fn truncate(v: &mut ~[T], newlen: uint) { do as_mut_buf(*v) |p, oldlen| { @@ -1699,6 +1619,8 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { #[allow(missing_doc)] pub trait OwnedVector { fn push(&mut self, t: T); + unsafe fn push_fast(&mut self, t: T); + fn push_all_move(&mut self, rhs: ~[T]); fn pop(&mut self) -> T; fn shift(&mut self) -> T; @@ -1716,14 +1638,67 @@ pub trait OwnedVector { } impl OwnedVector for ~[T] { + /// Append an element to a vector #[inline] fn push(&mut self, t: T) { - push(self, t); + unsafe { + let repr: **raw::VecRepr = transmute(&mut *self); + let fill = (**repr).unboxed.fill; + if (**repr).unboxed.alloc <= fill { + // need more space + reserve_no_inline(self); + } + + self.push_fast(t); + } + + // this peculiar function is because reserve_at_least is very + // large (because of reserve), and will be inlined, which + // makes push too large. + #[inline(never)] + fn reserve_no_inline(v: &mut ~[T]) { + let new_len = v.len() + 1; + reserve_at_least(v, new_len); + } } + // This doesn't bother to make sure we have space. + #[inline] // really pretty please + unsafe fn push_fast(&mut self, t: T) { + let repr: **mut raw::VecRepr = transmute(self); + let fill = (**repr).unboxed.fill; + (**repr).unboxed.fill += sys::nonzero_size_of::(); + let p = to_unsafe_ptr(&((**repr).unboxed.data)); + let p = ptr::offset(p, fill) as *mut T; + intrinsics::move_val_init(&mut(*p), t); + } + + /// Takes ownership of the vector `rhs`, moving all elements into + /// the current vector. This does not copy any elements, and it is + /// illegal to use the `rhs` vector after calling this method + /// (because it is moved here). + /// + /// # Example + /// + /// ~~~ {.rust} + /// let mut a = ~[~1]; + /// a.push_all_move(~[~2, ~3, ~4]); + /// assert!(a == ~[~1, ~2, ~3, ~4]); + /// ~~~ #[inline] - fn push_all_move(&mut self, rhs: ~[T]) { - push_all_move(self, rhs); + fn push_all_move(&mut self, mut rhs: ~[T]) { + let new_len = self.len() + rhs.len(); + reserve(self, new_len); + unsafe { + do as_mut_buf(rhs) |p, len| { + for uint::range(0, len) |i| { + let x = ptr::replace_ptr(ptr::mut_offset(p, i), + intrinsics::uninit()); + self.push(x); + } + } + raw::set_len(&mut rhs, 0); + } } /// Remove the last element from a vector and return it @@ -1898,9 +1873,24 @@ pub trait OwnedCopyableVector { } impl OwnedCopyableVector for ~[T] { + /// Iterates over the slice `rhs`, copies each element, and then appends it to + /// the vector provided `v`. The `rhs` vector is traversed in-order. + /// + /// # Example + /// + /// ~~~ {.rust} + /// let mut a = ~[1]; + /// a.push_all([2, 3, 4]); + /// assert!(a == ~[1, 2, 3, 4]); + /// ~~~ #[inline] fn push_all(&mut self, rhs: &const [T]) { - push_all(self, rhs); + let new_len = self.len() + rhs.len(); + reserve(self, new_len); + + for uint::range(0u, rhs.len()) |i| { + self.push(unsafe { raw::get(rhs, i) }) + } } #[inline]