@@ -1400,6 +1400,22 @@ pub trait OwnedVector<T> {
14001400 /// elements after position i one position to the right.
14011401 fn insert ( & mut self , i : uint , x : T ) ;
14021402
1403+ /// Remove and return the element at position `i` within `v`,
1404+ /// shifting all elements after position `i` one position to the
1405+ /// left. Returns `None` if `i` is out of bounds.
1406+ ///
1407+ /// # Example
1408+ /// ```rust
1409+ /// let mut v = ~[1, 2, 3];
1410+ /// assert_eq!(v.remove_opt(1), Some(2));
1411+ /// assert_eq!(v, ~[1, 3]);
1412+ ///
1413+ /// assert_eq!(v.remove_opt(4), None);
1414+ /// // v is unchanged:
1415+ /// assert_eq!(v, ~[1, 3]);
1416+ /// ```
1417+ fn remove_opt ( & mut self , i : uint ) -> Option < T > ;
1418+
14031419 /// Remove and return the element at position i within v, shifting
14041420 /// all elements after position i one position to the left.
14051421 fn remove ( & mut self , i : uint ) -> T ;
@@ -1609,66 +1625,59 @@ impl<T> OwnedVector<T> for ~[T] {
16091625 }
16101626
16111627 fn shift_opt ( & mut self ) -> Option < T > {
1612- match self . len ( ) {
1613- 0 => None ,
1614- 1 => self . pop_opt ( ) ,
1615- 2 => {
1616- let last = self . pop ( ) ;
1617- let first = self . pop_opt ( ) ;
1618- self . push ( last) ;
1619- first
1620- }
1621- len => {
1622- unsafe {
1623- let next_len = len - 1 ;
1624-
1625- let ptr = self . as_ptr ( ) ;
1626-
1627- // copy out the head element, for the moment it exists
1628- // unsafely on the stack and as the first element of the
1629- // vector.
1630- let head = ptr:: read_ptr ( ptr) ;
1631-
1632- // Memcpy everything to the left one element (leaving the
1633- // last element unsafely in two consecutive memory
1634- // locations)
1635- ptr:: copy_memory ( self . as_mut_ptr ( ) , ptr. offset ( 1 ) , next_len) ;
1636-
1637- // set the new length, which means the second instance of
1638- // the last element is forgotten.
1639- self . set_len ( next_len) ;
1640-
1641- Some ( head)
1642- }
1643- }
1644- }
1628+ self . remove_opt ( 0 )
16451629 }
16461630
16471631 fn unshift ( & mut self , x : T ) {
1648- let v = util:: replace ( self , ~[ x] ) ;
1649- self . push_all_move ( v) ;
1632+ self . insert ( 0 , x)
16501633 }
1651- fn insert ( & mut self , i : uint , x : T ) {
1634+
1635+ fn insert ( & mut self , i : uint , x : T ) {
16521636 let len = self . len ( ) ;
16531637 assert ! ( i <= len) ;
1654-
1655- self . push ( x) ;
1656- let mut j = len;
1657- while j > i {
1658- self . swap ( j, j - 1 ) ;
1659- j -= 1 ;
1638+ // space for the new element
1639+ self . reserve_additional ( 1 ) ;
1640+
1641+ unsafe { // infallible
1642+ // The spot to put the new value
1643+ let p = self . as_mut_ptr ( ) . offset ( i as int ) ;
1644+ // Shift everything over to make space. (Duplicating the
1645+ // `i`th element into two consecutive places.)
1646+ ptr:: copy_memory ( p. offset ( 1 ) , p, len - i) ;
1647+ // Write it in, overwriting the first copy of the `i`th
1648+ // element.
1649+ intrinsics:: move_val_init ( & mut * p, x) ;
1650+ self . set_len ( len + 1 ) ;
16601651 }
16611652 }
1653+
1654+ #[ inline]
16621655 fn remove ( & mut self , i : uint ) -> T {
1656+ match self . remove_opt ( i) {
1657+ Some ( t) => t,
1658+ None => fail ! ( "remove: the len is {} but the index is {}" , self . len( ) , i)
1659+ }
1660+ }
1661+
1662+ fn remove_opt ( & mut self , i : uint ) -> Option < T > {
16631663 let len = self . len ( ) ;
1664- assert ! ( i < len) ;
1664+ if i < len {
1665+ unsafe { // infallible
1666+ // the place we are taking from.
1667+ let ptr = self . as_mut_ptr ( ) . offset ( i as int ) ;
1668+ // copy it out, unsafely having a copy of the value on
1669+ // the stack and in the vector at the same time.
1670+ let ret = Some ( ptr:: read_ptr ( ptr as * T ) ) ;
1671+
1672+ // Shift everything down to fill in that spot.
1673+ ptr:: copy_memory ( ptr, ptr. offset ( 1 ) , len - i - 1 ) ;
1674+ self . set_len ( len - 1 ) ;
16651675
1666- let mut j = i ;
1667- while j < len - 1 {
1668- self . swap ( j , j + 1 ) ;
1669- j += 1 ;
1676+ ret
1677+ }
1678+ } else {
1679+ None
16701680 }
1671- self . pop ( )
16721681 }
16731682 fn swap_remove ( & mut self , index : uint ) -> T {
16741683 let ln = self . len ( ) ;
@@ -3380,6 +3389,29 @@ mod tests {
33803389 a. insert ( 4 , 5 ) ;
33813390 }
33823391
3392+ #[ test]
3393+ fn test_remove_opt ( ) {
3394+ let mut a = ~[ 1 , 2 , 3 , 4 ] ;
3395+
3396+ assert_eq ! ( a. remove_opt( 2 ) , Some ( 3 ) ) ;
3397+ assert_eq ! ( a, ~[ 1 , 2 , 4 ] ) ;
3398+
3399+ assert_eq ! ( a. remove_opt( 2 ) , Some ( 4 ) ) ;
3400+ assert_eq ! ( a, ~[ 1 , 2 ] ) ;
3401+
3402+ assert_eq ! ( a. remove_opt( 2 ) , None ) ;
3403+ assert_eq ! ( a, ~[ 1 , 2 ] ) ;
3404+
3405+ assert_eq ! ( a. remove_opt( 0 ) , Some ( 1 ) ) ;
3406+ assert_eq ! ( a, ~[ 2 ] ) ;
3407+
3408+ assert_eq ! ( a. remove_opt( 0 ) , Some ( 2 ) ) ;
3409+ assert_eq ! ( a, ~[ ] ) ;
3410+
3411+ assert_eq ! ( a. remove_opt( 0 ) , None ) ;
3412+ assert_eq ! ( a. remove_opt( 10 ) , None ) ;
3413+ }
3414+
33833415 #[ test]
33843416 fn test_remove ( ) {
33853417 let mut a = ~[ 1 , 2 , 3 , 4 ] ;
@@ -4092,6 +4124,7 @@ mod bench {
40924124 use vec:: VectorVector ;
40934125 use option:: * ;
40944126 use ptr;
4127+ use rand:: { weak_rng, Rng } ;
40954128
40964129 #[ bench]
40974130 fn iterator ( bh : & mut BenchHarness ) {
@@ -4268,4 +4301,28 @@ mod bench {
42684301 }
42694302 } ) ;
42704303 }
4304+
4305+ #[ bench]
4306+ fn random_inserts ( bh : & mut BenchHarness ) {
4307+ let mut rng = weak_rng ( ) ;
4308+ bh. iter ( || {
4309+ let mut v = vec:: from_elem ( 30 , ( 0 u, 0 u) ) ;
4310+ for _ in range ( 0 , 100 ) {
4311+ let l = v. len ( ) ;
4312+ v. insert ( rng. gen :: < uint > ( ) % ( l + 1 ) ,
4313+ ( 1 , 1 ) ) ;
4314+ }
4315+ } )
4316+ }
4317+ #[ bench]
4318+ fn random_removes ( bh : & mut BenchHarness ) {
4319+ let mut rng = weak_rng ( ) ;
4320+ bh. iter ( || {
4321+ let mut v = vec:: from_elem ( 130 , ( 0 u, 0 u) ) ;
4322+ for _ in range ( 0 , 100 ) {
4323+ let l = v. len ( ) ;
4324+ v. remove ( rng. gen :: < uint > ( ) % l) ;
4325+ }
4326+ } )
4327+ }
42714328}
0 commit comments