Coverage Report

Created: 2026-01-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/memchr-2.4.1/src/memchr/mod.rs
Line
Count
Source
1
use core::iter::Rev;
2
3
pub use self::iter::{Memchr, Memchr2, Memchr3};
4
5
// N.B. If you're looking for the cfg knobs for libc, see build.rs.
6
#[cfg(memchr_libc)]
7
mod c;
8
#[allow(dead_code)]
9
pub mod fallback;
10
mod iter;
11
pub mod naive;
12
#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))]
13
mod x86;
14
15
/// An iterator over all occurrences of the needle in a haystack.
16
#[inline]
17
0
pub fn memchr_iter(needle: u8, haystack: &[u8]) -> Memchr<'_> {
18
0
    Memchr::new(needle, haystack)
19
0
}
20
21
/// An iterator over all occurrences of the needles in a haystack.
22
#[inline]
23
0
pub fn memchr2_iter(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2<'_> {
24
0
    Memchr2::new(needle1, needle2, haystack)
25
0
}
26
27
/// An iterator over all occurrences of the needles in a haystack.
28
#[inline]
29
0
pub fn memchr3_iter(
30
0
    needle1: u8,
31
0
    needle2: u8,
32
0
    needle3: u8,
33
0
    haystack: &[u8],
34
0
) -> Memchr3<'_> {
35
0
    Memchr3::new(needle1, needle2, needle3, haystack)
36
0
}
37
38
/// An iterator over all occurrences of the needle in a haystack, in reverse.
39
#[inline]
40
0
pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev<Memchr<'_>> {
41
0
    Memchr::new(needle, haystack).rev()
42
0
}
43
44
/// An iterator over all occurrences of the needles in a haystack, in reverse.
45
#[inline]
46
0
pub fn memrchr2_iter(
47
0
    needle1: u8,
48
0
    needle2: u8,
49
0
    haystack: &[u8],
50
0
) -> Rev<Memchr2<'_>> {
51
0
    Memchr2::new(needle1, needle2, haystack).rev()
52
0
}
53
54
/// An iterator over all occurrences of the needles in a haystack, in reverse.
55
#[inline]
56
0
pub fn memrchr3_iter(
57
0
    needle1: u8,
58
0
    needle2: u8,
59
0
    needle3: u8,
60
0
    haystack: &[u8],
61
0
) -> Rev<Memchr3<'_>> {
62
0
    Memchr3::new(needle1, needle2, needle3, haystack).rev()
63
0
}
64
65
/// Search for the first occurrence of a byte in a slice.
66
///
67
/// This returns the index corresponding to the first occurrence of `needle` in
68
/// `haystack`, or `None` if one is not found. If an index is returned, it is
69
/// guaranteed to be less than `usize::MAX`.
70
///
71
/// While this is operationally the same as something like
72
/// `haystack.iter().position(|&b| b == needle)`, `memchr` will use a highly
73
/// optimized routine that can be up to an order of magnitude faster in some
74
/// cases.
75
///
76
/// # Example
77
///
78
/// This shows how to find the first position of a byte in a byte string.
79
///
80
/// ```
81
/// use memchr::memchr;
82
///
83
/// let haystack = b"the quick brown fox";
84
/// assert_eq!(memchr(b'k', haystack), Some(8));
85
/// ```
86
#[inline]
87
61.7M
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
88
    #[cfg(miri)]
89
    #[inline(always)]
90
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
91
        naive::memchr(n1, haystack)
92
    }
93
94
    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))]
95
    #[inline(always)]
96
61.7M
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
97
61.7M
        x86::memchr(n1, haystack)
98
61.7M
    }
99
100
    #[cfg(all(
101
        memchr_libc,
102
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
103
        not(miri),
104
    ))]
105
    #[inline(always)]
106
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
107
        c::memchr(n1, haystack)
108
    }
109
110
    #[cfg(all(
111
        not(memchr_libc),
112
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
113
        not(miri),
114
    ))]
115
    #[inline(always)]
116
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
117
        fallback::memchr(n1, haystack)
118
    }
119
120
61.7M
    if haystack.is_empty() {
121
2.75k
        None
122
    } else {
123
61.7M
        imp(needle, haystack)
124
    }
