Skip to content

Add no std support #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ keywords = ["search", "text", "string", "single", "simd"]
[dependencies]
cfg-if = "1"
paste = "1"
memchr = "2.3"
memchr = { version = "2.7.4", default-features = false }
seq-macro = "0.3"

[dev-dependencies]
memmap2 = "0.5"
memmap2 = "0.9"

[profile.release]
debug = true

[features]
stdsimd = []
default = ["std"]
alloc = []
std = ["alloc"]
stdsimd = ["std"]
2 changes: 1 addition & 1 deletion src/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{Needle, NeedleWithSize, Searcher, Vector, VectorHash};

#[cfg(target_arch = "aarch64")]
use std::arch::aarch64::*;
use core::arch::aarch64::*;

static MD: [u8; 16] = [
1 << 0,
Expand Down
30 changes: 21 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#![warn(missing_docs)]
#![cfg_attr(feature = "stdsimd", feature(portable_simd))]
#![cfg_attr(not(feature = "std"), no_std)]

/// Substring search implementations using aarch64 architecture features.
#[cfg(target_arch = "aarch64")]
Expand All @@ -23,9 +24,12 @@ pub mod x86;
#[cfg(target_arch = "wasm32")]
pub mod wasm32;

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(feature = "alloc")]
use alloc::{boxed::Box, rc::Rc, sync::Arc, vec::Vec};
use memchr::memchr;
use std::rc::Rc;
use std::sync::Arc;

#[macro_use]
mod multiversion;
Expand Down Expand Up @@ -58,6 +62,7 @@ impl Needle for [u8] {
}
}

#[cfg(feature = "alloc")]
impl<N: Needle + ?Sized> Needle for Box<N> {
const SIZE: Option<usize> = N::SIZE;

Expand All @@ -67,6 +72,7 @@ impl<N: Needle + ?Sized> Needle for Box<N> {
}
}

#[cfg(feature = "alloc")]
impl<N: Needle + ?Sized> Needle for Rc<N> {
const SIZE: Option<usize> = N::SIZE;

Expand All @@ -76,6 +82,7 @@ impl<N: Needle + ?Sized> Needle for Rc<N> {
}
}

#[cfg(feature = "alloc")]
impl<N: Needle + ?Sized> Needle for Arc<N> {
const SIZE: Option<usize> = N::SIZE;

Expand All @@ -94,6 +101,7 @@ impl<N: Needle + ?Sized> Needle for &N {
}
}

