Skip to content

Commit 2fd2670

Browse files
committed
Unify computation of length in EscapeUnicode
The `offset` value was computed both in `next` and in `size_hint`; computing it in a single place ensures consistency and makes it easier to apply improvements. The value is now computed as soon as the iterator is constructed. This means that the time to compute it is spent immediately and cannot be avoided, but it also guarantees that it is only spent once.
1 parent 035f4cc commit 2fd2670

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

src/libcore/char.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,15 @@ impl CharExt for char {
299299

300300
#[inline]
301301
fn escape_unicode(self) -> EscapeUnicode {
302-
EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
302+
let mut n = 0;
303+
while (self as u32) >> (4 * (n + 1)) != 0 {
304+
n += 1;
305+
}
306+
EscapeUnicode {
307+
c: self,
308+
state: EscapeUnicodeState::Backslash,
309+
offset: n,
310+
}
303311
}
304312

305313
#[inline]
@@ -420,15 +428,16 @@ pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<usize> {
420428
#[stable(feature = "rust1", since = "1.0.0")]
421429
pub struct EscapeUnicode {
422430
c: char,
423-
state: EscapeUnicodeState
431+
state: EscapeUnicodeState,
432+
offset: usize,
424433
}
425434

426435
#[derive(Clone)]
427436
enum EscapeUnicodeState {
428437
Backslash,
429438
Type,
430439
LeftBrace,
431-
Value(usize),
440+
Value,
432441
RightBrace,
433442
Done,
434443
}
@@ -448,19 +457,15 @@ impl Iterator for EscapeUnicode {
448457
Some('u')
449458
}
450459
EscapeUnicodeState::LeftBrace => {
451-
let mut n = 0;
452-
while (self.c as u32) >> (4 * (n + 1)) != 0 {
453-
n += 1;
454-
}
455-
self.state = EscapeUnicodeState::Value(n);
460+
self.state = EscapeUnicodeState::Value;
456461
Some('{')
457462
}
458-
EscapeUnicodeState::Value(offset) => {
459-
let c = from_digit(((self.c as u32) >> (offset * 4)) & 0xf, 16).unwrap();
460-
if offset == 0 {
463+
EscapeUnicodeState::Value => {
464+
let c = from_digit(((self.c as u32) >> (self.offset * 4)) & 0xf, 16).unwrap();
465+
if self.offset == 0 {
461466
self.state = EscapeUnicodeState::RightBrace;
462467
} else {
463-
self.state = EscapeUnicodeState::Value(offset - 1);
468+
self.offset -= 1;
464469
}
465470
Some(c)
466471
}
@@ -473,18 +478,15 @@ impl Iterator for EscapeUnicode {
473478
}
474479

475480
fn size_hint(&self) -> (usize, Option<usize>) {
476-
let mut n = 0;
477-
while (self.c as usize) >> (4 * (n + 1)) != 0 {
478-
n += 1;
479-
}
480481
let n = match self.state {
481-
EscapeUnicodeState::Backslash => n + 5,
482-
EscapeUnicodeState::Type => n + 4,
483-
EscapeUnicodeState::LeftBrace => n + 3,
484-
EscapeUnicodeState::Value(offset) => offset + 2,
482+
EscapeUnicodeState::Backslash => 5,
483+
EscapeUnicodeState::Type => 4,
484+
EscapeUnicodeState::LeftBrace => 3,
485+
EscapeUnicodeState::Value => 2,
485486
EscapeUnicodeState::RightBrace => 1,
486487
EscapeUnicodeState::Done => 0,
487488
};
489+
let n = n + self.offset;
488490
(n, Some(n))
489491
}
490492
}

0 commit comments

Comments
 (0)