}
mod byte_frequencies;
-#[cfg(all(target_arch = "x86_64", memchr_runtime_simd))]
+#[cfg(memchr_runtime_simd)]
mod genericsimd;
mod prefilter;
mod rabinkarp;
mod rarebytes;
mod twoway;
mod util;
-// SIMD is only supported on x86_64 currently.
-#[cfg(target_arch = "x86_64")]
+#[cfg(memchr_runtime_simd)]
mod vector;
+#[cfg(all(memchr_runtime_wasm128))]
+mod wasm;
#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))]
mod x86;
-/// Returns an iterator over all occurrences of a substring in a haystack.
+/// Returns an iterator over all non-overlapping occurrences of a substring in
+/// a haystack.
///
/// # Complexity
///
FindIter::new(haystack, Finder::new(needle))
}
-/// Returns a reverse iterator over all occurrences of a substring in a
-/// haystack.
+/// Returns a reverse iterator over all non-overlapping occurrences of a
+/// substring in a haystack.
///
/// # Complexity
///
let prestate = finder.searcher.prefilter_state();
FindIter { haystack, prestate, finder, pos: 0 }
}
+
+ /// Convert this iterator into its owned variant, such that it no longer
+ /// borrows the finder and needle.
+ ///
+ /// If this is already an owned iterator, then this is a no-op. Otherwise,
+ /// this copies the needle.
+ ///
+ /// This is only available when the `std` feature is enabled.
+ #[cfg(feature = "std")]
+ #[inline]
+ pub fn into_owned(self) -> FindIter<'h, 'static> {
+ FindIter {
+ haystack: self.haystack,
+ prestate: self.prestate,
+ finder: self.finder.into_owned(),
+ pos: self.pos,
+ }
+ }
}
impl<'h, 'n> Iterator for FindIter<'h, 'n> {
let pos = Some(haystack.len());
FindRevIter { haystack, finder, pos }
}
+
+ /// Convert this iterator into its owned variant, such that it no longer
+ /// borrows the finder and needle.
+ ///
+ /// If this is already an owned iterator, then this is a no-op. Otherwise,
+ /// this copies the needle.
+ ///
+ /// This is only available when the `std` feature is enabled.
+ #[cfg(feature = "std")]
+ #[inline]
+ pub fn into_owned(self) -> FindRevIter<'h, 'static> {
+ FindRevIter {
+ haystack: self.haystack,
+ finder: self.finder.into_owned(),
+ pos: self.pos,
+ }
+ }
}
impl<'h, 'n> Iterator for FindRevIter<'h, 'n> {
TwoWay(twoway::Forward),
#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))]
GenericSIMD128(x86::sse::Forward),
+ #[cfg(memchr_runtime_wasm128)]
+ GenericSIMD128(wasm::Forward),
#[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))]
GenericSIMD256(x86::avx::Forward),
}
impl<'n> Searcher<'n> {
- #[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))]
fn new(config: SearcherConfig, needle: &'n [u8]) -> Searcher<'n> {
use self::SearcherKind::*;
let ninfo = NeedleInfo::new(needle);
- let prefn =
- prefilter::forward(&config.prefilter, &ninfo.rarebytes, needle);
- let kind = if needle.len() == 0 {
- Empty
- } else if needle.len() == 1 {
- OneByte(needle[0])
- } else if let Some(fwd) = x86::avx::Forward::new(&ninfo, needle) {
- GenericSIMD256(fwd)
- } else if let Some(fwd) = x86::sse::Forward::new(&ninfo, needle) {
- GenericSIMD128(fwd)
- } else {
- TwoWay(twoway::Forward::new(needle))
+ let mk = |kind: SearcherKind| {
+ let prefn = prefilter::forward(
+ &config.prefilter,
+ &ninfo.rarebytes,
+ needle,
+ );
+ Searcher { needle: CowBytes::new(needle), ninfo, prefn, kind }
};
- Searcher { needle: CowBytes::new(needle), ninfo, prefn, kind }
- }
-
- #[cfg(not(all(not(miri), target_arch = "x86_64", memchr_runtime_simd)))]
- fn new(config: SearcherConfig, needle: &'n [u8]) -> Searcher<'n> {
- use self::SearcherKind::*;
+ if needle.len() == 0 {
+ return mk(Empty);
+ }
+ if needle.len() == 1 {
+ return mk(OneByte(needle[0]));
+ }
+ #[cfg(all(not(miri), target_arch = "x86_64", memchr_runtime_simd))]
+ {
+ if let Some(fwd) = x86::avx::Forward::new(&ninfo, needle) {
+ return mk(GenericSIMD256(fwd));
+ } else if let Some(fwd) = x86::sse::Forward::new(&ninfo, needle) {
+ return mk(GenericSIMD128(fwd));
+ }
+ }
+ #[cfg(all(target_arch = "wasm32", memchr_runtime_simd))]
+ {
+ if let Some(fwd) = wasm::Forward::new(&ninfo, needle) {
+ return mk(GenericSIMD128(fwd));
+ }
+ }
- let ninfo = NeedleInfo::new(needle);
- let prefn =
- prefilter::forward(&config.prefilter, &ninfo.rarebytes, needle);
- let kind = if needle.len() == 0 {
- Empty
- } else if needle.len() == 1 {
- OneByte(needle[0])
- } else {
- TwoWay(twoway::Forward::new(needle))
- };
- Searcher { needle: CowBytes::new(needle), ninfo, prefn, kind }
+ mk(TwoWay(twoway::Forward::new(needle)))
}
/// Return a fresh prefilter state that can be used with this searcher.
Empty => Empty,
OneByte(b) => OneByte(b),
TwoWay(tw) => TwoWay(tw),
- #[cfg(all(
- not(miri),
- target_arch = "x86_64",
- memchr_runtime_simd
- ))]
+ #[cfg(all(not(miri), memchr_runtime_simd))]
GenericSIMD128(gs) => GenericSIMD128(gs),
#[cfg(all(
not(miri),
Empty => Empty,
OneByte(b) => OneByte(b),
TwoWay(tw) => TwoWay(tw),
- #[cfg(all(
- not(miri),
- target_arch = "x86_64",
- memchr_runtime_simd
- ))]
+ #[cfg(all(not(miri), memchr_runtime_simd))]
GenericSIMD128(gs) => GenericSIMD128(gs),
#[cfg(all(
not(miri),
self.find_tw(tw, state, haystack, needle)
}
}
- #[cfg(all(
- not(miri),
- target_arch = "x86_64",
- memchr_runtime_simd
- ))]
+ #[cfg(all(not(miri), memchr_runtime_simd))]
GenericSIMD128(ref gs) => {
// The SIMD matcher can't handle particularly short haystacks,
// so we fall back to RK in these cases.