@@ -1256,16 +1256,15 @@ impl<T> OwnedVector<T> for ~[T] {
1256
1256
/// ~~~
1257
1257
#[ inline]
1258
1258
fn push_all_move( & mut self , mut rhs: ~[ T ] ) {
1259
- let new_len = self . len( ) + rhs. len( ) ;
1259
+ let self_len = self . len( ) ;
1260
+ let rhs_len = rhs. len( ) ;
1261
+ let new_len = self_len + rhs_len;
1260
1262
self . reserve( new_len) ;
1261
- unsafe {
1262
- do rhs. as_mut_buf |p, len| {
1263
- for uint:: range( 0 , len) |i| {
1264
- let x = ptr:: replace_ptr( ptr:: mut_offset( p, i) ,
1265
- intrinsics:: uninit( ) ) ;
1266
- self . push( x) ;
1267
- }
1268
- }
1263
+ unsafe { // Note: infallible.
1264
+ let self_p = vec:: raw :: to_mut_ptr( * self ) ;
1265
+ let rhs_p = vec:: raw :: to_ptr( rhs) ;
1266
+ ptr:: copy_memory( ptr:: mut_offset( self_p, self_len) , rhs_p, rhs_len) ;
1267
+ raw :: set_len( self , new_len) ;
1269
1268
raw :: set_len( & mut rhs, 0 ) ;
1270
1269
}
1271
1270
}
@@ -1277,9 +1276,8 @@ impl<T> OwnedVector<T> for ~[T] {
1277
1276
ln => {
1278
1277
let valptr = ptr:: to_mut_unsafe_ptr( & mut self [ ln - 1 u] ) ;
1279
1278
unsafe {
1280
- let val = ptr:: replace_ptr( valptr, intrinsics:: init( ) ) ;
1281
- raw :: set_len( self , ln - 1 u) ;
1282
- Some ( val)
1279
+ raw :: set_len( v, ln - 1 u) ;
1280
+ ptr:: read_ptr( valptr)
1283
1281
}
1284
1282
}
1285
1283
}
@@ -1410,7 +1408,7 @@ impl<T> OwnedVector<T> for ~[T] {
1410
1408
unsafe {
1411
1409
// This loop is optimized out for non-drop types.
1412
1410
for uint:: range( newlen, oldlen) |i| {
1413
- ptr:: replace_ptr ( ptr:: mut_offset( p, i) , intrinsics :: uninit ( ) ) ;
1411
+ ptr:: read_and_zero_ptr ( ptr:: mut_offset( p, i) )
1414
1412
}
1415
1413
}
1416
1414
}
@@ -1555,37 +1553,93 @@ pub trait OwnedEqVector<T:Eq> {
1555
1553
1556
1554
impl <T : Eq > OwnedEqVector <T > for ~[ T ] {
1557
1555
/**
1558
- * Remove consecutive repeated elements from a vector; if the vector is
1559
- * sorted, this removes all duplicates.
1560
- */
1561
- pub fn dedup( & mut self ) {
1556
+ * Remove consecutive repeated elements from a vector; if the vector is
1557
+ * sorted, this removes all duplicates.
1558
+ */
1559
+ pub fn dedup< T : Eq > ( & mut self ) {
1562
1560
unsafe {
1563
- if self . len( ) == 0 { return ; }
1564
- let mut last_written = 0 ;
1565
- let mut next_to_read = 1 ;
1566
- do self . as_mut_buf |p, ln| {
1567
- // last_written < next_to_read <= ln
1568
- while next_to_read < ln {
1569
- // last_written < next_to_read < ln
1570
- if * ptr:: mut_offset ( p, next_to_read) ==
1571
- * ptr:: mut_offset ( p, last_written) {
1572
- ptr:: replace_ptr ( ptr:: mut_offset ( p, next_to_read) ,
1573
- intrinsics:: uninit ( ) ) ;
1574
- } else {
1575
- last_written += 1 ;
1576
- // last_written <= next_to_read < ln
1577
- if next_to_read != last_written {
1578
- ptr:: swap_ptr ( ptr:: mut_offset ( p, last_written) ,
1579
- ptr:: mut_offset ( p, next_to_read) ) ;
1580
- }
1561
+ // Although we have a mutable reference to `self`, we cannot make
1562
+ // *arbitrary* changes. There exists the possibility that this
1563
+ // vector is contained with an `@mut` box and hence is still
1564
+ // readable by the outside world during the `Eq` comparisons.
1565
+ // Moreover, those comparisons could fail, so we must ensure
1566
+ // that the vector is in a valid state at all time.
1567
+ //
1568
+ // The way that we handle this is by using swaps; we iterate
1569
+ // over all the elements, swapping as we go so that at the end
1570
+ // the elements we wish to keep are in the front, and those we
1571
+ // wish to reject are at the back. We can then truncate the
1572
+ // vector. This operation is still O(n).
1573
+ //
1574
+ // Example: We start in this state, where `r` represents "next
1575
+ // read" and `w` represents "next_write`.
1576
+ //
1577
+ // r
1578
+ // +---+---+---+---+---+---+
1579
+ // | 0 | 1 | 1 | 2 | 3 | 3 |
1580
+ // +---+---+---+---+---+---+
1581
+ // w
1582
+ //
1583
+ // Comparing self[r] against self[w-1], tis is not a duplicate, so
1584
+ // we swap self[r] and self[w] (no effect as r==w) and then increment both
1585
+ // r and w, leaving us with:
1586
+ //
1587
+ // r
1588
+ // +---+---+---+---+---+---+
1589
+ // | 0 | 1 | 1 | 2 | 3 | 3 |
1590
+ // +---+---+---+---+---+---+
1591
+ // w
1592
+ //
1593
+ // Comparing self[r] against self[w-1], this value is a duplicate,
1594
+ // so we increment `r` but leave everything else unchanged:
1595
+ //
1596
+ // r
1597
+ // +---+---+---+---+---+---+
1598
+ // | 0 | 1 | 1 | 2 | 3 | 3 |
1599
+ // +---+---+---+---+---+---+
1600
+ // w
1601
+ //
1602
+ // Comparing self[r] against self[w-1], this is not a duplicate,
1603
+ // so swap self[r] and self[w] and advance r and w:
1604
+ //
1605
+ // r
1606
+ // +---+---+---+---+---+---+
1607
+ // | 0 | 1 | 2 | 1 | 3 | 3 |
1608
+ // +---+---+---+---+---+---+
1609
+ // w
1610
+ //
1611
+ // Not a duplicate, repeat:
1612
+ //
1613
+ // r
1614
+ // +---+---+---+---+---+---+
1615
+ // | 0 | 1 | 2 | 3 | 1 | 3 |
1616
+ // +---+---+---+---+---+---+
1617
+ // w
1618
+ //
1619
+ // Duplicate, advance r. End of vec. Truncate to w.
1620
+
1621
+ let ln = self . len( ) ;
1622
+ if ln < 1 { return ; }
1623
+
1624
+ // Avoid bounds checks by using unsafe pointers.
1625
+ let p = vec:: raw :: to_mut_ptr( * self ) ;
1626
+ let mut r = 1 ;
1627
+ let mut w = 1 ;
1628
+
1629
+ while r < ln {
1630
+ let p_r = ptr:: mut_offset( p, r) ;
1631
+ let p_wm1 = ptr:: mut_offset( p, w - 1 ) ;
1632
+ if * p_r != * p_wm1 {
1633
+ if r != w {
1634
+ let p_w = ptr:: mut_offset( p_wm1, 1 ) ;
1635
+ util:: swap( & mut * p_r, & mut * p_w) ;
1581
1636
}
1582
- // last_written <= next_to_read < ln
1583
- next_to_read += 1 ;
1584
- // last_written < next_to_read <= ln
1637
+ w += 1 ;
1585
1638
}
1639
+ r += 1 ;
1586
1640
}
1587
- // last_written < next_to_read == ln
1588
- raw :: set_len ( self , last_written + 1 ) ;
1641
+
1642
+ self . truncate ( w ) ;
1589
1643
}
1590
1644
}
1591
1645
}
0 commit comments