3
3
// We use this mainly to skip repeated `/`. If there is only one slash, `memrnchr` performs the same
4
4
// as a naive version (e.g. `rposition`). However, it is much faster in pathological cases.
5
5
6
- #[ cfg( target_pointer_width = "32" ) ]
7
- const USIZE_BYTES : usize = 4 ;
8
- #[ cfg( target_pointer_width = "64" ) ]
9
- const USIZE_BYTES : usize = 8 ;
6
+ use std:: mem:: size_of;
10
7
11
8
// Returns the byte offset of the last byte that is NOT equal to the given one.
12
9
#[ inline( always) ]
@@ -21,12 +18,11 @@ pub fn memrnchr(x: u8, text: &[u8]) -> Option<usize> {
21
18
let ptr = text. as_ptr ( ) ;
22
19
23
20
// search to an aligned boundary
24
- let end_align = ( ptr as usize + len) & ( USIZE_BYTES - 1 ) ;
21
+ let end_align = ( ptr as usize + len) & ( size_of :: < usize > ( ) - 1 ) ;
25
22
let mut offset;
26
23
if end_align > 0 {
27
24
offset = if end_align >= len { 0 } else { len - end_align } ;
28
- let pos = text[ offset..] . iter ( ) . rposition ( |elt| * elt != x) ;
29
- if let Some ( index) = pos {
25
+ if let Some ( index) = memrnchr_naive ( x, & text[ offset..] ) {
30
26
return Some ( offset + index) ;
31
27
}
32
28
} else {
@@ -35,23 +31,25 @@ pub fn memrnchr(x: u8, text: &[u8]) -> Option<usize> {
35
31
36
32
// search the body of the text
37
33
let repeated_x = repeat_byte ( x) ;
38
-
39
- while offset >= 2 * USIZE_BYTES {
40
- debug_assert_eq ! ( ( ptr as usize + offset) % USIZE_BYTES , 0 ) ;
34
+ while offset >= 2 * size_of :: < usize > ( ) {
35
+ debug_assert_eq ! ( ( ptr as usize + offset) % size_of:: <usize >( ) , 0 ) ;
41
36
unsafe {
42
- let u = * ( ptr. offset ( offset as isize - 2 * USIZE_BYTES as isize ) as * const usize ) ;
43
- let v = * ( ptr. offset ( offset as isize - USIZE_BYTES as isize ) as * const usize ) ;
44
-
45
- // break if there is no matching byte
37
+ let u = * ( ptr. offset ( offset as isize - 2 * size_of :: < usize > ( ) as isize ) as * const usize ) ;
38
+ let v = * ( ptr. offset ( offset as isize - size_of :: < usize > ( ) as isize ) as * const usize ) ;
46
39
if u & repeated_x != usize:: max_value ( ) || v & repeated_x != usize:: max_value ( ) {
47
40
break ;
48
41
}
49
42
}
50
- offset -= 2 * USIZE_BYTES ;
43
+ offset -= 2 * size_of :: < usize > ( ) ;
51
44
}
52
45
53
46
// find the byte before the point the body loop stopped
54
- text[ ..offset] . iter ( ) . rposition ( |elt| * elt != x)
47
+ memrnchr_naive ( x, & text[ ..offset] )
48
+ }
49
+
50
+ #[ inline( always) ]
51
+ fn memrnchr_naive ( x : u8 , text : & [ u8 ] ) -> Option < usize > {
52
+ text. iter ( ) . rposition ( |c| * c != x)
55
53
}
56
54
57
55
#[ cfg( target_pointer_width = "32" ) ]
0 commit comments