@@ -204,10 +204,8 @@ pub struct ValueIterMut<'a, T: 'a> {
204204/// An drain iterator of all values associated with a single header name.
205205#[ derive( Debug ) ]
206206pub struct ValueDrain < ' a , T : ' a > {
207- raw_links : RawLinks < T > ,
208- extra_values : * mut Vec < ExtraValue < T > > ,
209207 first : Option < T > ,
210- next : Option < usize > ,
208+ next : Option < :: std :: vec :: IntoIter < T > > ,
211209 lt : PhantomData < & ' a mut HeaderMap < T > > ,
212210}
213211
@@ -1163,13 +1161,16 @@ impl<T> HeaderMap<T> {
11631161 }
11641162
11651163 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+ } ) ;
11671170
11681171 ValueDrain {
1169- raw_links,
1170- extra_values,
11711172 first : Some ( old) ,
1172- next : links . map ( |l| l . next ) ,
1173+ next : next,
11731174 lt : PhantomData ,
11741175 }
11751176 }
@@ -1670,6 +1671,22 @@ fn remove_extra_value<T>(mut raw_links: RawLinks<T>, extra_values: &mut Vec<Extr
16701671 extra
16711672}
16721673
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+
16731690impl < ' a , T > IntoIterator for & ' a HeaderMap < T > {
16741691 type Item = ( & ' a HeaderName , & ' a T ) ;
16751692 type IntoIter = Iter < ' a , T > ;
@@ -2154,17 +2171,17 @@ impl<'a, T> Iterator for Drain<'a, T> {
21542171 // Read the header name
21552172 key = ptr:: read ( & entry. key as * const _ ) ;
21562173 value = ptr:: read ( & entry. value as * const _ ) ;
2157- next = entry. links . map ( |l| l. next ) ;
2158-
21592174
21602175 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+ } ) ;
21622181
21632182 ValueDrain {
2164- raw_links,
2165- extra_values,
21662183 first : Some ( value) ,
2167- next : next ,
2184+ next,
21682185 lt : PhantomData ,
21692186 }
21702187 } ;
@@ -2898,12 +2915,15 @@ impl<'a, T> OccupiedEntry<'a, T> {
28982915 pub fn remove_entry_mult ( self ) -> ( HeaderName , ValueDrain < ' a , T > ) {
28992916 let entry = self . map . remove_found ( self . probe , self . index ) ;
29002917 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+ } ) ;
29022924 let drain = ValueDrain {
2903- raw_links,
2904- extra_values,
29052925 first : Some ( entry. value ) ,
2906- next : entry . links . map ( |l| l . next ) ,
2926+ next,
29072927 lt : PhantomData ,
29082928 } ;
29092929 ( entry. key , drain)
@@ -2996,31 +3016,26 @@ impl<'a, T> Iterator for ValueDrain<'a, T> {
29963016 fn next ( & mut self ) -> Option < T > {
29973017 if self . first . is_some ( ) {
29983018 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 ( )
30113021 } else {
30123022 None
30133023 }
30143024 }
30153025
30163026 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3017- match ( & self . first , self . next ) {
3027+ match ( & self . first , & self . next ) {
30183028 // 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 ( ) ,
30223037 // No more
3023- ( & None , None ) => ( 0 , Some ( 0 ) ) ,
3038+ ( & None , & None ) => ( 0 , Some ( 0 ) ) ,
30243039 }
30253040 }
30263041}
0 commit comments