@@ -1400,6 +1400,22 @@ pub trait OwnedVector<T> {
1400
1400
/// elements after position i one position to the right.
1401
1401
fn insert ( & mut self , i : uint , x : T ) ;
1402
1402
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
+
1403
1419
/// Remove and return the element at position i within v, shifting
1404
1420
/// all elements after position i one position to the left.
1405
1421
fn remove ( & mut self , i : uint ) -> T ;
@@ -1609,66 +1625,59 @@ impl<T> OwnedVector<T> for ~[T] {
1609
1625
}
1610
1626
1611
1627
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 )
1645
1629
}
1646
1630
1647
1631
fn unshift ( & mut self , x : T ) {
1648
- let v = util:: replace ( self , ~[ x] ) ;
1649
- self . push_all_move ( v) ;
1632
+ self . insert ( 0 , x)
1650
1633
}
1651
- fn insert ( & mut self , i : uint , x : T ) {
1634
+
1635
+ fn insert ( & mut self , i : uint , x : T ) {
1652
1636
let len = self . len ( ) ;
1653
1637
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 ) ;
1660
1651
}
1661
1652
}
1653
+
1654
+ #[ inline]
1662
1655
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 > {
1663
1663
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 ) ;
1665
1675
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
1670
1680
}
1671
- self . pop ( )
1672
1681
}
1673
1682
fn swap_remove ( & mut self , index : uint ) -> T {
1674
1683
let ln = self . len ( ) ;
@@ -3380,6 +3389,29 @@ mod tests {
3380
3389
a. insert ( 4 , 5 ) ;
3381
3390
}
3382
3391
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
+
3383
3415
#[ test]
3384
3416
fn test_remove ( ) {
3385
3417
let mut a = ~[ 1 , 2 , 3 , 4 ] ;
@@ -4092,6 +4124,7 @@ mod bench {
4092
4124
use vec:: VectorVector ;
4093
4125
use option:: * ;
4094
4126
use ptr;
4127
+ use rand:: { weak_rng, Rng } ;
4095
4128
4096
4129
#[ bench]
4097
4130
fn iterator ( bh : & mut BenchHarness ) {
@@ -4268,4 +4301,28 @@ mod bench {
4268
4301
}
4269
4302
} ) ;
4270
4303
}
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
+ }
4271
4328
}
0 commit comments