125
61.7M
}
126
127
/// Like `memchr`, but searches for either of two bytes instead of just one.
128
///
129
/// This returns the index corresponding to the first occurrence of `needle1`
130
/// or the first occurrence of `needle2` in `haystack` (whichever occurs
131
/// earlier), or `None` if neither one is found. If an index is returned, it is
132
/// guaranteed to be less than `usize::MAX`.
133
///
134
/// While this is operationally the same as something like
135
/// `haystack.iter().position(|&b| b == needle1 || b == needle2)`, `memchr2`
136
/// will use a highly optimized routine that can be up to an order of magnitude
137
/// faster in some cases.
138
///
139
/// # Example
140
///
141
/// This shows how to find the first position of either of two bytes in a byte
142
/// string.
143
///
144
/// ```
145
/// use memchr::memchr2;
146
///
147
/// let haystack = b"the quick brown fox";
148
/// assert_eq!(memchr2(b'k', b'q', haystack), Some(4));
149
/// ```
150
#[inline]
151
0
pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
152
    #[cfg(miri)]
153
    #[inline(always)]
154
    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
155
        naive::memchr2(n1, n2, haystack)
156
    }
157
158
    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))]
159
    #[inline(always)]
160
0
    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
161
0
        x86::memchr2(n1, n2, haystack)
162
0
    }
163
164
    #[cfg(all(
165
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
166
        not(miri),
167
    ))]
168
    #[inline(always)]
169
    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
170
        fallback::memchr2(n1, n2, haystack)
171
    }
172
173
0
    if haystack.is_empty() {
174
0
        None
175
    } else {
176
0
        imp(needle1, needle2, haystack)
177
    }
178
0
}
179
180
/// Like `memchr`, but searches for any of three bytes instead of just one.
181
///
182
/// This returns the index corresponding to the first occurrence of `needle1`,
183
/// the first occurrence of `needle2`, or the first occurrence of `needle3` in
184
/// `haystack` (whichever occurs earliest), or `None` if none are found. If an
185
/// index is returned, it is guaranteed to be less than `usize::MAX`.
186
///
187
/// While this is operationally the same as something like
188
/// `haystack.iter().position(|&b| b == needle1 || b == needle2 ||
189
/// b == needle3)`, `memchr3` will use a highly optimized routine that can be
190
/// up to an order of magnitude faster in some cases.
191
///
192
/// # Example
193
///
194
/// This shows how to find the first position of any of three bytes in a byte
195
/// string.
196
///
197
/// ```
198
/// use memchr::memchr3;
199
///
200
/// let haystack = b"the quick brown fox";
201
/// assert_eq!(memchr3(b'k', b'q', b'e', haystack), Some(2));
202
/// ```
203
#[inline]
204
0
pub fn memchr3(
205
0
    needle1: u8,
206
0
    needle2: u8,
207
0
    needle3: u8,
208
0
    haystack: &[u8],
209
0
) -> Option<usize> {
210
    #[cfg(miri)]
211
    #[inline(always)]
212
    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
213
        naive::memchr3(n1, n2, n3, haystack)
214
    }
215
216
    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))]
217
    #[inline(always)]
218
0
    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
219
0
        x86::memchr3(n1, n2, n3, haystack)
220
0
    }
221
222
    #[cfg(all(
223
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
224
        not(miri),
225
    ))]
226
    #[inline(always)]
227
    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
228
        fallback::memchr3(n1, n2, n3, haystack)
229
    }
230
231
0
    if haystack.is_empty() {
232
0
        None
233
    } else {
234
0
        imp(needle1, needle2, needle3, haystack)
235
    }
236
0
}
237
238
/// Search for the last occurrence of a byte in a slice.
239
///
240
/// This returns the index corresponding to the last occurrence of `needle` in
241
/// `haystack`, or `None` if one is not found. If an index is returned, it is
242
/// guaranteed to be less than `usize::MAX`.
243
///
244
/// While this is operationally the same as something like
245
/// `haystack.iter().rposition(|&b| b == needle)`, `memrchr` will use a highly
246
/// optimized routine that can be up to an order of magnitude faster in some
247
/// cases.
248
///
249
/// # Example
250
///
251
/// This shows how to find the last position of a byte in a byte string.
252
///
253
/// ```
254
/// use memchr::memrchr;
255
///
256
/// let haystack = b"the quick brown fox";
257
/// assert_eq!(memrchr(b'o', haystack), Some(17));
258
/// ```
259
#[inline]
260
0
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
261
    #[cfg(miri)]
262
    #[inline(always)]
263
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
264
        naive::memrchr(n1, haystack)
265
    }
266
267
    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))]
268
    #[inline(always)]