#[cfg(feature = "alloc")]
impl Needle for Vec<u8> {
const SIZE: Option<usize> = None;

Expand Down Expand Up @@ -189,10 +197,10 @@ impl<T: Vector, V: Vector + From<T>> From<&VectorHash<T>> for VectorHash<V> {

macro_rules! memcmp {
($chunk:ident, $needle:ident, $len:literal) => {
std::slice::from_raw_parts($chunk, $len) == std::slice::from_raw_parts($needle, $len)
core::slice::from_raw_parts($chunk, $len) == core::slice::from_raw_parts($needle, $len)
};
($chunk:ident, $needle:ident, $len:ident) => {
std::slice::from_raw_parts($chunk, $len) == std::slice::from_raw_parts($needle, $len)
core::slice::from_raw_parts($chunk, $len) == core::slice::from_raw_parts($needle, $len)
};
}

Expand Down Expand Up @@ -294,7 +302,9 @@ trait Searcher<N: NeedleWithSize + ?Sized> {

#[cfg(test)]
mod tests {
use super::{MemchrSearcher, Needle};
use super::MemchrSearcher;
#[cfg(feature = "alloc")]
use super::Needle;

fn memchr_search(haystack: &[u8], needle: &[u8]) -> bool {
MemchrSearcher::new(needle[0]).search_in(haystack)
Expand Down Expand Up @@ -331,9 +341,10 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn needle_array_size() {
use std::rc::Rc;
use std::sync::Arc;
use alloc::rc::Rc;
use alloc::sync::Arc;

assert_eq!(<[u8; 0] as Needle>::SIZE, Some(0));

Expand All @@ -347,9 +358,10 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn needle_slice_size() {
use std::rc::Rc;
use std::sync::Arc;
use alloc::rc::Rc;
use alloc::sync::Arc;

assert_eq!(Box::<[u8]>::SIZE, None);

Expand Down
2 changes: 1 addition & 1 deletion src/stdsimd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ where

#[inline]
unsafe fn load(a: *const u8) -> Self {
std::ptr::read_unaligned(a as *const Self)
core::ptr::read_unaligned(a as *const Self)
}

#[inline]
Expand Down
10 changes: 5 additions & 5 deletions src/wasm32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{Needle, NeedleWithSize, Searcher, Vector, VectorHash};
#[cfg(target_arch = "wasm32")]
use std::arch::wasm32::*;
use core::arch::wasm32::*;

impl Vector for v128 {
const LANES: usize = 16;
Expand All @@ -17,7 +17,7 @@ impl Vector for v128 {
#[inline]
#[target_feature(enable = "simd128")]
unsafe fn load(a: *const u8) -> Self {
std::ptr::read_unaligned(a as *const v128)
core::ptr::read_unaligned(a as *const v128)
}

#[inline]
Expand Down Expand Up @@ -57,7 +57,7 @@ impl Vector for v64 {
#[inline]
#[target_feature(enable = "simd128")]
unsafe fn load(a: *const u8) -> Self {
Self(u64x2_splat(std::ptr::read_unaligned(a as *const u64)))
Self(u64x2_splat(core::ptr::read_unaligned(a as *const u64)))
}

#[inline]
Expand Down Expand Up @@ -103,7 +103,7 @@ impl Vector for v32 {
#[inline]
#[target_feature(enable = "simd128")]
unsafe fn load(a: *const u8) -> Self {
Self(u32x4_splat(std::ptr::read_unaligned(a as *const u32)))
Self(u32x4_splat(core::ptr::read_unaligned(a as *const u32)))
}

#[inline]
Expand Down Expand Up @@ -149,7 +149,7 @@ impl Vector for v16 {
#[inline]
#[target_feature(enable = "simd128")]
unsafe fn load(a: *const u8) -> Self {
Self(u16x8_splat(std::ptr::read_unaligned(a as *const u16)))
Self(u16x8_splat(core::ptr::read_unaligned(a as *const u16)))
}

#[inline]
Expand Down
33 changes: 18 additions & 15 deletions src/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
#![allow(clippy::missing_safety_doc)]

use crate::{MemchrSearcher, Needle, NeedleWithSize, Searcher, Vector, VectorHash};
use seq_macro::seq;
#[cfg(target_arch = "x86")]
use std::arch::x86::*;
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
use core::arch::x86_64::*;
use seq_macro::seq;

#[derive(Clone, Copy)]
#[repr(transparent)]
Expand All @@ -41,7 +41,7 @@ impl Vector for __m16i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn load(a: *const u8) -> Self {
__m16i(_mm_set1_epi16(std::ptr::read_unaligned(a as *const i16)))
__m16i(_mm_set1_epi16(core::ptr::read_unaligned(a as *const i16)))
}

#[inline]
Expand All @@ -59,7 +59,7 @@ impl Vector for __m16i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn to_bitmask(a: Self) -> u32 {
std::mem::transmute(_mm_movemask_epi8(a.0) & 0x3)
core::mem::transmute(_mm_movemask_epi8(a.0) & 0x3)
}
}

Expand Down Expand Up @@ -88,7 +88,7 @@ impl Vector for __m32i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn load(a: *const u8) -> Self {
__m32i(_mm_set1_epi32(std::ptr::read_unaligned(a as *const i32)))
__m32i(_mm_set1_epi32(core::ptr::read_unaligned(a as *const i32)))
}

#[inline]
Expand All @@ -106,7 +106,7 @@ impl Vector for __m32i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn to_bitmask(a: Self) -> u32 {
std::mem::transmute(_mm_movemask_epi8(a.0) & 0xF)
core::mem::transmute(_mm_movemask_epi8(a.0) & 0xF)
}
}

Expand Down Expand Up @@ -135,7 +135,7 @@ impl Vector for __m64i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn load(a: *const u8) -> Self {
__m64i(_mm_set1_epi64x(std::ptr::read_unaligned(a as *const i64)))
__m64i(_mm_set1_epi64x(core::ptr::read_unaligned(a as *const i64)))
}

#[inline]
Expand All @@ -153,7 +153,7 @@ impl Vector for __m64i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn to_bitmask(a: Self) -> u32 {
std::mem::transmute(_mm_movemask_epi8(a.0) & 0xFF)
core::mem::transmute(_mm_movemask_epi8(a.0) & 0xFF)
}
}

Expand Down Expand Up @@ -195,7 +195,7 @@ impl Vector for __m128i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn to_bitmask(a: Self) -> u32 {
std::mem::transmute(_mm_movemask_epi8(a))
core::mem::transmute(_mm_movemask_epi8(a))
}
}

Expand Down Expand Up @@ -230,7 +230,7 @@ impl Vector for __m256i {
#[inline]
#[target_feature(enable = "avx2")]
unsafe fn to_bitmask(a: Self) -> u32 {
std::mem::transmute(_mm256_movemask_epi8(a))
core::mem::transmute(_mm256_movemask_epi8(a))
}
}

Expand Down Expand Up @@ -533,16 +533,17 @@ mod tests {
#[test]
#[should_panic]
fn avx2_invalid_position() {
unsafe { Avx2Searcher::with_position(b"foo".to_vec().into_boxed_slice(), 3) };
unsafe { Avx2Searcher::with_position(b"foo", 3) };
}

#[test]
#[should_panic]
fn dynamic_avx2_invalid_position() {
unsafe { DynamicAvx2Searcher::with_position(b"foo".to_vec().into_boxed_slice(), 3) };
unsafe { DynamicAvx2Searcher::with_position(b"foo", 3) };
}

#[test]
#[cfg(feature = "alloc")]
#[should_panic]
fn avx2_empty_needle() {
unsafe { Avx2Searcher::new(Box::new([])) };
Expand All @@ -567,22 +568,24 @@ mod tests {
#[test]
#[cfg(target_pointer_width = "64")]
fn size_of_avx2_searcher() {
use std::mem::size_of;
use core::mem::size_of;

assert_eq!(size_of::<Avx2Searcher::<&[u8]>>(), 128);
assert_eq!(size_of::<Avx2Searcher::<[u8; 0]>>(), 128);
assert_eq!(size_of::<Avx2Searcher::<[u8; 16]>>(), 128);
#[cfg(feature = "alloc")]
assert_eq!(size_of::<Avx2Searcher::<Box<[u8]>>>(), 128);
}

#[test]
#[cfg(target_pointer_width = "64")]
fn size_of_dynamic_avx2_searcher() {
use std::mem::size_of;
use core::mem::size_of;

assert_eq!(size_of::<DynamicAvx2Searcher::<&[u8]>>(), 160);
assert_eq!(size_of::<DynamicAvx2Searcher::<[u8; 0]>>(), 160);
assert_eq!(size_of::<DynamicAvx2Searcher::<[u8; 16]>>(), 160);
#[cfg(feature = "alloc")]
assert_eq!(size_of::<DynamicAvx2Searcher::<Box<[u8]>>>(), 160);
}

Expand Down
2 changes: 1 addition & 1 deletion tests/i386.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn search(haystack: &str, needle: &str) {
cfg_if::cfg_if! {
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
use sliceslice::x86::DynamicAvx2Searcher;
let searcher = unsafe { DynamicAvx2Searcher::new(needle.to_owned().into_boxed_slice()) };
let searcher = unsafe { DynamicAvx2Searcher::new(needle) };
assert_eq!(unsafe { searcher.search_in(haystack) }, result);
} else if #[cfg(target_arch = "wasm32")] {
use sliceslice::wasm32::Wasm32Searcher;
Expand Down