about summary refs log tree commit diff
path: root/src/libstd_unicode
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-05-10 03:27:36 +0000
committerbors <bors@rust-lang.org>2017-05-10 03:27:36 +0000
commit58b33ad70cdd11f9ce7b5874c6effab9627e51aa (patch)
tree47ef239ec314ea983a951ce63e5639195f2ff181 /src/libstd_unicode
parentdb1c9eb2bd8d179e5a7547bd0f13f6a5586d6ac7 (diff)
parent41aeb9d4ec26c4b6fb118483d2d1375e04b2c62f (diff)
downloadrust-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.rs2
-rw-r--r--src/libstd_unicode/u_str.rs54
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;