1#![cfg_attr(not(feature = "use_std"), no_std)]
24
25#![deny(missing_docs)]
26#![doc(html_root_url = "https://docs.rs/memchr/2.0.0")]
27
28#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
31compile_error!("memchr currently not supported on non-32 or non-64 bit");
32
33#[cfg(feature = "use_std")]
34extern crate core;
35
36#[cfg(test)]
37#[macro_use]
38extern crate quickcheck;
39
40use core::iter::Rev;
41
42pub use iter::{Memchr, Memchr2, Memchr3};
43
44#[cfg(memchr_libc)]
46mod c;
47#[allow(dead_code)]
48mod fallback;
49mod iter;
50mod naive;
51#[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
52mod x86;
53#[cfg(test)]
54mod tests;
55
56#[inline]
58pub fn memchr_iter(needle: u8, haystack: &[u8]) -> Memchr {
59 Memchr::new(needle, haystack)
60}
61
62#[inline]
64pub fn memchr2_iter(
65 needle1: u8,
66 needle2: u8,
67 haystack: &[u8],
68) -> Memchr2 {
69 Memchr2::new(needle1, needle2, haystack)
70}
71
72#[inline]
74pub fn memchr3_iter(
75 needle1: u8,
76 needle2: u8,
77 needle3: u8,
78 haystack: &[u8],
79) -> Memchr3 {
80 Memchr3::new(needle1, needle2, needle3, haystack)
81}
82
83#[inline]
85pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev<Memchr> {
86 Memchr::new(needle, haystack).rev()
87}
88
89#[inline]
91pub fn memrchr2_iter(
92 needle1: u8,
93 needle2: u8,
94 haystack: &[u8],
95) -> Rev<Memchr2> {
96 Memchr2::new(needle1, needle2, haystack).rev()
97}
98
99#[inline]
101pub fn memrchr3_iter(
102 needle1: u8,
103 needle2: u8,
104 needle3: u8,
105 haystack: &[u8],
106) -> Rev<Memchr3> {
107 Memchr3::new(needle1, needle2, needle3, haystack).rev()
108}
109
110#[inline]
131pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
132 #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
133 #[inline(always)]
134 fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
135 x86::memchr(n1, haystack)
136 }
137
138 #[cfg(all(
139 memchr_libc,
140 not(all(target_arch = "x86_64", memchr_runtime_simd))
141 ))]
142 #[inline(always)]
143 fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
144 c::memchr(n1, haystack)
145 }
146
147 #[cfg(all(
148 not(memchr_libc),
149 not(all(target_arch = "x86_64", memchr_runtime_simd))
150 ))]
151 #[inline(always)]
152 fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
153 fallback::memchr(n1, haystack)
154 }
155
156 if haystack.is_empty() {
157 None
158 } else {
159 imp(needle, haystack)
160 }
161}
162
163#[inline]
165pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
166 #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
167 #[inline(always)]
168 fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
169 x86::memchr2(n1, n2, haystack)
170 }
171
172 #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
173 #[inline(always)]
174 fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
175 fallback::memchr2(n1, n2, haystack)
176 }
177
178 if haystack.is_empty() {
179 None
180 } else {
181 imp(needle1, needle2, haystack)
182 }
183}
184
185#[inline]
187pub fn memchr3(
188 needle1: u8,
189 needle2: u8,
190 needle3: u8,
191 haystack: &[u8],
192) -> Option<usize> {
193 #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
194 #[inline(always)]
195 fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
196 x86::memchr3(n1, n2, n3, haystack)
197 }
198
199 #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
200 #[inline(always)]
201 fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
202 fallback::memchr3(n1, n2, n3, haystack)
203 }
204
205 if haystack.is_empty() {
206 None
207 } else {
208 imp(needle1, needle2, needle3, haystack)
209 }
210}
211
212#[inline]
233pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
234 #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
235 #[inline(always)]
236 fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
237 x86::memrchr(n1, haystack)
238 }
239
240 #[cfg(all(
241 all(memchr_libc, target_os = "linux"),
242 not(all(target_arch = "x86_64", memchr_runtime_simd))
243 ))]
244 #[inline(always)]
245 fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
246 c::memrchr(n1, haystack)
247 }
248
249 #[cfg(all(
250 not(all(memchr_libc, target_os = "linux")),
251 not(all(target_arch = "x86_64", memchr_runtime_simd))
252 ))]
253 #[inline(always)]
254 fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
255 fallback::memrchr(n1, haystack)
256 }
257
258 if haystack.is_empty() {
259 None
260 } else {
261 imp(needle, haystack)
262 }
263}
264
265#[inline]
267pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
268 #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
269 #[inline(always)]
270 fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
271 x86::memrchr2(n1, n2, haystack)
272 }
273
274 #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
275 #[inline(always)]
276 fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
277 fallback::memrchr2(n1, n2, haystack)
278 }
279
280 if haystack.is_empty() {
281 None
282 } else {
283 imp(needle1, needle2, haystack)
284 }
285}
286
287#[inline]
289pub fn memrchr3(
290 needle1: u8,
291 needle2: u8,
292 needle3: u8,
293 haystack: &[u8],
294) -> Option<usize> {
295 #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
296 #[inline(always)]
297 fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
298 x86::memrchr3(n1, n2, n3, haystack)
299 }
300
301 #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))]
302 #[inline(always)]
303 fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
304 fallback::memrchr3(n1, n2, n3, haystack)
305 }
306
307 if haystack.is_empty() {
308 None
309 } else {
310 imp(needle1, needle2, needle3, haystack)
311 }
312}