aboutsummaryrefslogtreecommitdiff
path: root/libcore/char.rs
diff options
context:
space:
mode:
Diffstat (limited to 'libcore/char.rs')
-rw-r--r--libcore/char.rs96
1 files changed, 64 insertions, 32 deletions
diff --git a/libcore/char.rs b/libcore/char.rs
index 1404038..d80b456 100644
--- a/libcore/char.rs
+++ b/libcore/char.rs
@@ -15,11 +15,9 @@
#![allow(non_snake_case)]
#![stable(feature = "core_char", since = "1.2.0")]
-use iter::Iterator;
+use prelude::v1::*;
+
use mem::transmute;
-use option::Option::{None, Some};
-use option::Option;
-use slice::SliceExt;
// UTF-8 ranges and tags for encoding characters
const TAG_CONT: u8 = 0b1000_0000;
@@ -413,14 +411,17 @@ pub struct EscapeUnicode {
hex_digit_idx: usize,
}
+// The enum values are ordered so that their representation is the
+// same as the remaining length (besides the hexadecimal digits). This
+// likely makes `len()` a single load from memory) and inline-worth.
#[derive(Clone, Debug)]
enum EscapeUnicodeState {
- Backslash,
- Type,
- LeftBrace,
- Value,
- RightBrace,
Done,
+ RightBrace,
+ Value,
+ LeftBrace,
+ Type,
+ Backslash,
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -459,18 +460,44 @@ impl Iterator for EscapeUnicode {
}
}
+ #[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
- let n = match self.state {
- EscapeUnicodeState::Backslash => 5,
- EscapeUnicodeState::Type => 4,
- EscapeUnicodeState::LeftBrace => 3,
- EscapeUnicodeState::Value => 2,
- EscapeUnicodeState::RightBrace => 1,
- EscapeUnicodeState::Done => 0,
- };
- let n = n + self.hex_digit_idx;
+ let n = self.len();
(n, Some(n))
}
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ fn last(self) -> Option<char> {
+ match self.state {
+ EscapeUnicodeState::Done => None,
+
+ EscapeUnicodeState::RightBrace |
+ EscapeUnicodeState::Value |
+ EscapeUnicodeState::LeftBrace |
+ EscapeUnicodeState::Type |
+ EscapeUnicodeState::Backslash => Some('}'),
+ }
+ }
+}
+
+#[stable(feature = "exact_size_escape", since = "1.11.0")]
+impl ExactSizeIterator for EscapeUnicode {
+ #[inline]
+ fn len(&self) -> usize {
+ // The match is a single memory access with no branching
+ self.hex_digit_idx + match self.state {
+ EscapeUnicodeState::Done => 0,
+ EscapeUnicodeState::RightBrace => 1,
+ EscapeUnicodeState::Value => 2,
+ EscapeUnicodeState::LeftBrace => 3,
+ EscapeUnicodeState::Type => 4,
+ EscapeUnicodeState::Backslash => 5,
+ }
+ }
}
/// An iterator that yields the literal escape code of a `char`.
@@ -488,9 +515,9 @@ pub struct EscapeDefault {
#[derive(Clone, Debug)]
enum EscapeDefaultState {
- Backslash(char),
- Char(char),
Done,
+ Char(char),
+ Backslash(char),
Unicode(EscapeUnicode),
}
@@ -513,22 +540,15 @@ impl Iterator for EscapeDefault {
}
}
+ #[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
- match self.state {
- EscapeDefaultState::Char(_) => (1, Some(1)),
- EscapeDefaultState::Backslash(_) => (2, Some(2)),
- EscapeDefaultState::Unicode(ref iter) => iter.size_hint(),
- EscapeDefaultState::Done => (0, Some(0)),
- }
+ let n = self.len();
+ (n, Some(n))
}
+ #[inline]
fn count(self) -> usize {
- match self.state {
- EscapeDefaultState::Char(_) => 1,
- EscapeDefaultState::Unicode(iter) => iter.count(),
- EscapeDefaultState::Done => 0,
- EscapeDefaultState::Backslash(_) => 2,
- }
+ self.len()
}
fn nth(&mut self, n: usize) -> Option<char> {
@@ -568,6 +588,18 @@ impl Iterator for EscapeDefault {
}
}
+#[stable(feature = "exact_size_escape", since = "1.11.0")]
+impl ExactSizeIterator for EscapeDefault {
+ fn len(&self) -> usize {
+ match self.state {
+ EscapeDefaultState::Done => 0,
+ EscapeDefaultState::Char(_) => 1,
+ EscapeDefaultState::Backslash(_) => 2,
+ EscapeDefaultState::Unicode(ref iter) => iter.len(),
+ }
+ }
+}
+
/// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
/// value.
///