1use crate::fmt::NumBuffer;
4use crate::mem::MaybeUninit;
5use crate::num::imp::fmt as numfmt;
6use crate::{fmt, str};
7
8macro_rules! radix_integer {
10 (fmt::$Trait:ident for $Signed:ident and $Unsigned:ident, $prefix:literal, $dig_tab:literal) => {
11 #[stable(feature = "rust1", since = "1.0.0")]
12 impl fmt::$Trait for $Unsigned {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 const {
17 assert!($Unsigned::MIN == 0, "need unsigned");
18 assert!($dig_tab.is_ascii(), "need single-byte entries");
19 }
20
21 const DIG_TAB: &[u8] = $dig_tab;
23 const BASE: $Unsigned = DIG_TAB.len() as $Unsigned;
24 const MAX_DIG_N: usize = $Unsigned::MAX.ilog(BASE) as usize + 1;
25
26 let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DIG_N];
28 let mut offset = buf.len();
30
31 let mut remain = *self;
34 loop {
35 let digit = remain % BASE;
36 remain /= BASE;
37
38 offset -= 1;
39 unsafe { core::hint::assert_unchecked(offset < buf.len()) }
41 buf[offset].write(DIG_TAB[digit as usize]);
42 if remain == 0 {
43 break;
44 }
45 }
46
47 let digits = unsafe { slice_buffer_to_str(&buf, offset) };
49 f.pad_integral(true, $prefix, digits)
50 }
51 }
52
53 #[stable(feature = "rust1", since = "1.0.0")]
54 impl fmt::$Trait for $Signed {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 fmt::$Trait::fmt(&self.cast_unsigned(), f)
58 }
59 }
60 };
61}
62
63macro_rules! radix_integers {
65 ($Signed:ident, $Unsigned:ident) => {
66 radix_integer! { fmt::Binary for $Signed and $Unsigned, "0b", b"01" }
67 radix_integer! { fmt::Octal for $Signed and $Unsigned, "0o", b"01234567" }
68 radix_integer! { fmt::LowerHex for $Signed and $Unsigned, "0x", b"0123456789abcdef" }
69 radix_integer! { fmt::UpperHex for $Signed and $Unsigned, "0x", b"0123456789ABCDEF" }
70 };
71}
72radix_integers! { isize, usize }
73radix_integers! { i8, u8 }
74radix_integers! { i16, u16 }
75radix_integers! { i32, u32 }
76radix_integers! { i64, u64 }
77radix_integers! { i128, u128 }
78
79macro_rules! impl_Debug {
80 ($($T:ident)*) => {
81 $(
82 #[stable(feature = "rust1", since = "1.0.0")]
83 impl fmt::Debug for $T {
84 #[inline]
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 if f.debug_lower_hex() {
87 fmt::LowerHex::fmt(self, f)
88 } else if f.debug_upper_hex() {
89 fmt::UpperHex::fmt(self, f)
90 } else {
91 fmt::Display::fmt(self, f)
92 }
93 }
94 }
95 )*
96 };
97}
98
99static DECIMAL_PAIRS: &[u8; 200] = b"\
101 0001020304050607080910111213141516171819\
102 2021222324252627282930313233343536373839\
103 4041424344454647484950515253545556575859\
104 6061626364656667686970717273747576777879\
105 8081828384858687888990919293949596979899";
106
107unsafe fn slice_buffer_to_str(buf: &[MaybeUninit<u8>], offset: usize) -> &str {
114 let written = unsafe { buf.get_unchecked(offset..) };
116 unsafe { str::from_utf8_unchecked(written.assume_init_ref()) }
119}
120
121macro_rules! impl_Display {
122 ($($Signed:ident, $Unsigned:ident),* ; as $T:ident into $fmt_fn:ident) => {
123
124 $(
125 const _: () = {
126 assert!($Signed::MIN < 0, "need signed");
127 ass