use core::arch::wasm32::v128;
use crate::arch::{all::packedpair::Pair, generic::packedpair};
#[derive(Clone, Copy, Debug)]
pub struct Finder(packedpair::Finder<v128>);
impl Finder {
#[inline]
pub fn new(needle: &[u8]) -> Option<Finder> {
Finder::with_pair(needle, Pair::new(needle)?)
}
#[inline]
pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder> {
if Finder::is_available() {
unsafe { Some(Finder::with_pair_impl(needle, pair)) }
} else {
None
}
}
#[target_feature(enable = "simd128")]
#[inline]
unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder {
let finder = packedpair::Finder::<v128>::new(needle, pair);
Finder(finder)
}
#[inline]
pub fn is_available() -> bool {
true
}
#[inline]
pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
self.find_impl(haystack, needle)
}
#[inline]
pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize> {
self.find_prefilter_impl(haystack)
}
#[target_feature(enable = "simd128")]
#[inline]
fn find_impl(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
unsafe { self.0.find(haystack, needle) }
}
#[target_feature(enable = "simd128")]
#[inline]
fn find_prefilter_impl(&self, haystack: &[u8]) -> Option<usize> {
unsafe { self.0.find_prefilter(haystack) }
}
#[inline]
pub fn pair(&self) -> &Pair {
self.0.pair()
}
#[inline]
pub fn min_haystack_len(&self) -> usize {
self.0.min_haystack_len()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn find(haystack: &[u8], needle: &[u8]) -> Option<Option<usize>> {
let f = Finder::new(needle)?;
if haystack.len() < f.min_haystack_len() {
return None;
}
Some(f.find(haystack, needle))
}
define_substring_forward_quickcheck!(find);
#[test]
fn forward_substring() {
crate::tests::substring::Runner::new().fwd(find).run()
}
#[test]
fn forward_packedpair() {
fn find(
haystack: &[u8],
needle: &[u8],
index1: u8,
index2: u8,
) -> Option<Option<usize>> {
let pair = Pair::with_indices(needle, index1, index2)?;
let f = Finder::with_pair(needle, pair)?;
if haystack.len() < f.min_haystack_len() {
return None;
}
Some(f.find(haystack, needle))
}
crate::tests::packedpair::Runner::new().fwd(find).run()
}
#[test]
fn forward_packedpair_prefilter() {
fn find(
haystack: &[u8],
needle: &[u8],
index1: u8,
index2: u8,
) -> Option<Option<usize>> {
let pair = Pair::with_indices(needle, index1, index2)?;
let f = Finder::with_pair(needle, pair)?;
if haystack.len() < f.min_haystack_len() {
return None;
}
Some(f.find_prefilter(haystack))
}
crate::tests::packedpair::Runner::new().fwd(find).run()
}
}