@@ -102,20 +102,21 @@ There are a number of free functions that create or take vectors, for example:
102
102
#[ warn( non_camel_case_types) ] ;
103
103
104
104
use cast;
105
+ use ops:: Drop ;
105
106
use clone:: { Clone , DeepClone } ;
106
107
use container:: { Container , Mutable } ;
107
108
use cmp:: { Eq , TotalOrd , Ordering , Less , Equal , Greater } ;
108
109
use cmp;
109
110
use default:: Default ;
110
111
use iter:: * ;
111
- use libc:: c_void;
112
+ use libc:: { c_char , c_void} ;
112
113
use num:: { Integer , CheckedAdd , Saturating } ;
113
114
use option:: { None , Option , Some } ;
114
115
use ptr:: to_unsafe_ptr;
115
116
use ptr;
116
117
use ptr:: RawPtr ;
117
- use rt:: global_heap:: malloc_raw;
118
- use rt:: global_heap :: realloc_raw ;
118
+ use rt:: global_heap:: { malloc_raw, realloc_raw , exchange_free } ;
119
+ use rt:: local_heap :: local_free ;
119
120
use mem;
120
121
use mem:: size_of;
121
122
use uint;
@@ -1325,9 +1326,6 @@ pub trait OwnedVector<T> {
1325
1326
/// value out of the vector (from start to end). The vector cannot
1326
1327
/// be used after calling this.
1327
1328
///
1328
- /// Note that this performs O(n) swaps, and so `move_rev_iter`
1329
- /// (which just calls `pop` repeatedly) is more efficient.
1330
- ///
1331
1329
/// # Examples
1332
1330
///
1333
1331
/// ```rust
@@ -1339,8 +1337,7 @@ pub trait OwnedVector<T> {
1339
1337
/// ```
1340
1338
fn move_iter ( self ) -> MoveIterator < T > ;
1341
1339
/// Creates a consuming iterator that moves out of the vector in
1342
- /// reverse order. Also see `move_iter`, however note that this
1343
- /// is more efficient.
1340
+ /// reverse order.
1344
1341
fn move_rev_iter ( self ) -> MoveRevIterator < T > ;
1345
1342
1346
1343
/**
@@ -1469,11 +1466,18 @@ pub trait OwnedVector<T> {
1469
1466
}
1470
1467
1471
1468
impl < T > OwnedVector < T > for ~[ T ] {
1469
+ #[ inline]
1472
1470
fn move_iter ( self ) -> MoveIterator < T > {
1473
- MoveIterator { v : self , idx : 0 }
1471
+ unsafe {
1472
+ let iter = cast:: transmute ( self . iter ( ) ) ;
1473
+ let ptr = cast:: transmute ( self ) ;
1474
+ MoveIterator { allocation : ptr, iter : iter }
1475
+ }
1474
1476
}
1477
+
1478
+ #[ inline]
1475
1479
fn move_rev_iter ( self ) -> MoveRevIterator < T > {
1476
- MoveRevIterator { v : self }
1480
+ self . move_iter ( ) . invert ( )
1477
1481
}
1478
1482
1479
1483
fn reserve ( & mut self , n : uint ) {
@@ -2660,58 +2664,54 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunkIter<'a, T> {
2660
2664
}
2661
2665
2662
2666
/// An iterator that moves out of a vector.
2663
- #[ deriving( Clone ) ]
2664
2667
pub struct MoveIterator < T > {
2665
- priv v : ~ [ T ] ,
2666
- priv idx : uint ,
2668
+ priv allocation : * mut u8 , // the block of memory allocated for the vector
2669
+ priv iter : VecIterator < ' static , T >
2667
2670
}
2668
2671
2669
2672
impl < T > Iterator < T > for MoveIterator < T > {
2670
2673
#[ inline]
2671
2674
fn next ( & mut self ) -> Option < T > {
2672
- // this is peculiar, but is required for safety with respect
2673
- // to dtors. It traverses the first half of the vec, and
2674
- // removes them by swapping them with the last element (and
2675
- // popping), which results in the second half in reverse
2676
- // order, and so these can just be pop'd off. That is,
2677
- //
2678
- // [1,2,3,4,5] => 1, [5,2,3,4] => 2, [5,4,3] => 3, [5,4] => 4,
2679
- // [5] -> 5, []
2680
- let l = self . v . len ( ) ;
2681
- if self . idx < l {
2682
- self . v . swap ( self . idx , l - 1 ) ;
2683
- self . idx += 1 ;
2675
+ unsafe {
2676
+ self . iter . next ( ) . map ( |x| ptr:: read_ptr ( x) )
2684
2677
}
2685
-
2686
- self . v . pop_opt ( )
2687
2678
}
2688
2679
2689
2680
#[ inline]
2690
2681
fn size_hint ( & self ) -> ( uint , Option < uint > ) {
2691
- let l = self . v . len ( ) ;
2692
- ( l, Some ( l) )
2682
+ self . iter . size_hint ( )
2693
2683
}
2694
2684
}
2695
2685
2696
- /// An iterator that moves out of a vector in reverse order.
2697
- #[ deriving( Clone ) ]
2698
- pub struct MoveRevIterator < T > {
2699
- priv v: ~[ T ]
2700
- }
2701
-
2702
- impl < T > Iterator < T > for MoveRevIterator < T > {
2686
+ impl < T > DoubleEndedIterator < T > for MoveIterator < T > {
2703
2687
#[ inline]
2704
- fn next ( & mut self ) -> Option < T > {
2705
- self . v . pop_opt ( )
2688
+ fn next_back ( & mut self ) -> Option < T > {
2689
+ unsafe {
2690
+ self . iter . next_back ( ) . map ( |x| ptr:: read_ptr ( x) )
2691
+ }
2706
2692
}
2693
+ }
2707
2694
2708
- #[ inline]
2709
- fn size_hint ( & self ) -> ( uint , Option < uint > ) {
2710
- let l = self . v . len ( ) ;
2711
- ( l, Some ( l) )
2695
+ #[ unsafe_destructor]
2696
+ impl < T > Drop for MoveIterator < T > {
2697
+ fn drop ( & mut self ) {
2698
+ unsafe {
2699
+ // destroy the remaining elements
2700
+ for x in self . iter {
2701
+ ptr:: read_ptr ( x) ;
2702
+ }
2703
+ if owns_managed :: < T > ( ) {
2704
+ local_free ( self . allocation as * u8 as * c_char )
2705
+ } else {
2706
+ exchange_free ( self . allocation as * u8 as * c_char )
2707
+ }
2708
+ }
2712
2709
}
2713
2710
}
2714
2711
2712
+ /// An iterator that moves out of a vector in reverse order.
2713
+ pub type MoveRevIterator < T > = Invert < MoveIterator < T > > ;
2714
+
2715
2715
impl < A > FromIterator < A > for ~[ A ] {
2716
2716
fn from_iterator < T : Iterator < A > > ( iterator : & mut T ) -> ~[ A ] {
2717
2717
let ( lower, _) = iterator. size_hint ( ) ;
0 commit comments