269
0
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
270
0
        x86::memrchr(n1, haystack)
271
0
    }
272
273
    #[cfg(all(
274
        memchr_libc,
275
        target_os = "linux",
276
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
277
        not(miri)
278
    ))]
279
    #[inline(always)]
280
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
281
        c::memrchr(n1, haystack)
282
    }
283
284
    #[cfg(all(
285
        not(all(memchr_libc, target_os = "linux")),
286
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
287
        not(miri),
288
    ))]
289
    #[inline(always)]
290
    fn imp(n1: u8, haystack: &[u8]) -> Option<usize> {
291
        fallback::memrchr(n1, haystack)
292
    }
293
294
0
    if haystack.is_empty() {
295
0
        None
296
    } else {
297
0
        imp(needle, haystack)
298
    }
299
0
}
300
301
/// Like `memrchr`, but searches for either of two bytes instead of just one.
302
///
303
/// This returns the index corresponding to the last occurrence of `needle1` or
304
/// the last occurrence of `needle2` in `haystack` (whichever occurs later), or
305
/// `None` if neither one is found. If an index is returned, it is guaranteed
306
/// to be less than `usize::MAX`.
307
///
308
/// While this is operationally the same as something like
309
/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2)`, `memrchr2`
310
/// will use a highly optimized routine that can be up to an order of magnitude
311
/// faster in some cases.
312
///
313
/// # Example
314
///
315
/// This shows how to find the last position of either of two bytes in a byte
316
/// string.
317
///
318
/// ```
319
/// use memchr::memrchr2;
320
///
321
/// let haystack = b"the quick brown fox";
322
/// assert_eq!(memrchr2(b'k', b'q', haystack), Some(8));
323
/// ```
324
#[inline]
325
0
pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
326
    #[cfg(miri)]
327
    #[inline(always)]
328
    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
329
        naive::memrchr2(n1, n2, haystack)
330
    }
331
332
    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))]
333
    #[inline(always)]
334
0
    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
335
0
        x86::memrchr2(n1, n2, haystack)
336
0
    }
337
338
    #[cfg(all(
339
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
340
        not(miri),
341
    ))]
342
    #[inline(always)]
343
    fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option<usize> {
344
        fallback::memrchr2(n1, n2, haystack)
345
    }
346
347
0
    if haystack.is_empty() {
348
0
        None
349
    } else {
350
0
        imp(needle1, needle2, haystack)
351
    }
352
0
}
353
354
/// Like `memrchr`, but searches for any of three bytes instead of just one.
355
///
356
/// This returns the index corresponding to the last occurrence of `needle1`,
357
/// the last occurrence of `needle2`, or the last occurrence of `needle3` in
358
/// `haystack` (whichever occurs later), or `None` if none are found. If an
359
/// index is returned, it is guaranteed to be less than `usize::MAX`.
360
///
361
/// While this is operationally the same as something like
362
/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2 ||
363
/// b == needle3)`, `memrchr3` will use a highly optimized routine that can be
364
/// up to an order of magnitude faster in some cases.
365
///
366
/// # Example
367
///
368
/// This shows how to find the last position of any of three bytes in a byte
369
/// string.
370
///
371
/// ```
372
/// use memchr::memrchr3;
373
///
374
/// let haystack = b"the quick brown fox";
375
/// assert_eq!(memrchr3(b'k', b'q', b'e', haystack), Some(8));
376
/// ```
377
#[inline]
378
0
pub fn memrchr3(
379
0
    needle1: u8,
380
0
    needle2: u8,
381
0
    needle3: u8,
382
0
    haystack: &[u8],
383
0
) -> Option<usize> {
384
    #[cfg(miri)]
385
    #[inline(always)]
386
    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
387
        naive::memrchr3(n1, n2, n3, haystack)
388
    }
389
390
    #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, not(miri)))]
391
    #[inline(always)]
392
0
    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
393
0
        x86::memrchr3(n1, n2, n3, haystack)
394
0
    }
395
396
    #[cfg(all(
397
        not(all(target_arch = "x86_64", memchr_runtime_simd)),
398
        not(miri),
399
    ))]
400
    #[inline(always)]
401
    fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option<usize> {
402
        fallback::memrchr3(n1, n2, n3, haystack)
403
    }
404
405
0
    if haystack.is_empty() {
406
0
        None
407
    } else {
408
0
        imp(needle1, needle2, needle3, haystack)
409
    }
410
0
}