@@ -8,6 +8,7 @@ use crate::iter::{TrustedRandomAccess, TrustedRandomAccessNoCoerce};
8
8
use crate :: ops:: Try ;
9
9
use crate :: option;
10
10
use crate :: slice:: { self , Split as SliceSplit } ;
11
+ use core:: num:: NonZeroUsize ;
11
12
12
13
use super :: from_utf8_unchecked;
13
14
use super :: pattern:: Pattern ;
@@ -49,6 +50,48 @@ impl<'a> Iterator for Chars<'a> {
49
50
super :: count:: count_chars ( self . as_str ( ) )
50
51
}
51
52
53
+ #[ inline]
54
+ fn advance_by ( & mut self , mut remainder : usize ) -> Result < ( ) , NonZeroUsize > {
55
+ const CHUNK_SIZE : usize = 32 ;
56
+
57
+ if remainder >= CHUNK_SIZE {
58
+ let mut chunks = self . iter . as_slice ( ) . array_chunks :: < CHUNK_SIZE > ( ) ;
59
+ let mut bytes_skipped: usize = 0 ;
60
+
61
+ while remainder > CHUNK_SIZE && let Some ( chunk) = chunks. next ( ) {
62
+ bytes_skipped += CHUNK_SIZE ;
63
+
64
+ let mut start_bytes = [ false ; CHUNK_SIZE ] ;
65
+
66
+ for i in 0 ..CHUNK_SIZE {
67
+ start_bytes[ i] = !super :: validations:: utf8_is_cont_byte ( chunk[ i] ) ;
68
+ }
69
+
70
+ remainder -= start_bytes. into_iter ( ) . map ( |i| i as u8 ) . sum :: < u8 > ( ) as usize ;
71
+ }
72
+
73
+ unsafe { self . iter . advance_by ( bytes_skipped) . unwrap_unchecked ( ) } ;
74
+
75
+ // skip trailing continuation bytes
76
+ while self . iter . len ( ) > 0 {
77
+ let b = self . iter . as_slice ( ) [ 0 ] ;
78
+ if !super :: validations:: utf8_is_cont_byte ( b) {
79
+ break
80
+ }
81
+ unsafe { self . iter . advance_by ( 1 ) . unwrap_unchecked ( ) } ;
82
+ }
83
+ }
84
+
85
+ while ( remainder > 0 ) && ( self . iter . len ( ) > 0 ) {
86
+ remainder -= 1 ;
87
+ let b = self . iter . as_slice ( ) [ 0 ] ;
88
+ let slurp = super :: validations:: utf8_char_width ( b) ;
89
+ unsafe { self . iter . advance_by ( slurp) . unwrap_unchecked ( ) } ;
90
+ }
91
+
92
+ NonZeroUsize :: new ( remainder) . map_or ( Ok ( ( ) ) , Err )
93
+ }
94
+
52
95
#[ inline]
53
96
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
54
97
let len = self . iter . len ( ) ;
0 commit comments