diff --git a/src/str.rs b/src/str.rs index 205e42783..89aaabd00 100644 --- a/src/str.rs +++ b/src/str.rs @@ -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 @@ -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 /// @@ -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 /// @@ -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 /// @@ -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 /// @@ -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 Pattern for [char; N] { + impl_pattern!(&self => self.as_slice()); +} + +impl Pattern for &[char; N] { + impl_pattern!(&self => self.as_slice()); +} + impl bool> Pattern for FN { impl_pattern!(&self => self); } diff --git a/tests/str.rs b/tests/str.rs index 7a65a7b82..96b882df6 100644 --- a/tests/str.rs +++ b/tests/str.rs @@ -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(); @@ -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); }