//! 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` and any `F: Fn(char) -> bool + Sync + Send`.
+//! It is implemented for `char`, `&[char]`, 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
// character boundary. So we look at the raw bytes, first scanning
// forward from the midpoint for a boundary, then trying backward.
let (left, right) = chars.as_bytes().split_at(mid);
- match right.iter().cloned().position(is_char_boundary) {
+ match right.iter().copied().position(is_char_boundary) {
Some(i) => mid + i,
None => left
.iter()
- .cloned()
+ .copied()
.rposition(is_char_boundary)
.unwrap_or(0),
}
/// Note that multi-byte sequences (for code points greater than `U+007F`)
/// are produced as separate items, but will not be split across threads.
/// If you would prefer an indexed iterator without that guarantee, consider
- /// `string.as_bytes().par_iter().cloned()` instead.
+ /// `string.as_bytes().par_iter().copied()` instead.
///
/// # Examples
///
/// 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` and any `F: Fn(char) -> bool + Sync + Send`.
+ /// It is implemented for `char`, `&[char]`, and any function or closure
+ /// `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
/// substring after a trailing terminator.
///
/// Note: the `Pattern` trait is private, for use only by Rayon itself.
- /// It is implemented for `char` and any `F: Fn(char) -> bool + Sync + Send`.
+ /// It is implemented for `char`, `&[char]`, and any function or closure
+ /// `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
/// 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` and any `F: Fn(char) -> bool + Sync + Send`.
+ /// It is implemented for `char`, `&[char]`, and any function or closure
+ /// `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
/// 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` and any `F: Fn(char) -> bool + Sync + Send`.
+ /// It is implemented for `char`, `&[char]`, and any function or closure
+ /// `F: Fn(char) -> bool + Sync + Send`.
///
/// # Examples
///
move |(i, x)| (base + i, x)
}
-impl Pattern for char {
- private_impl! {}
+macro_rules! impl_pattern {
+ (&$self:ident => $pattern:expr) => {
+ private_impl! {}
- #[inline]
- fn find_in(&self, chars: &str) -> Option<usize> {
- chars.find(*self)
- }
+ #[inline]
+ fn find_in(&$self, chars: &str) -> Option<usize> {
+ chars.find($pattern)
+ }
- #[inline]
- fn rfind_in(&self, chars: &str) -> Option<usize> {
- chars.rfind(*self)
- }
+ #[inline]
+ fn rfind_in(&$self, chars: &str) -> Option<usize> {
+ chars.rfind($pattern)
+ }
- #[inline]
- fn is_suffix_of(&self, chars: &str) -> bool {
- chars.ends_with(*self)
- }
+ #[inline]
+ fn is_suffix_of(&$self, chars: &str) -> bool {
+ chars.ends_with($pattern)
+ }
- fn fold_splits<'ch, F>(&self, chars: &'ch str, folder: F, skip_last: bool) -> F
- where
- F: Folder<&'ch str>,
- {
- let mut split = chars.split(*self);
- if skip_last {
- split.next_back();
+ fn fold_splits<'ch, F>(&$self, chars: &'ch str, folder: F, skip_last: bool) -> F
+ where
+ F: Folder<&'ch str>,
+ {
+ let mut split = chars.split($pattern);
+ if skip_last {
+ split.next_back();
+ }
+ folder.consume_iter(split)
}
- folder.consume_iter(split)
- }
- fn fold_matches<'ch, F>(&self, chars: &'ch str, folder: F) -> F
- where
- F: Folder<&'ch str>,
- {
- folder.consume_iter(chars.matches(*self))
- }
+ fn fold_matches<'ch, F>(&$self, chars: &'ch str, folder: F) -> F
+ where
+ F: Folder<&'ch str>,
+ {
+ folder.consume_iter(chars.matches($pattern))
+ }
- fn fold_match_indices<'ch, F>(&self, chars: &'ch str, folder: F, base: usize) -> F
- where
- F: Folder<(usize, &'ch str)>,
- {
- folder.consume_iter(chars.match_indices(*self).map(offset(base)))
+ fn fold_match_indices<'ch, F>(&$self, chars: &'ch str, folder: F, base: usize) -> F
+ where
+ F: Folder<(usize, &'ch str)>,
+ {
+ folder.consume_iter(chars.match_indices($pattern).map(offset(base)))
+ }
}
}
-impl<FN: Sync + Send + Fn(char) -> bool> Pattern for FN {
- private_impl! {}
-
- fn find_in(&self, chars: &str) -> Option<usize> {
- chars.find(self)
- }
-
- fn rfind_in(&self, chars: &str) -> Option<usize> {
- chars.rfind(self)
- }
-
- fn is_suffix_of(&self, chars: &str) -> bool {
- chars.ends_with(self)
- }
-
- fn fold_splits<'ch, F>(&self, chars: &'ch str, folder: F, skip_last: bool) -> F
- where
- F: Folder<&'ch str>,
- {
- let mut split = chars.split(self);
- if skip_last {
- split.next_back();
- }
- folder.consume_iter(split)
- }
+impl Pattern for char {
+ impl_pattern!(&self => *self);
+}
- fn fold_matches<'ch, F>(&self, chars: &'ch str, folder: F) -> F
- where
- F: Folder<&'ch str>,
- {
- folder.consume_iter(chars.matches(self))
- }
+impl Pattern for &[char] {
+ impl_pattern!(&self => *self);
+}
- fn fold_match_indices<'ch, F>(&self, chars: &'ch str, folder: F, base: usize) -> F
- where
- F: Folder<(usize, &'ch str)>,
- {
- folder.consume_iter(chars.match_indices(self).map(offset(base)))
- }
+impl<FN: Sync + Send + Fn(char) -> bool> Pattern for FN {
+ impl_pattern!(&self => self);
}
// /////////////////////////////////////////////////////////////////////////