Skip to content

Commit

Permalink
Merge pull request #1117 from cuviper/array-patterns
Browse files Browse the repository at this point in the history
`impl Pattern for [char; N]` and `&[char; N]`
  • Loading branch information
cuviper committed Jan 26, 2024
2 parents 9ca21de + 719b4ce commit 97f11ee
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 66 deletions.
31 changes: 21 additions & 10 deletions src/str.rs
Expand Up @@ -6,8 +6,8 @@
//! Note: [`ParallelString::par_split()`] and [`par_split_terminator()`]
//! reference a `Pattern` trait which is not visible outside this crate.
//! This trait is intentionally kept private, for use only by Rayon itself.
//! It is implemented for `char`, `&[char]`, and any function or closure
//! `F: Fn(char) -> bool + Sync + Send`.
//! It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
//! and any function or closure `F: Fn(char) -> bool + Sync + Send`.
//!
//! [`ParallelString::par_split()`]: trait.ParallelString.html#method.par_split
//! [`par_split_terminator()`]: trait.ParallelString.html#method.par_split_terminator
Expand Down Expand Up @@ -140,8 +140,8 @@ pub trait ParallelString {
/// given character or predicate, similar to `str::split`.
///
/// Note: the `Pattern` trait is private, for use only by Rayon itself.
/// It is implemented for `char`, `&[char]`, and any function or closure
/// `F: Fn(char) -> bool + Sync + Send`.
/// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
/// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
Expand All @@ -163,8 +163,8 @@ pub trait ParallelString {
/// substring after a trailing terminator.
///
/// Note: the `Pattern` trait is private, for use only by Rayon itself.
/// It is implemented for `char`, `&[char]`, and any function or closure
/// `F: Fn(char) -> bool + Sync + Send`.
/// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
/// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
Expand Down Expand Up @@ -278,8 +278,8 @@ pub trait ParallelString {
/// given character or predicate, similar to `str::matches`.
///
/// Note: the `Pattern` trait is private, for use only by Rayon itself.
/// It is implemented for `char`, `&[char]`, and any function or closure
/// `F: Fn(char) -> bool + Sync + Send`.
/// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
/// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
Expand All @@ -302,8 +302,8 @@ pub trait ParallelString {
/// or predicate, with their positions, similar to `str::match_indices`.
///
/// Note: the `Pattern` trait is private, for use only by Rayon itself.
/// It is implemented for `char`, `&[char]`, and any function or closure
/// `F: Fn(char) -> bool + Sync + Send`.
/// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
/// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
Expand Down Expand Up @@ -419,6 +419,17 @@ impl Pattern for &[char] {
impl_pattern!(&self => *self);
}

// TODO (MSRV 1.75): use `*self` for array patterns too.
// - Needs `DoubleEndedSearcher` so `split.next_back()` works.

impl<const N: usize> Pattern for [char; N] {
impl_pattern!(&self => self.as_slice());
}

impl<const N: usize> Pattern for &[char; N] {
impl_pattern!(&self => self.as_slice());
}

impl<FN: Sync + Send + Fn(char) -> bool> Pattern for FN {
impl_pattern!(&self => self);
}
Expand Down
88 changes: 32 additions & 56 deletions tests/str.rs
Expand Up @@ -59,35 +59,38 @@ pub fn execute_strings_split() {
(include_str!("str.rs"), ' '),
];

for &(string, separator) in &tests {
let serial: Vec<_> = string.split(separator).collect();
let parallel: Vec<_> = string.par_split(separator).collect();
assert_eq!(serial, parallel);

let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
let serial: Vec<_> = string.split(pattern).collect();
let parallel: Vec<_> = string.par_split(pattern).collect();
assert_eq!(serial, parallel);

let serial_fn: Vec<_> = string.split(|c| c == separator).collect();
let parallel_fn: Vec<_> = string.par_split(|c| c == separator).collect();
assert_eq!(serial_fn, parallel_fn);
macro_rules! check_separators {
($split:ident, $par_split:ident) => {
for &(string, separator) in &tests {
let serial: Vec<_> = string.$split(separator).collect();
let parallel: Vec<_> = string.$par_split(separator).collect();
assert_eq!(serial, parallel);

let array = ['\u{0}', separator, '\u{1F980}'];
let array_ref = &array;
let slice: &[char] = array_ref;

let serial: Vec<_> = string.$split(slice).collect();
let parallel: Vec<_> = string.$par_split(slice).collect();
assert_eq!(serial, parallel);

let serial: Vec<_> = string.$split(array).collect();
let parallel: Vec<_> = string.$par_split(array).collect();
assert_eq!(serial, parallel);

let serial: Vec<_> = string.$split(array_ref).collect();
let parallel: Vec<_> = string.$par_split(array_ref).collect();
assert_eq!(serial, parallel);

let serial_fn: Vec<_> = string.$split(|c| c == separator).collect();
let parallel_fn: Vec<_> = string.$par_split(|c| c == separator).collect();
assert_eq!(serial_fn, parallel_fn);
}
};
}

for &(string, separator) in &tests {
let serial: Vec<_> = string.split_terminator(separator).collect();
let parallel: Vec<_> = string.par_split_terminator(separator).collect();
assert_eq!(serial, parallel);

let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
let serial: Vec<_> = string.split_terminator(pattern).collect();
let parallel: Vec<_> = string.par_split_terminator(pattern).collect();
assert_eq!(serial, parallel);

let serial: Vec<_> = string.split_terminator(|c| c == separator).collect();
let parallel: Vec<_> = string.par_split_terminator(|c| c == separator).collect();
assert_eq!(serial, parallel);
}
check_separators!(split, par_split);
check_separators!(split_terminator, par_split_terminator);

for &(string, _) in &tests {
let serial: Vec<_> = string.lines().collect();
Expand All @@ -108,33 +111,6 @@ pub fn execute_strings_split() {
}

// try matching separators too!
for &(string, separator) in &tests {
let serial: Vec<_> = string.matches(separator).collect();
let parallel: Vec<_> = string.par_matches(separator).collect();
assert_eq!(serial, parallel);

let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
let serial: Vec<_> = string.matches(pattern).collect();
let parallel: Vec<_> = string.par_matches(pattern).collect();
assert_eq!(serial, parallel);

let serial_fn: Vec<_> = string.matches(|c| c == separator).collect();
let parallel_fn: Vec<_> = string.par_matches(|c| c == separator).collect();
assert_eq!(serial_fn, parallel_fn);
}

for &(string, separator) in &tests {
let serial: Vec<_> = string.match_indices(separator).collect();
let parallel: Vec<_> = string.par_match_indices(separator).collect();
assert_eq!(serial, parallel);

let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
let serial: Vec<_> = string.match_indices(pattern).collect();
let parallel: Vec<_> = string.par_match_indices(pattern).collect();
assert_eq!(serial, parallel);

let serial_fn: Vec<_> = string.match_indices(|c| c == separator).collect();
let parallel_fn: Vec<_> = string.par_match_indices(|c| c == separator).collect();
assert_eq!(serial_fn, parallel_fn);
}
check_separators!(matches, par_matches);
check_separators!(match_indices, par_match_indices);
}

0 comments on commit 97f11ee

Please sign in to comment.