@@ -1416,6 +1416,22 @@ pub trait OwnedVector<T> {
1416
1416
/// elements after position i one position to the right.
1417
1417
fn insert ( & mut self , i : uint , x : T ) ;
1418
1418
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
+
1419
1435
/// Remove and return the element at position i within v, shifting
1420
1436
/// all elements after position i one position to the left.
1421
1437
fn remove ( & mut self , i : uint ) -> T ;
@@ -1625,39 +1641,7 @@ impl<T> OwnedVector<T> for ~[T] {
1625
1641
}
1626
1642
1627
1643
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 )
1661
1645
}
1662
1646
1663
1647
fn unshift ( & mut self , x : T ) {
@@ -1683,16 +1667,33 @@ impl<T> OwnedVector<T> for ~[T] {
1683
1667
}
1684
1668
}
1685
1669
1670
+ #[ inline]
1686
1671
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 > {
1687
1679
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 ) ;
1689
1691
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
1694
1696
}
1695
- self . pop ( )
1696
1697
}
1697
1698
fn swap_remove ( & mut self , index : uint ) -> T {
1698
1699
let ln = self . len ( ) ;
@@ -3422,6 +3423,29 @@ mod tests {
3422
3423
a. insert ( 4 , 5 ) ;
3423
3424
}
3424
3425
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
+
3425
3449
#[ test]
3426
3450
fn test_remove ( ) {
3427
3451
let mut a = ~[ 1 , 2 , 3 , 4 ] ;
@@ -4342,4 +4366,15 @@ mod bench {
4342
4366
}
4343
4367
} )
4344
4368
}
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
+ }
4345
4380
}
0 commit comments