33use crate :: fmt:: NumBuffer ;
44use crate :: mem:: MaybeUninit ;
55use crate :: num:: fmt as numfmt;
6- use crate :: ops:: { Div , Rem , Sub } ;
76use 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.
369macro_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
148121macro_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
389375macro_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+ * self as $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+ * self as $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" ) ) ]
565560mod 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" ) ) ) ]
582567mod 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
599577const U128_MAX_DEC_N : usize = u128:: MAX . ilog10 ( ) as usize + 1 ;
600578
0 commit comments