[−][src]Macro safe_arch::string_search_for_index
This is supported with target feature
sse4.2
only.Looks for $needle
in $haystack
and gives the index of the either the
first or last match.
This is a fairly flexible operation, and so I apologize in advance.
- The "needle" is the string you're looking for.
- The "haystack" is the string you're looking inside of.
- The lengths of each string can be "explicit" or "implicit".
- "explicit" is specified with
[str, len]
pairs. - "implicit" just ends at the first
\0
. - Either way a string doesn't go past the end of the register.
- "explicit" is specified with
- You need to pick a "char type", which can be any of
u8
,i8
,u16
,i16
. These operations always operate onm128i
registers, but the interpretation of the data is configurable. - You need to pick the search operation, which determines how the
needle
is compared to thehaystack
:EqAny
: Matches when any haystack character equals any needle character, regardless of position.CmpRanges
: Interprets consecutive pairs of characters in the needle as(low..=high)
ranges to compare each haystack character to.CmpEqEach
: Matches when a character position in the needle is equal to the character at the same position in the haystack.CmpEqOrdered
: Matches when the complete needle string is a substring somewhere in the haystack.
- Finally, you need to specify if you're looking for the
FirstMatch
orLastMatch
.- If no match is found the output will be the length of the haystack.
It's a lot to take in. Hopefully the examples below can help clarify how
things work. They all use u8
since Rust string literals are UTF-8, but
it's the same with the other character types.
EqAny
let hay: m128i = m128i::from(*b"some test words."); // explicit needle length let needle: m128i = m128i::from(*b"e_______________"); let i: ::core::primitive::i32 = string_search_for_index!([needle, 1], [hay, 16], u8, EqAny, FirstMatch); assert_eq!(i, 3); let i: ::core::primitive::i32 = string_search_for_index!([needle, 1], [hay, 16], u8, EqAny, LastMatch); assert_eq!(i, 6); // implicit needle length let needle: m128i = m128i::from(*b"e\0______________"); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, EqAny, FirstMatch); assert_eq!(i, 3); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, EqAny, LastMatch); assert_eq!(i, 6); // more than one needle character will match any of them, though we // don't get info about _which_ needle character matched. let needle: m128i = m128i::from(*b"et\0_____________"); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, EqAny, FirstMatch); assert_eq!(i, 3); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, EqAny, LastMatch); assert_eq!(i, 8);
CmpRanges
let hay: m128i = m128i::from(*b"some test words."); let needle: m128i = m128i::from(*b"vz\0_____________"); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, CmpRanges, FirstMatch); assert_eq!(i, 10); // matches the 'w'
CmpEqEach
let hay: m128i = m128i::from(*b"some test words."); let needle: m128i = m128i::from(*b"_____test_______"); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, CmpEqEach, FirstMatch); assert_eq!(i, 5); // start of "test" let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, CmpEqEach, LastMatch); assert_eq!(i, 8); // end of "test"
CmpEqOrdered
let hay: m128i = m128i::from(*b"some test words."); let needle: m128i = m128i::from(*b"words\0__________"); let i: ::core::primitive::i32 = string_search_for_index!(needle, hay, u8, CmpEqOrdered, FirstMatch); assert_eq!(i, 10); // This is where the "words" substring begins