Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1f77424

Browse files
fmt::DisplayInt abstraction obsolete with better macro
1 parent 4ad8606 commit 1f77424

File tree

1 file changed

+72
-94
lines changed

1 file changed

+72
-94
lines changed

‎library/core/src/fmt/num.rs‎

Lines changed: 72 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,8 @@
33
use crate::fmt::NumBuffer;
44
use crate::mem::MaybeUninit;
55
use crate::num::fmt as numfmt;
6-
use crate::ops::{Div, Rem, Sub};
76
use crate::{fmt, ptr, slice, str};
87

9-
#[doc(hidden)]
10-
trait DisplayInt:
11-
PartialEq + PartialOrd + Div<Output = Self> + Rem<Output = Self> + Sub<Output = Self> + Copy
12-
{
13-
#[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))]
14-
fn to_u32(&self) -> u32;
15-
fn to_u64(&self) -> u64;
16-
fn to_u128(&self) -> u128;
17-
}
18-
19-
macro_rules! impl_int {
20-
($($t:ident)*) => (
21-
$(impl DisplayInt for $t {
22-
#[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))]
23-
fn to_u32(&self) -> u32 { *self as u32 }
24-
fn to_u64(&self) -> u64 { *self as u64 }
25-
fn to_u128(&self) -> u128 { *self as u128 }
26-
})*
27-
)
28-
}
29-
30-
impl_int! {
31-
i8 i16 i32 i64 i128 isize
32-
u8 u16 u32 u64 u128 usize
33-
}
34-
358
/// Formatting of integers with a non-decimal radix.
369
macro_rules! radix_integer {
3710
(fmt::$Trait:ident for $Signed:ident and $Unsigned:ident, $prefix:literal, $dig_tab:literal) => {
@@ -146,49 +119,58 @@ unsafe fn slice_buffer_to_str(buf: &[MaybeUninit<u8>], offset: usize) -> &str {
146119
}
147120

148121
macro_rules! impl_Display {
149-
($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
122+
($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => {
150123

151124
$(
125+
const _: () = {
126+
assert!($Signed::BITS <= $T::BITS, "need lossless conversion");
127+
assert!($Unsigned::BITS <= $T::BITS, "need lossless conversion");
128+
};
129+
152130
#[stable(feature = "rust1", since = "1.0.0")]
153-
impl fmt::Display for $unsigned {
131+
impl fmt::Display for $Unsigned {
154132
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155133
#[cfg(not(feature = "optimize_for_size"))]
156134
{
157-
const MAX_DEC_N: usize = $unsigned::MAX.ilog10() as usize + 1;
158-
// Buffer decimals for $unsigned with right alignment.
135+
const MAX_DEC_N: usize = $Unsigned::MAX.ilog10() as usize + 1;
136+
// Buffer decimals for self with right alignment.
159137
let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
160138

161139
// SAFETY: `buf` is always big enough to contain all the digits.
162140
unsafe { f.pad_integral(true, "", self._fmt(&mut buf)) }
163141
}
164142
#[cfg(feature = "optimize_for_size")]
165143
{
166-
$gen_name(self.$conv_fn(), true, f)
144+
// Lossless conversion (with as) is asserted at the top of
145+
// this macro.
146+
${concat($fmt_fn, _small)}(*self as $T, true, f)
167147
}
168148
}
169149
}
170150

171151
#[stable(feature = "rust1", since = "1.0.0")]
172-
impl fmt::Display for $signed {
152+
impl fmt::Display for $Signed {
173153
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174154
#[cfg(not(feature = "optimize_for_size"))]
175155
{
176-
const MAX_DEC_N: usize = $unsigned::MAX.ilog10() as usize + 1;
177-
// Buffer decimals for $unsigned with right alignment.
156+
const MAX_DEC_N: usize = $Unsigned::MAX.ilog10() as usize + 1;
157+
// Buffer decimals for self with right alignment.
178158
let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
179159

180160
// SAFETY: `buf` is always big enough to contain all the digits.
181161
unsafe { f.pad_integral(*self >= 0, "", self.unsigned_abs()._fmt(&mut buf)) }
182162
}
183163
#[cfg(feature = "optimize_for_size")]
184164
{
185-
return $gen_name(self.unsigned_abs().$conv_fn(), *self >= 0, f);
165+
// Lossless conversion (with as) is asserted at the top of
166+
// this macro.
167+
return ${concat($fmt_fn, _small)}(self.unsigned_abs() as $T, *self >= 0, f);
186168
}
187169
}
188170
}
189171

190172
#[cfg(not(feature = "optimize_for_size"))]
191-
impl $unsigned {
173+
impl $Unsigned {
192174
#[doc(hidden)]
193175
#[unstable(
194176
feature = "fmt_internals",
@@ -209,7 +191,7 @@ macro_rules! impl_Display {
209191
let mut remain = self;
210192

211193
// Format per four digits from the lookup table.
212-
// Four digits need a 16-bit $unsigned or wider.
194+
// Four digits need a 16-bit $Unsigned or wider.
213195
while size_of::<Self>() > 1 && remain > 999.try_into().expect("branch is not hit for types that cannot fit 999 (u8)") {
214196
// SAFETY: All of the decimals fit in buf due to MAX_DEC_N
215197
// and the while condition ensures at least 4 more decimals.
@@ -268,7 +250,7 @@ macro_rules! impl_Display {
268250
}
269251
}
270252

271-
impl $signed {
253+
impl $Signed {
272254
/// Allows users to write an integer (in signed decimal format) into a variable `buf` of
273255
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
274256
///
@@ -278,15 +260,15 @@ macro_rules! impl_Display {
278260
/// #![feature(int_format_into)]
279261
/// use core::fmt::NumBuffer;
280262
///
281-
#[doc = concat!("let n = 0", stringify!($signed), ";")]
263+
#[doc = concat!("let n = 0", stringify!($Signed), ";")]
282264
/// let mut buf = NumBuffer::new();
283265
/// assert_eq!(n.format_into(&mut buf), "0");
284266
///
285-
#[doc = concat!("let n1 = 32", stringify!($signed), ";")]
267+
#[doc = concat!("let n1 = 32", stringify!($Signed), ";")]
286268
/// assert_eq!(n1.format_into(&mut buf), "32");
287269
///
288-
#[doc = concat!("let n2 = ", stringify!($signed::MAX), ";")]
289-
#[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($signed::MAX), ".to_string());")]
270+
#[doc = concat!("let n2 = ", stringify!($Signed::MAX), ";")]
271+
#[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($Signed::MAX), ".to_string());")]
290272
/// ```
291273
#[unstable(feature = "int_format_into", issue = "138215")]
292274
pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
@@ -299,7 +281,9 @@ macro_rules! impl_Display {
299281
}
300282
#[cfg(feature = "optimize_for_size")]
301283
{
302-
offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.unsigned_abs().$conv_fn(), &mut buf.buf);
284+
// Lossless conversion (with as) is asserted at the top of
285+
// this macro.
286+
offset = ${concat($fmt_fn, _in_buf_small)}(self.unsigned_abs() as $T, &mut buf.buf);
303287
}
304288
// Only difference between signed and unsigned are these 4 lines.
305289
if self < 0 {
@@ -311,7 +295,7 @@ macro_rules! impl_Display {
311295
}
312296
}
313297

314-
impl $unsigned {
298+
impl $Unsigned {
315299
/// Allows users to write an integer (in signed decimal format) into a variable `buf` of
316300
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
317301
///
@@ -321,15 +305,15 @@ macro_rules! impl_Display {
321305
/// #![feature(int_format_into)]
322306
/// use core::fmt::NumBuffer;
323307
///
324-
#[doc = concat!("let n = 0", stringify!($unsigned), ";")]
308+
#[doc = concat!("let n = 0", stringify!($Unsigned), ";")]
325309
/// let mut buf = NumBuffer::new();
326310
/// assert_eq!(n.format_into(&mut buf), "0");
327311
///
328-
#[doc = concat!("let n1 = 32", stringify!($unsigned), ";")]
312+
#[doc = concat!("let n1 = 32", stringify!($Unsigned), ";")]
329313
/// assert_eq!(n1.format_into(&mut buf), "32");
330314
///
331-
#[doc = concat!("let n2 = ", stringify!($unsigned::MAX), ";")]
332-
#[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($unsigned::MAX), ".to_string());")]
315+
#[doc = concat!("let n2 = ", stringify!($Unsigned::MAX), ";")]
316+
#[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($Unsigned::MAX), ".to_string());")]
333317
/// ```
334318
#[unstable(feature = "int_format_into", issue = "138215")]
335319
pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
@@ -342,7 +326,9 @@ macro_rules! impl_Display {
342326
}
343327
#[cfg(feature = "optimize_for_size")]
344328
{
345-
offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.$conv_fn(), &mut buf.buf);
329+
// Lossless conversion (with as) is asserted at the top of
330+
// this macro.
331+
offset = ${concat($fmt_fn, _in_buf_small)}(self as $T, &mut buf.buf);
346332
}
347333
// SAFETY: Starting from `offset`, all elements of the slice have been set.
348334
unsafe { slice_buffer_to_str(&buf.buf, offset) }
@@ -353,7 +339,7 @@ macro_rules! impl_Display {
353339
)*
354340

355341
#[cfg(feature = "optimize_for_size")]
356-
fn ${concat(_inner_slow_integer_to_str, $gen_name)}(mut n: $u, buf: &mut [MaybeUninit::<u8>]) -> usize {
342+
fn ${concat($fmt_fn, _in_buf_small)}(mut n: $T, buf: &mut [MaybeUninit::<u8>]) -> usize {
357343
let mut curr = buf.len();
358344

359345
// SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning
@@ -374,11 +360,11 @@ macro_rules! impl_Display {
374360
}
375361

376362
#[cfg(feature = "optimize_for_size")]
377-
fn $gen_name(n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378-
const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1;
363+
fn ${concat($fmt_fn, _small)}(n: $T, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364+
const MAX_DEC_N: usize = $T::MAX.ilog(10) as usize + 1;
379365
let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
380366

381-
let offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(n, &mut buf);
367+
let offset = ${concat($fmt_fn, _in_buf_small)}(n, &mut buf);
382368
// SAFETY: Starting from `offset`, all elements of the slice have been set.
383369
let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) };
384370
f.pad_integral(is_nonnegative, "", buf_slice)
@@ -387,9 +373,9 @@ macro_rules! impl_Display {
387373
}
388374

389375
macro_rules! impl_Exp {
390-
($($t:ident),*as $u:ident via $conv_fn:ident named $name:ident) => {
391-
fn $name(
392-
mut n: $u,
376+
($($Signed:ident, $Unsigned:ident),*;as $T:ident into $fmt_fn:ident) => {
377+
fn $fmt_fn(
378+
mut n: $T,
393379
is_nonnegative: bool,
394380
upper: bool,
395381
f: &mut fmt::Formatter<'_>
@@ -523,32 +509,41 @@ macro_rules! impl_Exp {
523509

524510
$(
525511
#[stable(feature = "integer_exp_format", since = "1.42.0")]
526-
impl fmt::LowerExp for $t {
527-
#[allow(unused_comparisons)]
512+
impl fmt::LowerExp for $Signed {
528513
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
529514
let is_nonnegative = *self >= 0;
530515
let n = if is_nonnegative {
531-
self.$conv_fn()
516+
*selfas $T
532517
} else {
533-
// convert the negative num to positive by summing 1 to its 2s complement
534-
(!self.$conv_fn()).wrapping_add(1)
518+
self.unsigned_abs() as $T
535519
};
536-
$name(n, is_nonnegative, false, f)
520+
$fmt_fn(n, is_nonnegative, false, f)
521+
}
522+
}
523+
#[stable(feature = "integer_exp_format", since = "1.42.0")]
524+
impl fmt::LowerExp for $Unsigned {
525+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
526+
$fmt_fn(*self as $T, true, false, f)
537527
}
538528
})*
529+
539530
$(
540531
#[stable(feature = "integer_exp_format", since = "1.42.0")]
541-
impl fmt::UpperExp for $t {
542-
#[allow(unused_comparisons)]
532+
impl fmt::UpperExp for $Signed {
543533
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
544534
let is_nonnegative = *self >= 0;
545535
let n = if is_nonnegative {
546-
self.$conv_fn()
536+
*selfas $T
547537
} else {
548-
// convert the negative num to positive by summing 1 to its 2s complement
549-
(!self.$conv_fn()).wrapping_add(1)
538+
self.unsigned_abs() as $T
550539
};
551-
$name(n, is_nonnegative, true, f)
540+
$fmt_fn(n, is_nonnegative, true, f)
541+
}
542+
}
543+
#[stable(feature = "integer_exp_format", since = "1.42.0")]
544+
impl fmt::UpperExp for $Unsigned {
545+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
546+
$fmt_fn(*self as $T, true, true, f)
552547
}
553548
})*
554549
};
@@ -564,37 +559,20 @@ impl_Debug! {
564559
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
565560
mod imp {
566561
use super::*;
567-
impl_Display!(
568-
i8, u8,
569-
i16, u16,
570-
i32, u32,
571-
i64, u64,
572-
isize, usize,
573-
; as u64 via to_u64 named fmt_u64
574-
);
575-
impl_Exp!(
576-
i8, u8, i16, u16, i32, u32, i64, u64, usize, isize
577-
as u64 via to_u64 named exp_u64
578-
);
562+
impl_Display!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into display_u64);
563+
impl_Exp!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize; as u64 into exp_u64);
579564
}
580565

581566
#[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))]
582567
mod imp {
583568
use super::*;
584-
impl_Display!(
585-
i8, u8,
586-
i16, u16,
587-
i32, u32,
588-
isize, usize,
589-
; as u32 via to_u32 named fmt_u32);
590-
impl_Display!(
591-
i64, u64,
592-
; as u64 via to_u64 named fmt_u64);
593-
594-
impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32);
595-
impl_Exp!(i64, u64 as u64 via to_u64 named exp_u64);
569+
impl_Display!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into display_u32);
570+
impl_Display!(i64, u64; as u64 into display_u64);
571+
572+
impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into exp_u32);
573+
impl_Exp!(i64, u64; as u64 into exp_u64);
596574
}
597-
impl_Exp!(i128, u128 as u128 via to_u128 named exp_u128);
575+
impl_Exp!(i128, u128; as u128 into exp_u128);
598576

599577
const U128_MAX_DEC_N: usize = u128::MAX.ilog10() as usize + 1;
600578

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /