@@ -204,10 +204,8 @@ pub struct ValueIterMut<'a, T: 'a> {
204
204
/// An drain iterator of all values associated with a single header name.
205
205
#[ derive( Debug ) ]
206
206
pub struct ValueDrain < ' a , T : ' a > {
207
- raw_links : RawLinks < T > ,
208
- extra_values : * mut Vec < ExtraValue < T > > ,
209
207
first : Option < T > ,
210
- next : Option < usize > ,
208
+ next : Option < :: std :: vec :: IntoIter < T > > ,
211
209
lt : PhantomData < & ' a mut HeaderMap < T > > ,
212
210
}
213
211
@@ -1163,13 +1161,16 @@ impl<T> HeaderMap<T> {
1163
1161
}
1164
1162
1165
1163
let raw_links = self . raw_links ( ) ;
1166
- let extra_values = & mut self . extra_values as * mut _ ;
1164
+ let extra_values = & mut self . extra_values ;
1165
+
1166
+ let next = links. map ( |l| {
1167
+ drain_all_extra_values ( raw_links, extra_values, l. next )
1168
+ . into_iter ( )
1169
+ } ) ;
1167
1170
1168
1171
ValueDrain {
1169
- raw_links,
1170
- extra_values,
1171
1172
first : Some ( old) ,
1172
- next : links . map ( |l| l . next ) ,
1173
+ next : next,
1173
1174
lt : PhantomData ,
1174
1175
}
1175
1176
}
@@ -1670,6 +1671,22 @@ fn remove_extra_value<T>(mut raw_links: RawLinks<T>, extra_values: &mut Vec<Extr
1670
1671
extra
1671
1672
}
1672
1673
1674
+
1675
+ fn drain_all_extra_values < T > ( raw_links : RawLinks < T > , extra_values : & mut Vec < ExtraValue < T > > , mut head : usize ) -> Vec < T > {
1676
+ let mut vec = Vec :: new ( ) ;
1677
+ loop {
1678
+ let extra = remove_extra_value ( raw_links, extra_values, head) ;
1679
+ vec. push ( extra. value ) ;
1680
+
1681
+ if let Link :: Extra ( idx) = extra. next {
1682
+ head = idx;
1683
+ } else {
1684
+ break ;
1685
+ }
1686
+ }
1687
+ vec
1688
+ }
1689
+
1673
1690
impl < ' a , T > IntoIterator for & ' a HeaderMap < T > {
1674
1691
type Item = ( & ' a HeaderName , & ' a T ) ;
1675
1692
type IntoIter = Iter < ' a , T > ;
@@ -2154,17 +2171,17 @@ impl<'a, T> Iterator for Drain<'a, T> {
2154
2171
// Read the header name
2155
2172
key = ptr:: read ( & entry. key as * const _ ) ;
2156
2173
value = ptr:: read ( & entry. value as * const _ ) ;
2157
- next = entry. links . map ( |l| l. next ) ;
2158
-
2159
2174
2160
2175
let raw_links = RawLinks ( self . entries ) ;
2161
- let extra_values = self . extra_values ;
2176
+ let extra_values = & mut * self . extra_values ;
2177
+ next = entry. links . map ( |l| {
2178
+ drain_all_extra_values ( raw_links, extra_values, l. next )
2179
+ . into_iter ( )
2180
+ } ) ;
2162
2181
2163
2182
ValueDrain {
2164
- raw_links,
2165
- extra_values,
2166
2183
first : Some ( value) ,
2167
- next : next ,
2184
+ next,
2168
2185
lt : PhantomData ,
2169
2186
}
2170
2187
} ;
@@ -2898,12 +2915,15 @@ impl<'a, T> OccupiedEntry<'a, T> {
2898
2915
pub fn remove_entry_mult ( self ) -> ( HeaderName , ValueDrain < ' a , T > ) {
2899
2916
let entry = self . map . remove_found ( self . probe , self . index ) ;
2900
2917
let raw_links = self . map . raw_links ( ) ;
2901
- let extra_values = & mut self . map . extra_values as * mut _ ;
2918
+ let extra_values = & mut self . map . extra_values ;
2919
+
2920
+ let next = entry. links . map ( |l| {
2921
+ drain_all_extra_values ( raw_links, extra_values, l. next )
2922
+ . into_iter ( )
2923
+ } ) ;
2902
2924
let drain = ValueDrain {
2903
- raw_links,
2904
- extra_values,
2905
2925
first : Some ( entry. value ) ,
2906
- next : entry . links . map ( |l| l . next ) ,
2926
+ next,
2907
2927
lt : PhantomData ,
2908
2928
} ;
2909
2929
( entry. key , drain)
@@ -2996,31 +3016,26 @@ impl<'a, T> Iterator for ValueDrain<'a, T> {
2996
3016
fn next ( & mut self ) -> Option < T > {
2997
3017
if self . first . is_some ( ) {
2998
3018
self . first . take ( )
2999
- } else if let Some ( next) = self . next {
3000
- // Remove the extra value
3001
- let extra = unsafe {
3002
- remove_extra_value ( self . raw_links , & mut * self . extra_values , next)
3003
- } ;
3004
-
3005
- match extra. next {
3006
- Link :: Extra ( idx) => self . next = Some ( idx) ,
3007
- Link :: Entry ( _) => self . next = None ,
3008
- }
3009
-
3010
- Some ( extra. value )
3019
+ } else if let Some ( ref mut extras) = self . next {
3020
+ extras. next ( )
3011
3021
} else {
3012
3022
None
3013
3023
}
3014
3024
}
3015
3025
3016
3026
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3017
- match ( & self . first , self . next ) {
3027
+ match ( & self . first , & self . next ) {
3018
3028
// Exactly 1
3019
- ( & Some ( _) , None ) => ( 1 , Some ( 1 ) ) ,
3020
- // At least 1
3021
- ( & _, Some ( _) ) => ( 1 , None ) ,
3029
+ ( & Some ( _) , & None ) => ( 1 , Some ( 1 ) ) ,
3030
+ // 1 + extras
3031
+ ( & Some ( _) , & Some ( ref extras) ) => {
3032
+ let ( l, u) = extras. size_hint ( ) ;
3033
+ ( l + 1 , u. map ( |u| u + 1 ) )
3034
+ } ,
3035
+ // Extras only
3036
+ ( & None , & Some ( ref extras) ) => extras. size_hint ( ) ,
3022
3037
// No more
3023
- ( & None , None ) => ( 0 , Some ( 0 ) ) ,
3038
+ ( & None , & None ) => ( 0 , Some ( 0 ) ) ,
3024
3039
}
3025
3040
}
3026
3041
}
0 commit comments