File tree Expand file tree Collapse file tree 1 file changed +22
-15
lines changed Expand file tree Collapse file tree 1 file changed +22
-15
lines changed Original file line number Diff line number Diff line change @@ -1233,37 +1233,44 @@ impl String {
12331233 where
12341234 F : FnMut ( char ) -> bool ,
12351235 {
1236- let len = self . len ( ) ;
1237- let mut del_bytes = 0 ;
1238- let mut idx = 0 ;
1236+ struct SetLenOnDrop < ' a > {
1237+ s : & ' a mut String ,
1238+ idx : usize ,
1239+ del_bytes : usize ,
1240+ }
12391241
1240- unsafe {
1241- self . vec . set_len ( 0 ) ;
1242+ impl < ' a > Drop for SetLenOnDrop < ' a > {
1243+ fn drop ( & mut self ) {
1244+ let new_len = self . idx - self . del_bytes ;
1245+ debug_assert ! ( new_len <= self . s. len( ) ) ;
1246+ unsafe { self . s . vec . set_len ( new_len) } ;
1247+ }
12421248 }
12431249
1244- while idx < len {
1245- let ch = unsafe { self . get_unchecked ( idx..len) . chars ( ) . next ( ) . unwrap ( ) } ;
1250+ let len = self . len ( ) ;
1251+ let mut guard = SetLenOnDrop { s : self , idx : 0 , del_bytes : 0 } ;
1252+
1253+ while guard. idx < len {
1254+ let ch = unsafe { guard. s . get_unchecked ( guard. idx ..len) . chars ( ) . next ( ) . unwrap ( ) } ;
12461255 let ch_len = ch. len_utf8 ( ) ;
12471256
12481257 if !f ( ch) {
1249- del_bytes += ch_len;
1250- } else if del_bytes > 0 {
1258+ guard . del_bytes += ch_len;
1259+ } else if guard . del_bytes > 0 {
12511260 unsafe {
12521261 ptr:: copy (
1253- self . vec . as_ptr ( ) . add ( idx) ,
1254- self . vec . as_mut_ptr ( ) . add ( idx - del_bytes) ,
1262+ guard . s . vec . as_ptr ( ) . add ( guard . idx ) ,
1263+ guard . s . vec . as_mut_ptr ( ) . add ( guard . idx - guard . del_bytes ) ,
12551264 ch_len,
12561265 ) ;
12571266 }
12581267 }
12591268
12601269 // Point idx to the next char
1261- idx += ch_len;
1270+ guard . idx += ch_len;
12621271 }
12631272
1264- unsafe {
1265- self . vec . set_len ( len - del_bytes) ;
1266- }
1273+ drop ( guard) ;
12671274 }
12681275
12691276 /// Inserts a character into this `String` at a byte position.
You can’t perform that action at this time.
0 commit comments