diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2021-05-20 17:56:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-20 17:56:46 +0200 |
| commit | 0d3bee8be03e58cfe0295a775961a4daa2ea2fd1 (patch) | |
| tree | 7bbf034849d62e31e35417daabc14711e74bff02 /library/std/src/sys_common | |
| parent | 8a57820bca64a252489790a57cb5ea23db6f9198 (diff) | |
| parent | 5353c5c3fb7ebc4fb12ca3488c555ee3006c8325 (diff) | |
| download | rust-0d3bee8be03e58cfe0295a775961a4daa2ea2fd1.tar.gz rust-0d3bee8be03e58cfe0295a775961a4daa2ea2fd1.zip | |
Rollup merge of #85275 - CDirkx:memchr, r=m-ou-se
Move `std::memchr` to `sys_common` `std::memchr` is a thin abstraction over the different `memchr` implementations in `sys`, along with documentation and tests. The module is only used internally by `std`, nothing is exported externally. Code like this is exactly what the `sys_common` module is for, so this PR moves it there.
Diffstat (limited to 'library/std/src/sys_common')
| -rw-r--r-- | library/std/src/sys_common/memchr.rs | 51 | ||||
| -rw-r--r-- | library/std/src/sys_common/memchr/tests.rs | 86 | ||||
| -rw-r--r-- | library/std/src/sys_common/mod.rs | 1 |
3 files changed, 138 insertions, 0 deletions
diff --git a/library/std/src/sys_common/memchr.rs b/library/std/src/sys_common/memchr.rs new file mode 100644 index 00000000000..b219e878912 --- /dev/null +++ b/library/std/src/sys_common/memchr.rs @@ -0,0 +1,51 @@ +// Original implementation taken from rust-memchr. +// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch + +use crate::sys::memchr as sys; + +#[cfg(test)] +mod tests; + +/// A safe interface to `memchr`. +/// +/// Returns the index corresponding to the first occurrence of `needle` in +/// `haystack`, or `None` if one is not found. +/// +/// memchr reduces to super-optimized machine code at around an order of +/// magnitude faster than `haystack.iter().position(|&b| b == needle)`. +/// (See benchmarks.) +/// +/// # Examples +/// +/// This shows how to find the first position of a byte in a byte string. +/// +/// ```ignore (cannot-doctest-private-modules) +/// use memchr::memchr; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr(b'k', haystack), Some(8)); +/// ``` +#[inline] +pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { + sys::memchr(needle, haystack) +} + +/// A safe interface to `memrchr`. +/// +/// Returns the index corresponding to the last occurrence of `needle` in +/// `haystack`, or `None` if one is not found. +/// +/// # Examples +/// +/// This shows how to find the last position of a byte in a byte string. +/// +/// ```ignore (cannot-doctest-private-modules) +/// use memchr::memrchr; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr(b'o', haystack), Some(17)); +/// ``` +#[inline] +pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { + sys::memrchr(needle, haystack) +} diff --git a/library/std/src/sys_common/memchr/tests.rs b/library/std/src/sys_common/memchr/tests.rs new file mode 100644 index 00000000000..557d749c7f6 --- /dev/null +++ b/library/std/src/sys_common/memchr/tests.rs @@ -0,0 +1,86 @@ +// Original implementation taken from rust-memchr. +// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch + +// test the implementations for the current platform +use super::{memchr, memrchr}; + +#[test] +fn matches_one() { + assert_eq!(Some(0), memchr(b'a', b"a")); +} + +#[test] +fn matches_begin() { + assert_eq!(Some(0), memchr(b'a', b"aaaa")); +} + +#[test] +fn matches_end() { + assert_eq!(Some(4), memchr(b'z', b"aaaaz")); +} + +#[test] +fn matches_nul() { + assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00")); +} + +#[test] +fn matches_past_nul() { + assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z")); +} + +#[test] +fn no_match_empty() { + assert_eq!(None, memchr(b'a', b"")); +} + +#[test] +fn no_match() { + assert_eq!(None, memchr(b'a', b"xyz")); +} + +#[test] +fn matches_one_reversed() { + assert_eq!(Some(0), memrchr(b'a', b"a")); +} + +#[test] +fn matches_begin_reversed() { + assert_eq!(Some(3), memrchr(b'a', b"aaaa")); +} + +#[test] +fn matches_end_reversed() { + assert_eq!(Some(0), memrchr(b'z', b"zaaaa")); +} + +#[test] +fn matches_nul_reversed() { + assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00")); +} + +#[test] +fn matches_past_nul_reversed() { + assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa")); +} + +#[test] +fn no_match_empty_reversed() { + assert_eq!(None, memrchr(b'a', b"")); +} + +#[test] +fn no_match_reversed() { + assert_eq!(None, memrchr(b'a', b"xyz")); +} + +#[test] +fn each_alignment() { + let mut data = [1u8; 64]; + let needle = 2; + let pos = 40; + data[pos] = needle; + for start in 0..16 { + assert_eq!(Some(pos - start), memchr(needle, &data[start..])); + } +} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 4ef0e72adf0..1a9caa22c92 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -25,6 +25,7 @@ pub mod bytestring; pub mod condvar; pub mod fs; pub mod io; +pub mod memchr; pub mod mutex; // `doc` is required because `sys/mod.rs` imports `unix/ext/mod.rs` on Windows // when generating documentation. |
