Skip to content

Commit fb59e5d

Browse files
EliasHolzmanngitbot
authored and
gitbot
committed
Refactored FormattingOptions to use a bitmask for storing flags
1 parent b0f43c5 commit fb59e5d

File tree

2 files changed

+52
-54
lines changed

2 files changed

+52
-54
lines changed

core/src/fmt/mod.rs

+46-44
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,11 @@ pub enum DebugAsHex {
288288
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
289289
#[unstable(feature = "formatting_options", issue = "118117")]
290290
pub struct FormattingOptions {
291-
sign: Option<Sign>,
292-
sign_aware_zero_pad: bool,
293-
alternate: bool,
291+
flags: u32,
294292
fill: char,
295293
align: Option<Alignment>,
296294
width: Option<usize>,
297295
precision: Option<usize>,
298-
debug_as_hex: Option<DebugAsHex>,
299296
}
300297

301298
impl FormattingOptions {
@@ -312,14 +309,11 @@ impl FormattingOptions {
312309
#[unstable(feature = "formatting_options", issue = "118117")]
313310
pub const fn new() -> Self {
314311
Self {
315-
sign: None,
316-
sign_aware_zero_pad: false,
317-
alternate: false,
312+
flags: 0,
318313
fill: ' ',
319314
align: None,
320315
width: None,
321316
precision: None,
322-
debug_as_hex: None,
323317
}
324318
}
325319

@@ -333,15 +327,24 @@ impl FormattingOptions {
333327
/// - `-`: Currently not used
334328
#[unstable(feature = "formatting_options", issue = "118117")]
335329
pub const fn sign(&mut self, sign: Option<Sign>) -> &mut Self {
336-
self.sign = sign;
330+
self.flags = self.flags & !(1 << rt::Flag::SignMinus as u32 | 1 << rt::Flag::SignPlus as u32);
331+
match sign {
332+
None => {},
333+
Some(Sign::Plus) => self.flags |= 1 << rt::Flag::SignPlus as u32,
334+
Some(Sign::Minus) => self.flags |= 1 << rt::Flag::SignMinus as u32,
335+
}
337336
self
338337
}
339338
/// Sets or unsets the `0` flag.
340339
///
341340
/// This is used to indicate for integer formats that the padding to width should both be done with a 0 character as well as be sign-aware
342341
#[unstable(feature = "formatting_options", issue = "118117")]
343342
pub const fn sign_aware_zero_pad(&mut self, sign_aware_zero_pad: bool) -> &mut Self {
344-
self.sign_aware_zero_pad = sign_aware_zero_pad;
343+
if sign_aware_zero_pad {
344+
self.flags |= 1 << rt::Flag::SignAwareZeroPad as u32
345+
} else {
346+
self.flags &= !(1 << rt::Flag::SignAwareZeroPad as u32)
347+
}
345348
self
346349
}
347350
/// Sets or unsets the `#` flag.
@@ -354,7 +357,11 @@ impl FormattingOptions {
354357
/// - [`Binary`] - precedes the argument with a `0o`
355358
#[unstable(feature = "formatting_options", issue = "118117")]
356359
pub const fn alternate(&mut self, alternate: bool) -> &mut Self {
357-
self.alternate = alternate;
360+
if alternate {
361+
self.flags |= 1 << rt::Flag::Alternate as u32
362+
} else {
363+
self.flags &= !(1 << rt::Flag::Alternate as u32)
364+
}
358365
self
359366
}
360367
/// Sets the fill character.
@@ -406,24 +413,36 @@ impl FormattingOptions {
406413
/// hexadecimal or normal integers
407414
#[unstable(feature = "formatting_options", issue = "118117")]
408415
pub const fn debug_as_hex(&mut self, debug_as_hex: Option<DebugAsHex>) -> &mut Self {
409-
self.debug_as_hex = debug_as_hex;
416+
self.flags = self.flags & !(1 << rt::Flag::DebugUpperHex as u32 | 1 << rt::Flag::DebugLowerHex as u32);
417+
match debug_as_hex {
418+
None => {},
419+
Some(DebugAsHex::Upper) => self.flags |= 1 << rt::Flag::DebugUpperHex as u32,
420+
Some(DebugAsHex::Lower) => self.flags |= 1 << rt::Flag::DebugLowerHex as u32,
421+
}
410422
self
411423
}
412424

413425
/// Returns the current sign (the `+` or the `-` flag).
414426
#[unstable(feature = "formatting_options", issue = "118117")]
415427
pub const fn get_sign(&self) -> Option<Sign> {
416-
self.sign
428+
const SIGN_PLUS_BITFIELD: u32 = 1 << rt::Flag::SignPlus as u32;
429+
const SIGN_MINUS_BITFIELD: u32 = 1 << rt::Flag::SignMinus as u32;
430+
match self.flags & ((1 << rt::Flag::SignPlus as u32) | (1 << rt::Flag::SignMinus as u32)) {
431+
SIGN_PLUS_BITFIELD => Some(Sign::Plus),
432+
SIGN_MINUS_BITFIELD => Some(Sign::Minus),
433+
0 => None,
434+
_ => panic!("Invalid sign bits set in flags"),
435+
}
417436
}
418437
/// Returns the current `0` flag.
419438
#[unstable(feature = "formatting_options", issue = "118117")]
420439
pub const fn get_sign_aware_zero_pad(&self) -> bool {
421-
self.sign_aware_zero_pad
440+
self.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0
422441
}
423442
/// Returns the current `#` flag.
424443
#[unstable(feature = "formatting_options", issue = "118117")]
425444
pub const fn get_alternate(&self) -> bool {
426-
self.alternate
445+
self.flags & (1 << rt::Flag::Alternate as u32) != 0
427446
}
428447
/// Returns the current fill character.
429448
#[unstable(feature = "formatting_options", issue = "118117")]
@@ -448,7 +467,14 @@ impl FormattingOptions {
448467
/// Returns the current precision.
449468
#[unstable(feature = "formatting_options", issue = "118117")]
450469
pub const fn get_debug_as_hex(&self) -> Option<DebugAsHex> {
451-
self.debug_as_hex
470+
const DEBUG_UPPER_BITFIELD: u32 = 1 << rt::Flag::DebugUpperHex as u32;
471+
const DEBUG_LOWER_BITFIELD: u32 = 1 << rt::Flag::DebugLowerHex as u32;
472+
match self.flags & ((1 << rt::Flag::DebugUpperHex as u32) | (1 << rt::Flag::DebugLowerHex as u32)) {
473+
DEBUG_UPPER_BITFIELD => Some(DebugAsHex::Upper),
474+
DEBUG_LOWER_BITFIELD => Some(DebugAsHex::Lower),
475+
0 => None,
476+
_ => panic!("Invalid hex debug bits set in flags"),
477+
}
452478
}
453479

454480
/// Creates a [`Formatter`] that writes its output to the given [`Write`] trait.
@@ -463,37 +489,13 @@ impl FormattingOptions {
463489
#[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")]
464490
/// Flags for formatting
465491
pub fn flags(&mut self, flags: u32) {
466-
self.sign = if flags & (1 << rt::Flag::SignPlus as u32) != 0 {
467-
Some(Sign::Plus)
468-
} else if flags & (1 << rt::Flag::SignMinus as u32) != 0 {
469-
Some(Sign::Minus)
470-
} else {
471-
None
472-
};
473-
self.alternate = (flags & (1 << rt::Flag::Alternate as u32)) != 0;
474-
self.sign_aware_zero_pad = (flags & (1 << rt::Flag::SignAwareZeroPad as u32)) != 0;
475-
self.debug_as_hex = if flags & (1 << rt::Flag::DebugLowerHex as u32) != 0 {
476-
Some(DebugAsHex::Lower)
477-
} else if flags & (1 << rt::Flag::DebugUpperHex as u32) != 0 {
478-
Some(DebugAsHex::Upper)
479-
} else {
480-
None
481-
};
492+
self.flags = flags
482493
}
483494
#[doc(hidden)]
484495
#[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")]
485496
/// Flags for formatting
486497
pub fn get_flags(&self) -> u32 {
487-
<bool as Into<u32>>::into(self.get_sign() == Some(Sign::Plus)) << rt::Flag::SignPlus as u32
488-
| <bool as Into<u32>>::into(self.get_sign() == Some(Sign::Minus))
489-
<< rt::Flag::SignMinus as u32
490-
| <bool as Into<u32>>::into(self.get_alternate()) << rt::Flag::Alternate as u32
491-
| <bool as Into<u32>>::into(self.get_sign_aware_zero_pad())
492-
<< rt::Flag::SignAwareZeroPad as u32
493-
| <bool as Into<u32>>::into(self.debug_as_hex == Some(DebugAsHex::Lower))
494-
<< rt::Flag::DebugLowerHex as u32
495-
| <bool as Into<u32>>::into(self.debug_as_hex == Some(DebugAsHex::Upper))
496-
<< rt::Flag::DebugUpperHex as u32
498+
self.flags
497499
}
498500
}
499501

@@ -2161,11 +2163,11 @@ impl<'a> Formatter<'a> {
21612163
// FIXME: Decide what public API we want for these two flags.
21622164
// https://github.com/rust-lang/rust/issues/48584
21632165
fn debug_lower_hex(&self) -> bool {
2164-
self.options.debug_as_hex == Some(DebugAsHex::Lower)
2166+
self.options.flags & (1 << rt::Flag::DebugLowerHex as u32) != 0
21652167
}
21662168

21672169
fn debug_upper_hex(&self) -> bool {
2168-
self.options.debug_as_hex == Some(DebugAsHex::Upper)
2170+
self.options.flags & (1 << rt::Flag::DebugUpperHex as u32) != 0
21692171
}
21702172

21712173
/// Creates a [`DebugStruct`] builder designed to assist with creation of

core/tests/fmt/mod.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,17 @@ fn formatting_options_flags() {
5858
for alternate in [true, false] {
5959
for sign_aware_zero_pad in [true, false] {
6060
for debug_as_hex in [None, Some(DebugAsHex::Lower), Some(DebugAsHex::Upper)] {
61-
let mut original_formatting_options = FormattingOptions::new();
62-
original_formatting_options
61+
let mut formatting_options = FormattingOptions::new();
62+
formatting_options
6363
.sign(sign)
6464
.sign_aware_zero_pad(sign_aware_zero_pad)
6565
.alternate(alternate)
6666
.debug_as_hex(debug_as_hex);
6767

68-
let mut formatting_options_with_flags_set_to_self = original_formatting_options;
69-
formatting_options_with_flags_set_to_self
70-
.flags(formatting_options_with_flags_set_to_self.get_flags());
71-
72-
assert_eq!(
73-
original_formatting_options, formatting_options_with_flags_set_to_self,
74-
"Reading and setting flags changes FormattingOptions; Sign({sign:?}), Alternate({alternate:?}). DebugAsHex({debug_as_hex:?})"
75-
)
68+
assert_eq!(formatting_options.get_sign(), sign);
69+
assert_eq!(formatting_options.get_alternate(), alternate);
70+
assert_eq!(formatting_options.get_sign_aware_zero_pad(), sign_aware_zero_pad);
71+
assert_eq!(formatting_options.get_debug_as_hex(), debug_as_hex);
7672
}
7773
}
7874
}

0 commit comments

Comments
 (0)