@@ -1416,6 +1416,22 @@ pub trait OwnedVector<T> {
14161416 /// elements after position i one position to the right.
14171417 fn insert ( & mut self , i : uint , x : T ) ;
14181418
1419+ /// Remove and return the element at position `i` within `v`,
1420+ /// shifting all elements after position `i` one position to the
1421+ /// left. Returns `None` if `i` is out of bounds.
1422+ ///
1423+ /// # Example
1424+ /// ```rust
1425+ /// let mut v = ~[1, 2, 3];
1426+ /// assert_eq!(v.remove_opt(1), Some(2));
1427+ /// assert_eq!(v, ~[1, 3]);
1428+ ///
1429+ /// assert_eq!(v.remove_opt(4), None);
1430+ /// // v is unchanged:
1431+ /// assert_eq!(v, ~[1, 3]);
1432+ /// ```
1433+ fn remove_opt ( & mut self , i : uint ) -> Option < T > ;
1434+
14191435 /// Remove and return the element at position i within v, shifting
14201436 /// all elements after position i one position to the left.
14211437 fn remove ( & mut self , i : uint ) -> T ;
@@ -1625,39 +1641,7 @@ impl<T> OwnedVector<T> for ~[T] {
16251641 }
16261642
16271643 fn shift_opt ( & mut self ) -> Option < T > {
1628- match self . len ( ) {
1629- 0 => None ,
1630- 1 => self . pop_opt ( ) ,
1631- 2 => {
1632- let last = self . pop ( ) ;
1633- let first = self . pop_opt ( ) ;
1634- self . push ( last) ;
1635- first
1636- }
1637- len => {
1638- unsafe {
1639- let next_len = len - 1 ;
1640-
1641- let ptr = self . as_ptr ( ) ;
1642-
1643- // copy out the head element, for the moment it exists
1644- // unsafely on the stack and as the first element of the
1645- // vector.
1646- let head = ptr:: read_ptr ( ptr) ;
1647-
1648- // Memcpy everything to the left one element (leaving the
1649- // last element unsafely in two consecutive memory
1650- // locations)
1651- ptr:: copy_memory ( self . as_mut_ptr ( ) , ptr. offset ( 1 ) , next_len) ;
1652-
1653- // set the new length, which means the second instance of
1654- // the last element is forgotten.
1655- self . set_len ( next_len) ;
1656-
1657- Some ( head)
1658- }
1659- }
1660- }
1644+ self . remove_opt ( 0 )
16611645 }
16621646
16631647 fn unshift ( & mut self , x : T ) {
@@ -1683,16 +1667,33 @@ impl<T> OwnedVector<T> for ~[T] {
16831667 }
16841668 }
16851669
1670+ #[ inline]
16861671 fn remove ( & mut self , i : uint ) -> T {
1672+ match self . remove_opt ( i) {
1673+ Some ( t) => t,
1674+ None => fail ! ( "remove: the len is {} but the index is {}" , self . len( ) , i)
1675+ }
1676+ }
1677+
1678+ fn remove_opt ( & mut self , i : uint ) -> Option < T > {
16871679 let len = self . len ( ) ;
1688- assert ! ( i < len) ;
1680+ if i < len {
1681+ unsafe { // infallible
1682+ // the place we are taking from.
1683+ let ptr = self . as_mut_ptr ( ) . offset ( i as int ) ;
1684+ // copy it out, unsafely having a copy of the value on
1685+ // the stack and in the vector at the same time.
1686+ let ret = Some ( ptr:: read_ptr ( ptr as * T ) ) ;
1687+
1688+ // Shift everything down to fill in that spot.
1689+ ptr:: copy_memory ( ptr, ptr. offset ( 1 ) , len - i - 1 ) ;
1690+ self . set_len ( len - 1 ) ;
16891691
1690- let mut j = i ;
1691- while j < len - 1 {
1692- self . swap ( j , j + 1 ) ;
1693- j += 1 ;
1692+ ret
1693+ }
1694+ } else {
1695+ None
16941696 }
1695- self . pop ( )
16961697 }
16971698 fn swap_remove ( & mut self , index : uint ) -> T {
16981699 let ln = self . len ( ) ;
@@ -3422,6 +3423,29 @@ mod tests {
34223423 a. insert ( 4 , 5 ) ;
34233424 }
34243425
3426+ #[ test]
3427+ fn test_remove_opt ( ) {
3428+ let mut a = ~[ 1 , 2 , 3 , 4 ] ;
3429+
3430+ assert_eq ! ( a. remove_opt( 2 ) , Some ( 3 ) ) ;
3431+ assert_eq ! ( a, ~[ 1 , 2 , 4 ] ) ;
3432+
3433+ assert_eq ! ( a. remove_opt( 2 ) , Some ( 4 ) ) ;
3434+ assert_eq ! ( a, ~[ 1 , 2 ] ) ;
3435+
3436+ assert_eq ! ( a. remove_opt( 2 ) , None ) ;
3437+ assert_eq ! ( a, ~[ 1 , 2 ] ) ;
3438+
3439+ assert_eq ! ( a. remove_opt( 0 ) , Some ( 1 ) ) ;
3440+ assert_eq ! ( a, ~[ 2 ] ) ;
3441+
3442+ assert_eq ! ( a. remove_opt( 0 ) , Some ( 2 ) ) ;
3443+ assert_eq ! ( a, ~[ ] ) ;
3444+
3445+ assert_eq ! ( a. remove_opt( 0 ) , None ) ;
3446+ assert_eq ! ( a. remove_opt( 10 ) , None ) ;
3447+ }
3448+
34253449 #[ test]
34263450 fn test_remove ( ) {
34273451 let mut a = ~[ 1 , 2 , 3 , 4 ] ;
@@ -4342,4 +4366,15 @@ mod bench {
43424366 }
43434367 } )
43444368 }
4369+ #[ bench]
4370+ fn random_removes ( bh : & mut BenchHarness ) {
4371+ let mut rng = weak_rng ( ) ;
4372+ bh. iter ( || {
4373+ let mut v = vec:: from_elem ( 130 , ( 0 u, 0 u) ) ;
4374+ for _ in range ( 0 , 100 ) {
4375+ let l = v. len ( ) ;
4376+ v. remove ( rng. gen :: < uint > ( ) % l) ;
4377+ }
4378+ } )
4379+ }
43454380}
0 commit comments