diff --git a/src/libcollections/benches/str.rs b/src/libcollections/benches/str.rs index 7f727078101c4..fc4063fae9277 100644 --- a/src/libcollections/benches/str.rs +++ b/src/libcollections/benches/str.rs @@ -195,30 +195,34 @@ fn bench_contains_equal(b: &mut Bencher) { }) } + macro_rules! make_test_inner { - ($s:ident, $code:expr, $name:ident, $str:expr) => { + ($s:ident, $code:expr, $name:ident, $str:expr, $iters:expr) => { #[bench] fn $name(bencher: &mut Bencher) { let mut $s = $str; black_box(&mut $s); - bencher.iter(|| $code); + bencher.iter(|| for _ in 0..$iters { black_box($code); }); } } } macro_rules! make_test { ($name:ident, $s:ident, $code:expr) => { + make_test!($name, $s, $code, 1); + }; + ($name:ident, $s:ident, $code:expr, $iters:expr) => { mod $name { use test::Bencher; use test::black_box; // Short strings: 65 bytes each make_test_inner!($s, $code, short_ascii, - "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!"); + "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!", $iters); make_test_inner!($s, $code, short_mixed, - "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!"); + "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!", $iters); make_test_inner!($s, $code, short_pile_of_poo, - "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!"); + "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!", $iters); make_test_inner!($s, $code, long_lorem_ipsum,"\ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \ ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \ @@ -253,7 +257,7 @@ Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \ vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \ leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \ -malesuada sollicitudin quam eu fermentum!"); +malesuada sollicitudin quam eu fermentum!", $iters); } } } @@ -288,6 +292,13 @@ make_test!(find_zzz_char, s, s.find('\u{1F4A4}')); make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}')); make_test!(find_zzz_str, s, s.find("\u{1F4A4}")); +make_test!(starts_with_ascii_char, s, s.starts_with('/'), 1024); +make_test!(ends_with_ascii_char, s, s.ends_with('/'), 1024); +make_test!(starts_with_unichar, s, s.starts_with('\u{1F4A4}'), 1024); +make_test!(ends_with_unichar, s, s.ends_with('\u{1F4A4}'), 1024); +make_test!(starts_with_str, s, s.starts_with("💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩"), 1024); +make_test!(ends_with_str, s, s.ends_with("💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩"), 1024); + make_test!(split_space_char, s, s.split(' ').count()); make_test!(split_terminator_space_char, s, s.split_terminator(' ').count()); diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 5f4578bbeb368..7e67befb700db 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -813,6 +813,7 @@ impl str { /// assert!(!bananas.contains("apples")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { core_str::StrExt::contains(self, pat) } @@ -900,6 +901,7 @@ impl str { /// assert_eq!(s.find(x), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option { core_str::StrExt::find(self, pat) } @@ -944,6 +946,7 @@ impl str { /// assert_eq!(s.rfind(x), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option where P::Searcher: ReverseSearcher<'a> { @@ -1057,6 +1060,7 @@ impl str { /// /// [`split_whitespace`]: #method.split_whitespace #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { core_str::StrExt::split(self, pat) } @@ -1106,6 +1110,7 @@ impl str { /// assert_eq!(v, ["ghi", "def", "abc"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1152,6 +1157,7 @@ impl str { /// assert_eq!(v, ["A", "", "B", ""]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { core_str::StrExt::split_terminator(self, pat) } @@ -1195,6 +1201,7 @@ impl str { /// assert_eq!(v, ["", "B", "", "A"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1247,6 +1254,7 @@ impl str { /// assert_eq!(v, ["abc", "defXghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> { core_str::StrExt::splitn(self, n, pat) } @@ -1294,6 +1302,7 @@ impl str { /// assert_eq!(v, ["ghi", "abc1def"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1334,6 +1343,7 @@ impl str { /// assert_eq!(v, ["1", "2", "3"]); /// ``` #[stable(feature = "str_matches", since = "1.2.0")] + #[inline] pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> { core_str::StrExt::matches(self, pat) } @@ -1370,6 +1380,7 @@ impl str { /// assert_eq!(v, ["3", "2", "1"]); /// ``` #[stable(feature = "str_matches", since = "1.2.0")] + #[inline] pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1415,6 +1426,7 @@ impl str { /// assert_eq!(v, [(0, "aba")]); // only the first `aba` /// ``` #[stable(feature = "str_match_indices", since = "1.5.0")] + #[inline] pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> { core_str::StrExt::match_indices(self, pat) } @@ -1457,6 +1469,7 @@ impl str { /// assert_eq!(v, [(2, "aba")]); // only the last `aba` /// ``` #[stable(feature = "str_match_indices", since = "1.5.0")] + #[inline] pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1737,6 +1750,7 @@ impl str { /// assert_eq!(s, s.replace("cookie monster", "little lamb")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String { let mut result = String::new(); let mut last_end = 0; diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 8493afe98bc57..4918e37eb35f0 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -429,7 +429,33 @@ impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {} /// Searches for chars that are equal to a given char impl<'a> Pattern<'a> for char { - pattern_methods!(CharSearcher<'a>, CharEqPattern, CharSearcher); + type Searcher = CharSearcher<'a>; + + #[inline] + fn into_searcher(self, haystack: &'a str) -> Self::Searcher { + CharSearcher(CharEqPattern(self).into_searcher(haystack)) + } + + #[inline] + fn is_contained_in(self, haystack: &'a str) -> bool { + if (self as u32) < 128 { + haystack.as_bytes().contains(&(self as u8)) + } else { + let mut buffer = [0u8; 4]; + self.encode_utf8(&mut buffer).is_contained_in(haystack) + } + } + + #[inline] + fn is_prefix_of(self, haystack: &'a str) -> bool { + CharEqPattern(self).is_prefix_of(haystack) + } + + #[inline] + fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a> + { + CharEqPattern(self).is_suffix_of(haystack) + } } /////////////////////////////////////////////////////////////////////////////