@@ -510,7 +510,9 @@ fn consume_mut<T>(+v: ~[mut T], f: fn(uint, +T)) unsafe {
510
510
/// Remove the last element from a vector and return it
511
511
fn pop < T > ( & v: ~[ const T ] ) -> T {
512
512
let ln = len ( v) ;
513
- assert ln > 0 u;
513
+ if ln == 0 {
514
+ fail ~"sorry, cannot vec:: pop an empty vector"
515
+ }
514
516
let valptr = ptr:: mut_addr_of ( v[ ln - 1 u] ) ;
515
517
unsafe {
516
518
let val <- * valptr;
@@ -519,6 +521,29 @@ fn pop<T>(&v: ~[const T]) -> T {
519
521
}
520
522
}
521
523
524
+ /**
525
+ * Remove an element from anywhere in the vector and return it, replacing it
526
+ * with the last element. This does not preserve ordering, but is O(1).
527
+ *
528
+ * Fails if index >= length.
529
+ */
530
+ fn swap_remove < T > ( & v : ~[ const T ] , index : uint ) -> T {
531
+ let ln = len ( v ) ;
532
+ if index >= ln {
533
+ fail #fmt ( "vec::swap_remove - index %u >= length %u" , index , ln ) ;
534
+ }
535
+ let lastptr = ptr:: mut_addr_of ( v[ ln - 1 ] ) ;
536
+ unsafe {
537
+ let mut val <- * lastptr;
538
+ if index < ln - 1 {
539
+ let valptr = ptr:: mut_addr_of ( v[ index] ) ;
540
+ * valptr <-> val;
541
+ }
542
+ unsafe:: set_len ( v, ln - 1 ) ;
543
+ val
544
+ }
545
+ }
546
+
522
547
/// Append an element to a vector
523
548
#[ inline( always) ]
524
549
fn push < T > ( & v: ~[ const T ] , +initval : T ) {
@@ -1935,6 +1960,34 @@ mod tests {
1935
1960
assert ( e == 5 ) ;
1936
1961
}
1937
1962
1963
+ #[ test]
1964
+ fn test_swap_remove ( ) {
1965
+ let mut v = ~[ 1 , 2 , 3 , 4 , 5 ] ;
1966
+ let mut e = swap_remove ( v, 0 ) ;
1967
+ assert ( len ( v) == 4 ) ;
1968
+ assert e == 1 ;
1969
+ assert ( v[ 0 ] == 5 ) ;
1970
+ e = swap_remove ( v, 3 ) ;
1971
+ assert ( len ( v) == 3 ) ;
1972
+ assert e == 4 ;
1973
+ assert ( v[ 0 ] == 5 ) ;
1974
+ assert ( v[ 1 ] == 2 ) ;
1975
+ assert ( v[ 2 ] == 3 ) ;
1976
+ }
1977
+
1978
+ #[ test]
1979
+ fn test_swap_remove_noncopyable ( ) {
1980
+ // Tests that we don't accidentally run destructors twice.
1981
+ let mut v = ~[ :: unsafe:: exclusive ( ( ) ) , :: unsafe:: exclusive ( ( ) ) ,
1982
+ :: unsafe:: exclusive ( ( ) ) ] ;
1983
+ let mut _e = swap_remove ( v, 0 ) ;
1984
+ assert ( len ( v) == 2 ) ;
1985
+ _e = swap_remove ( v, 1 ) ;
1986
+ assert ( len ( v) == 1 ) ;
1987
+ _e = swap_remove ( v, 0 ) ;
1988
+ assert ( len ( v) == 0 ) ;
1989
+ }
1990
+
1938
1991
#[ test]
1939
1992
fn test_push ( ) {
1940
1993
// Test on-stack push().
0 commit comments