1 use core
::arch
::x86_64
::__m128i
;
3 use crate::memmem
::{genericsimd, NeedleInfo}
;
5 /// An SSE accelerated vectorized substring search routine that only works on
7 #[derive(Clone, Copy, Debug)]
8 pub(crate) struct Forward(genericsimd
::Forward
);
11 /// Create a new "generic simd" forward searcher. If one could not be
12 /// created from the given inputs, then None is returned.
13 pub(crate) fn new(ninfo
: &NeedleInfo
, needle
: &[u8]) -> Option
<Forward
> {
14 if !cfg
!(memchr_runtime_sse2
) {
17 genericsimd
::Forward
::new(ninfo
, needle
).map(Forward
)
20 /// Returns the minimum length of haystack that is needed for this searcher
21 /// to work. Passing a haystack with a length smaller than this will cause
24 pub(crate) fn min_haystack_len(&self) -> usize {
25 self.0.min_haystack_len
::<__m128i
>()
34 // SAFETY: sse2 is enabled on all x86_64 targets, so this is always
36 unsafe { self.find_impl(haystack, needle) }
39 /// The implementation of find marked with the appropriate target feature.
43 /// This is safe to call in all cases since sse2 is guaranteed to be part
44 /// of x86_64. It is marked as unsafe because of the target feature
46 #[target_feature(enable = "sse2")]
52 genericsimd
::fwd_find
::<__m128i
>(&self.0, haystack
, needle
)
56 #[cfg(all(test, feature = "std", not(miri)))]
58 use crate::memmem
::{prefilter::PrefilterState, NeedleInfo}
;
61 _
: &mut PrefilterState
,
66 super::Forward
::new(ninfo
, needle
).unwrap().find(haystack
, needle
)
70 fn prefilter_permutations() {
71 use crate::memmem
::prefilter
::tests
::PrefilterTest
;
73 // SAFETY: sse2 is enabled on all x86_64 targets, so this is always
76 PrefilterTest
::run_all_tests_filter(find
, |t
| {
77 // This substring searcher only works on certain configs, so
78 // filter our tests such that Forward::new will be guaranteed
79 // to succeed. (And also remove tests with a haystack that is
81 let fwd
= match super::Forward
::new(&t
.ninfo
, &t
.needle
) {
85 t
.haystack
.len() >= fwd
.min_haystack_len()