diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs index 7e5ab1a54ab3a..d63878a7a7c24 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 770b67acd49ef..1454168d2d5cc 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 bool>, fn(&&str) -> bool>, + inner: Filter, 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 Iterator for Utf16Encoder impl FusedIterator for Utf16Encoder where I: FusedIterator {} +#[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;