@@ -398,28 +398,51 @@ pub fn rsplitn<T: Copy>(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] {
398
398
// Mutators
399
399
400
400
/// 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 {
404
402
405
- let mut vv = ~[ ] ;
406
- * v <-> vv;
403
+ assert v. is_not_empty ( ) ;
407
404
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 ( ) }
420
406
421
- rr
407
+ if v. len ( ) == 2 {
408
+ let last = v. pop ( ) ;
409
+ let first = v. pop ( ) ;
410
+ v. push ( last) ;
411
+ return first;
422
412
}
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;
423
446
}
424
447
425
448
/// Prepend an element to the vector
@@ -1760,7 +1783,7 @@ pub struct UnboxedVecRepr {
1760
1783
}
1761
1784
1762
1785
/// Unsafe operations
1763
- mod raw {
1786
+ pub mod raw {
1764
1787
1765
1788
/// The internal representation of a (boxed) vector
1766
1789
pub struct VecRepr {
0 commit comments