Skip to content

Commit da5a0cd

Browse files
committed
De-duplicate number formatting implementations for smaller code size
Instead of inlining the same logic into every number formatting implementation, pull it out into a function that each of the number formatting impls call into.
1 parent b2c6b8c commit da5a0cd

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

src/libcore/fmt/num.rs

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -178,45 +178,36 @@ integer! { i32, u32 }
178178
integer! { i64, u64 }
179179
integer! { i128, u128 }
180180

181-
const DEC_DIGITS_LUT: &'static[u8] =
181+
182+
static DEC_DIGITS_LUT: &[u8; 200] =
182183
b"0001020304050607080910111213141516171819\
183184
2021222324252627282930313233343536373839\
184185
4041424344454647484950515253545556575859\
185186
6061626364656667686970717273747576777879\
186187
8081828384858687888990919293949596979899";
187188

188189
macro_rules! impl_Display {
189-
($($t:ident),*: $conv_fn:ident) => ($(
190-
#[stable(feature = "rust1", since = "1.0.0")]
191-
impl fmt::Display for $t {
192-
#[allow(unused_comparisons)]
193-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
194-
let is_nonnegative = *self >= 0;
195-
let mut n = if is_nonnegative {
196-
self.$conv_fn()
197-
} else {
198-
// convert the negative num to positive by summing 1 to it's 2 complement
199-
(!self.$conv_fn()).wrapping_add(1)
200-
};
190+
($($t:ident),* as $u:ident via $conv_fn:ident named $name:ident) => {
191+
fn $name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter) -> fmt::Result {
201192
let mut buf = uninitialized_array![u8; 39];
202193
let mut curr = buf.len() as isize;
203194
let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
204195
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
205196

206197
unsafe {
207198
// need at least 16 bits for the 4-characters-at-a-time to work.
208-
if ::mem::size_of::<$t>() >= 2 {
209-
// eagerly decode 4 characters at a time
210-
while n >= 10000 {
211-
let rem = (n % 10000) as isize;
212-
n /= 10000;
199+
assert!(::mem::size_of::<$u>() >= 2);
200+
201+
// eagerly decode 4 characters at a time
202+
while n >= 10000 {
203+
let rem = (n % 10000) as isize;
204+
n /= 10000;
213205

214-
let d1 = (rem / 100) << 1;
215-
let d2 = (rem % 100) << 1;
216-
curr -= 4;
217-
ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
218-
ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2);
219-
}
206+
let d1 = (rem / 100) << 1;
207+
let d2 = (rem % 100) << 1;
208+
curr -= 4;
209+
ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2);
210+
ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2);
220211
}
221212

222213
// if we reach here numbers are <= 9999, so at most 4 chars long
@@ -247,15 +238,31 @@ macro_rules! impl_Display {
247238
};
248239
f.pad_integral(is_nonnegative, "", buf_slice)
249240
}
250-
})*);
241+
242+
$(
243+
#[stable(feature = "rust1", since = "1.0.0")]
244+
impl fmt::Display for $t {
245+
#[allow(unused_comparisons)]
246+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247+
let is_nonnegative = *self >= 0;
248+
let n = if is_nonnegative {
249+
self.$conv_fn()
250+
} else {
251+
// convert the negative num to positive by summing 1 to it's 2 complement
252+
(!self.$conv_fn()).wrapping_add(1)
253+
};
254+
$name(n, is_nonnegative, f)
255+
}
256+
})*
257+
};
251258
}
252259

253-
impl_Display!(i8, u8, i16, u16, i32, u32: to_u32);
254-
impl_Display!(i64, u64: to_u64);
255-
impl_Display!(i128, u128: to_u128);
260+
impl_Display!(i8, u8, i16, u16, i32, u32 as u32 via to_u32 named fmt_u32);
261+
impl_Display!(i64, u64 as u64 via to_u64 named fmt_u64);
262+
impl_Display!(i128, u128 as u128 via to_u128 named fmt_u128);
256263
#[cfg(target_pointer_width = "16")]
257-
impl_Display!(isize, usize: to_u16);
264+
impl_Display!(isize, usize as u16 via to_u16 named fmt_usize);
258265
#[cfg(target_pointer_width = "32")]
259-
impl_Display!(isize, usize: to_u32);
266+
impl_Display!(isize, usize as u32 via to_u32 named fmt_usize);
260267
#[cfg(target_pointer_width = "64")]
261-
impl_Display!(isize, usize: to_u64);
268+
impl_Display!(isize, usize as u64 via to_u64 named fmt_usize);

0 commit comments

Comments
 (0)