Skip to content

Commit 3c40b74

Browse files
committed
---
yaml --- r: 40831 b: refs/heads/dist-snap c: 2c21f34 h: refs/heads/master i: 40829: 5e94dee 40827: 21b0e18 40823: e943c48 40815: 3e9a63e 40799: 32c8d5c 40767: 993b40a 40703: 0e49dc7 v: v3
1 parent a186379 commit 3c40b74

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: a810c03263670238bccd64cabb12a23a46e3a278
99
refs/heads/incoming: e90142e536c150df0d9b4b2f11352152177509b5
10-
refs/heads/dist-snap: dbc52ce505eb5da181a658606a6129962a90c403
10+
refs/heads/dist-snap: 2c21f348a45f593ed4452fab9d083283cd4e7ce0
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1313
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libcore/vec.rs

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -398,28 +398,51 @@ pub fn rsplitn<T: Copy>(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] {
398398
// Mutators
399399

400400
/// Removes the first element from a vector and return it
401-
pub fn shift<T>(v: &mut ~[T]) -> T {
402-
let ln = v.len();
403-
assert (ln > 0);
401+
pub fn shift<T>(v: &mut ~[T]) -> T unsafe {
404402

405-
let mut vv = ~[];
406-
*v <-> vv;
403+
assert v.is_not_empty();
407404

408-
unsafe {
409-
let mut rr;
410-
{
411-
let vv = raw::to_ptr(vv);
412-
rr = move *vv;
413-
414-
for uint::range(1, ln) |i| {
415-
let r = move *ptr::offset(vv, i);
416-
v.push(r);
417-
}
418-
}
419-
raw::set_len(&mut vv, 0);
405+
if v.len() == 1 { return v.pop() }
420406

421-
rr
407+
if v.len() == 2 {
408+
let last = v.pop();
409+
let first = v.pop();
410+
v.push(last);
411+
return first;
422412
}
413+
414+
let ln = v.len();
415+
let next_ln = v.len() - 1;
416+
417+
// Save the last element. We're going to overwrite its position
418+
let mut work_elt = v.pop();
419+
// We still should have room to work where what last element was
420+
assert capacity(v) >= ln;
421+
// Pretend like we have the original length so we can use
422+
// the vector memcpy to overwrite the hole we just made
423+
raw::set_len(v, ln);
424+
425+
// Memcopy the head element (the one we want) to the location we just
426+
// popped. For the moment it unsafely exists at both the head and last
427+
// positions
428+
let first_slice = view(*v, 0, 1);
429+
let last_slice = mut_view(*v, next_ln, ln);
430+
raw::memcpy(last_slice, first_slice, 1);
431+
432+
// Memcopy everything to the left one element
433+
let init_slice = mut_view(*v, 0, next_ln);
434+
let tail_slice = view(*v, 1, ln);
435+
raw::memcpy(init_slice, tail_slice, next_ln);
436+
437+
// Set the new length. Now the vector is back to normal
438+
raw::set_len(v, next_ln);
439+
440+
// Swap out the element we want from the end
441+
let vp = raw::to_mut_ptr(*v);
442+
let vp = ptr::mut_offset(vp, next_ln - 1);
443+
*vp <-> work_elt;
444+
445+
return work_elt;
423446
}
424447

425448
/// Prepend an element to the vector
@@ -1760,7 +1783,7 @@ pub struct UnboxedVecRepr {
17601783
}
17611784

17621785
/// Unsafe operations
1763-
mod raw {
1786+
pub mod raw {
17641787

17651788
/// The internal representation of a (boxed) vector
17661789
pub struct VecRepr {

0 commit comments

Comments
 (0)