regex_automata/util/
memchr.rs

1/*!
2This module defines simple wrapper routines for the memchr functions from the
3`memchr` crate. Basically, when the `memchr` crate is available, we use it,
4otherwise we use a naive implementation which is still pretty fast.
5*/
6
7pub(crate) use self::inner::*;
8
9#[cfg(feature = "perf-literal-substring")]
10pub(super) mod inner {
11    #[cfg_attr(feature = "perf-inline", inline(always))]
12    pub(crate) fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
13        memchr::memchr(n1, haystack)
14    }
15
16    #[cfg_attr(feature = "perf-inline", inline(always))]
17    pub(crate) fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
18        memchr::memchr2(n1, n2, haystack)
19    }
20
21    #[cfg_attr(feature = "perf-inline", inline(always))]
22    pub(crate) fn memchr3(
23        n1: u8,
24        n2: u8,
25        n3: u8,
26        haystack: &[u8],
27    ) -> Option<usize> {
28        memchr::memchr3(n1, n2, n3, haystack)
29    }
30
31    #[cfg_attr(feature = "perf-inline", inline(always))]
32    pub(crate) fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
33        memchr::memrchr(n1, haystack)
34    }
35
36    #[cfg_attr(feature = "perf-inline", inline(always))]
37    pub(crate) fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
38        memchr::memrchr2(n1, n2, haystack)
39    }
40
41    #[cfg_attr(feature = "perf-inline", inline(always))]
42    pub(crate) fn memrchr3(
43        n1: u8,
44        n2: u8,
45        n3: u8,
46        haystack: &[u8],
47    ) -> Option<usize> {
48        memchr::memrchr3(n1, n2, n3, haystack)
49    }
50}
51
52#[cfg(not(feature = "perf-literal-substring"))]
53pub(super) mod inner {
54    #[cfg_attr(feature = "perf-inline", inline(always))]
55    pub(crate) fn memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
56        haystack.iter().position(|&b| b == n1)
57    }
58
59    #[cfg_attr(feature = "perf-inline", inline(always))]
60    pub(crate) fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
61        haystack.iter().position(|&b| b == n1 || b == n2)
62    }
63
64    #[cfg_attr(feature = "perf-inline", inline(always))]
65    pub(crate) fn memchr3(
66        n1: u8,
67        n2: u8,
68        n3: u8,
69        haystack: &[u8],
70    ) -> Option<usize> {
71        haystack.iter().position(|&b| b == n1 || b == n2 || b == n3)
72    }
73
74    #[cfg_attr(feature = "perf-inline", inline(always))]
75    pub(crate) fn memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
76        haystack.iter().rposition(|&b| b == n1)
77    }
78
79    #[cfg_attr(feature = "perf-inline", inline(always))]
80    pub(crate) fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
81        haystack.iter().rposition(|&b| b == n1 || b == n2)
82    }
83
84    #[cfg_attr(feature = "perf-inline", inline(always))]
85    pub(crate) fn memrchr3(
86        n1: u8,
87        n2: u8,
88        n3: u8,
89        haystack: &[u8],
90    ) -> Option<usize> {
91        haystack.iter().rposition(|&b| b == n1 || b == n2 || b == n3)
92    }
93}