diff options
| author | bors <bors@rust-lang.org> | 2017-05-10 03:27:36 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-05-10 03:27:36 +0000 |
| commit | 58b33ad70cdd11f9ce7b5874c6effab9627e51aa (patch) | |
| tree | 47ef239ec314ea983a951ce63e5639195f2ff181 /src/libstd_unicode | |
| parent | db1c9eb2bd8d179e5a7547bd0f13f6a5586d6ac7 (diff) | |
| parent | 41aeb9d4ec26c4b6fb118483d2d1375e04b2c62f (diff) | |
| download | rust-58b33ad70cdd11f9ce7b5874c6effab9627e51aa.tar.gz rust-58b33ad70cdd11f9ce7b5874c6effab9627e51aa.zip | |
Auto merge of #41659 - bluss:clone-split-whitespace, r=aturon
impl Clone for .split_whitespace() Use custom closure structs for the predicates so that the iterator's clone can simply be derived. This should also reduce virtual call overhead by not using function pointers. Fixes #41655
Diffstat (limited to 'src/libstd_unicode')
| -rw-r--r-- | src/libstd_unicode/lib.rs | 2 | ||||
| -rw-r--r-- | src/libstd_unicode/u_str.rs | 54 |
2 files changed, 44 insertions, 12 deletions
diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs index 7e5ab1a54ab..d63878a7a7c 100644 --- a/src/libstd_unicode/lib.rs +++ b/src/libstd_unicode/lib.rs @@ -36,9 +36,11 @@ #![feature(core_char_ext)] #![feature(decode_utf8)] #![feature(fused)] +#![feature(fn_traits)] #![feature(lang_items)] #![feature(staged_api)] #![feature(try_from)] +#![feature(unboxed_closures)] mod tables; mod u_str; diff --git a/src/libstd_unicode/u_str.rs b/src/libstd_unicode/u_str.rs index 770b67acd49..1454168d2d5 100644 --- a/src/libstd_unicode/u_str.rs +++ b/src/libstd_unicode/u_str.rs @@ -26,8 +26,9 @@ use core::str::Split; /// [`split_whitespace`]: ../../std/primitive.str.html#method.split_whitespace /// [`str`]: ../../std/primitive.str.html #[stable(feature = "split_whitespace", since = "1.1.0")] +#[derive(Clone)] pub struct SplitWhitespace<'a> { - inner: Filter<Split<'a, fn(char) -> bool>, fn(&&str) -> bool>, + inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>, } /// Methods for Unicode string slices @@ -44,17 +45,7 @@ pub trait UnicodeStr { impl UnicodeStr for str { #[inline] fn split_whitespace(&self) -> SplitWhitespace { - fn is_not_empty(s: &&str) -> bool { - !s.is_empty() - } - let is_not_empty: fn(&&str) -> bool = is_not_empty; // coerce to fn pointer - - fn is_whitespace(c: char) -> bool { - c.is_whitespace() - } - let is_whitespace: fn(char) -> bool = is_whitespace; // coerce to fn pointer - - SplitWhitespace { inner: self.split(is_whitespace).filter(is_not_empty) } + SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) } } #[inline] @@ -139,6 +130,45 @@ impl<I> Iterator for Utf16Encoder<I> impl<I> FusedIterator for Utf16Encoder<I> where I: FusedIterator<Item = char> {} +#[derive(Clone)] +struct IsWhitespace; + +impl FnOnce<(char, )> for IsWhitespace { + type Output = bool; + + #[inline] + extern "rust-call" fn call_once(mut self, arg: (char, )) -> bool { + self.call_mut(arg) + } +} + +impl FnMut<(char, )> for IsWhitespace { + #[inline] + extern "rust-call" fn call_mut(&mut self, arg: (char, )) -> bool { + arg.0.is_whitespace() + } +} + +#[derive(Clone)] +struct IsNotEmpty; + +impl<'a, 'b> FnOnce<(&'a &'b str, )> for IsNotEmpty { + type Output = bool; + + #[inline] + extern "rust-call" fn call_once(mut self, arg: (&&str, )) -> bool { + self.call_mut(arg) + } +} + +impl<'a, 'b> FnMut<(&'a &'b str, )> for IsNotEmpty { + #[inline] + extern "rust-call" fn call_mut(&mut self, arg: (&&str, )) -> bool { + !arg.0.is_empty() + } +} + + #[stable(feature = "split_whitespace", since = "1.1.0")] impl<'a> Iterator for SplitWhitespace<'a> { type Item = &'a str; |
