@@ -736,6 +736,27 @@ pub pure fn filter<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[T] {
736
736
move result
737
737
}
738
738
739
+ /**
740
+ * Like `filter()`, but in place. Preserves order of `v`. Linear time.
741
+ */
742
+ pub fn retain < T > ( v : & mut ~[ T ] , f : pure fn( t : & T ) -> bool ) {
743
+ let len = v. len ( ) ;
744
+ let mut deleted: uint = 0 ;
745
+
746
+ for uint:: range( 0 , len) |i| {
747
+ if !f ( & v[ i] ) {
748
+ deleted += 1 ;
749
+ } else if deleted > 0 {
750
+ v[ i - deleted] <-> v[ i] ;
751
+ }
752
+ }
753
+
754
+ while deleted > 0 {
755
+ v. pop ( ) ;
756
+ deleted -= 1 ;
757
+ }
758
+ }
759
+
739
760
/**
740
761
* Concatenate a vector of vectors.
741
762
*
@@ -759,14 +780,17 @@ pub pure fn connect<T: Copy>(v: &[~[T]], sep: &T) -> ~[T] {
759
780
}
760
781
761
782
/// Reduce a vector from left to right
762
- pub pure fn foldl < T : Copy , U > ( z : T , v : & [ U ] , p : fn ( t : T , u : & U ) -> T ) -> T {
763
- let mut accum = z;
764
- for each( v) |elt| {
765
- // it should be possible to move accum in, but the liveness analysis
766
- // is not smart enough.
767
- accum = p( accum, elt) ;
783
+ pub pure fn foldl < T , U > ( z : T , v : & [ U ] , p : fn ( t : T , u : & U ) -> T ) -> T {
784
+ let mut accum = move z;
785
+ let mut i = 0 ;
786
+ let l = v. len ( ) ;
787
+ while i < l {
788
+ // Use a while loop so that liveness analysis can handle moving
789
+ // the accumulator.
790
+ accum = p ( move accum, & v[ i] ) ;
791
+ i += 1 ;
768
792
}
769
- return accum;
793
+ return move accum;
770
794
}
771
795
772
796
/// Reduce a vector from right to left
@@ -1293,13 +1317,24 @@ pure fn eq<T: Eq>(a: &[T], b: &[T]) -> bool {
1293
1317
return true ;
1294
1318
}
1295
1319
1320
+ #[ cfg( stage0) ]
1296
1321
impl < T : Eq > & [ T ] : Eq {
1297
1322
#[ inline( always) ]
1298
1323
pure fn eq ( other : & & [ T ] ) -> bool { eq ( self , ( * other) ) }
1299
1324
#[ inline( always) ]
1300
1325
pure fn ne ( other : & & [ T ] ) -> bool { !self . eq ( other) }
1301
1326
}
1302
1327
1328
+ #[ cfg( stage1) ]
1329
+ #[ cfg( stage2) ]
1330
+ impl < T : Eq > & [ T ] : Eq {
1331
+ #[ inline( always) ]
1332
+ pure fn eq ( other : & & self /[ T ] ) -> bool { eq ( self , ( * other) ) }
1333
+ #[ inline( always) ]
1334
+ pure fn ne ( other : & & self /[ T ] ) -> bool { !self . eq ( other) }
1335
+ }
1336
+
1337
+
1303
1338
impl < T : Eq > ~[ T ] : Eq {
1304
1339
#[ inline( always) ]
1305
1340
pure fn eq ( other : & ~[ T ] ) -> bool { eq ( self , ( * other) ) }
@@ -1335,6 +1370,7 @@ pure fn le<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
1335
1370
pure fn ge < T : Ord > ( a : & [ T ] , b : & [ T ] ) -> bool { !lt ( a, b) }
1336
1371
pure fn gt < T : Ord > ( a : & [ T ] , b : & [ T ] ) -> bool { lt ( b, a) }
1337
1372
1373
+ #[ cfg( stage0) ]
1338
1374
impl < T : Ord > & [ T ] : Ord {
1339
1375
#[ inline( always) ]
1340
1376
pure fn lt ( other : & & [ T ] ) -> bool { lt ( self , ( * other) ) }
@@ -1346,6 +1382,19 @@ impl<T: Ord> &[T] : Ord {
1346
1382
pure fn gt ( other : & & [ T ] ) -> bool { gt ( self , ( * other) ) }
1347
1383
}
1348
1384
1385
+ #[ cfg( stage1) ]
1386
+ #[ cfg( stage2) ]
1387
+ impl < T : Ord > & [ T ] : Ord {
1388
+ #[ inline( always) ]
1389
+ pure fn lt ( other : & & self /[ T ] ) -> bool { lt ( self , ( * other) ) }
1390
+ #[ inline( always) ]
1391
+ pure fn le ( other : & & self /[ T ] ) -> bool { le ( self , ( * other) ) }
1392
+ #[ inline( always) ]
1393
+ pure fn ge ( other : & & self /[ T ] ) -> bool { ge ( self , ( * other) ) }
1394
+ #[ inline( always) ]
1395
+ pure fn gt ( other : & & self /[ T ] ) -> bool { gt ( self , ( * other) ) }
1396
+ }
1397
+
1349
1398
impl < T : Ord > ~[ T ] : Ord {
1350
1399
#[ inline( always) ]
1351
1400
pure fn lt ( other : & ~[ T ] ) -> bool { lt ( self , ( * other) ) }
@@ -1370,19 +1419,39 @@ impl<T: Ord> @[T] : Ord {
1370
1419
1371
1420
#[ cfg( notest) ]
1372
1421
pub mod traits {
1422
+ #[ cfg( stage0) ]
1373
1423
impl < T : Copy > ~[ T ] : Add < & [ const T ] , ~[ T ] > {
1374
1424
#[ inline( always) ]
1375
1425
pure fn add ( rhs : & & [ const T ] ) -> ~[ T ] {
1376
1426
append ( copy self, ( * rhs) )
1377
1427
}
1378
1428
}
1379
1429
1430
+ #[ cfg( stage1) ]
1431
+ #[ cfg( stage2) ]
1432
+ impl < T : Copy > ~[ T ] : Add < & [ const T ] , ~[ T ] > {
1433
+ #[ inline( always) ]
1434
+ pure fn add ( rhs : & & self /[ const T ] ) -> ~[ T ] {
1435
+ append ( copy self, ( * rhs) )
1436
+ }
1437
+ }
1438
+
1439
+ #[ cfg( stage0) ]
1380
1440
impl < T : Copy > ~[ mut T ] : Add < & [ const T ] , ~[ mut T ] > {
1381
1441
#[ inline( always) ]
1382
1442
pure fn add ( rhs : & & [ const T ] ) -> ~[ mut T ] {
1383
1443
append_mut ( copy self, ( * rhs) )
1384
1444
}
1385
1445
}
1446
+
1447
+ #[ cfg( stage1) ]
1448
+ #[ cfg( stage2) ]
1449
+ impl < T : Copy > ~[ mut T ] : Add < & [ const T ] , ~[ mut T ] > {
1450
+ #[ inline( always) ]
1451
+ pure fn add ( rhs : & & self /[ const T ] ) -> ~[ mut T ] {
1452
+ append_mut ( copy self, ( * rhs) )
1453
+ }
1454
+ }
1386
1455
}
1387
1456
1388
1457
#[ cfg( test) ]
@@ -1590,6 +1659,7 @@ pub trait MutableVector<T> {
1590
1659
fn unshift ( & mut self , x : T ) ;
1591
1660
fn swap_remove ( & mut self , index : uint ) -> T ;
1592
1661
fn truncate ( & mut self , newlen : uint ) ;
1662
+ fn retain ( & mut self , f : pure fn( t : & T ) -> bool ) ;
1593
1663
}
1594
1664
1595
1665
pub trait MutableCopyableVector < T : Copy > {
@@ -1631,6 +1701,10 @@ impl<T> ~[T]: MutableVector<T> {
1631
1701
fn truncate ( & mut self , newlen : uint ) {
1632
1702
truncate ( self , newlen) ;
1633
1703
}
1704
+
1705
+ fn retain ( & mut self , f : pure fn( t : & T ) -> bool ) {
1706
+ retain ( self , f) ;
1707
+ }
1634
1708
}
1635
1709
1636
1710
impl < T : Copy > ~[ T ] : MutableCopyableVector < T > {
0 commit comments