@@ -208,11 +208,46 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\
208
208
8081828384858687888990919293949596979899";
209
209
210
210
macro_rules! impl_Display {
211
- ( $( $t: ident) ,* as $u: ident via $conv_fn: ident named $name: ident) => {
211
+ ( $( $t: ident => $size: literal $( as $positive: ident in $other: ident) ? => named $name: ident, ) * ; as $u: ident via $conv_fn: ident named $gen_name: ident) => {
212
+
213
+ $(
214
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
215
+ impl fmt:: Display for $t {
216
+ fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
217
+ // If it's a signed integer.
218
+ $(
219
+ let is_nonnegative = * self >= 0 ;
220
+
221
+ #[ cfg( not( feature = "optimize_for_size" ) ) ]
222
+ {
223
+ if !is_nonnegative {
224
+ // convert the negative num to positive by summing 1 to its 2s complement
225
+ return $other( ( !self as $positive) . wrapping_add( 1 ) , false , f) ;
226
+ }
227
+ }
228
+ #[ cfg( feature = "optimize_for_size" ) ]
229
+ {
230
+ if !is_nonnegative {
231
+ // convert the negative num to positive by summing 1 to its 2s complement
232
+ return $other( ( !self . $conv_fn( ) ) . wrapping_add( 1 ) , false , f) ;
233
+ }
234
+ }
235
+ ) ?
236
+ // If it's a positive integer.
237
+ #[ cfg( not( feature = "optimize_for_size" ) ) ]
238
+ {
239
+ $name( * self , true , f)
240
+ }
241
+ #[ cfg( feature = "optimize_for_size" ) ]
242
+ {
243
+ $gen_name( * self , true , f)
244
+ }
245
+ }
246
+ }
247
+
212
248
#[ cfg( not( feature = "optimize_for_size" ) ) ]
213
- fn $name( mut n: $u, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
214
- // 2^128 is about 3*10^38, so 39 gives an extra byte of space
215
- let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; 39 ] ;
249
+ fn $name( mut n: $t, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
250
+ let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; $size] ;
216
251
let mut curr = buf. len( ) ;
217
252
let buf_ptr = MaybeUninit :: slice_as_mut_ptr( & mut buf) ;
218
253
let lut_ptr = DEC_DIGITS_LUT . as_ptr( ) ;
@@ -225,9 +260,12 @@ macro_rules! impl_Display {
225
260
// non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]`
226
261
// is safe to access.
227
262
unsafe {
228
- // need at least 16 bits for the 4-characters-at-a-time to work.
229
- assert!( crate :: mem:: size_of:: <$u>( ) >= 2 ) ;
230
-
263
+ // The two `allow` are for `i8` and `u8`.
264
+ #[ allow( overflowing_literals) ]
265
+ #[ allow( unused_comparisons) ]
266
+ // This block should be removed for smaller types at compile time so it
267
+ // should be ok.
268
+ //
231
269
// eagerly decode 4 characters at a time
232
270
while n >= 10000 {
233
271
let rem = ( n % 10000 ) as usize ;
@@ -240,8 +278,8 @@ macro_rules! impl_Display {
240
278
// We are allowed to copy to `buf_ptr[curr..curr + 3]` here since
241
279
// otherwise `curr < 0`. But then `n` was originally at least `10000^10`
242
280
// which is `10^40 > 2^128 > n`.
243
- ptr:: copy_nonoverlapping( lut_ptr. add( d1) , buf_ptr. add( curr) , 2 ) ;
244
- ptr:: copy_nonoverlapping( lut_ptr. add( d2) , buf_ptr. add( curr + 2 ) , 2 ) ;
281
+ ptr:: copy_nonoverlapping( lut_ptr. add( d1 as usize ) , buf_ptr. add( curr) , 2 ) ;
282
+ ptr:: copy_nonoverlapping( lut_ptr. add( d2 as usize ) , buf_ptr. add( curr + 2 ) , 2 ) ;
245
283
}
246
284
247
285
// if we reach here numbers are <= 9999, so at most 4 chars long
@@ -255,6 +293,8 @@ macro_rules! impl_Display {
255
293
ptr:: copy_nonoverlapping( lut_ptr. add( d1) , buf_ptr. add( curr) , 2 ) ;
256
294
}
257
295
296
+ // if we reach here numbers are <= 100, so at most 2 chars long
297
+ // The biggest it can be is 99, and 99 << 1 == 198, so a `u8` is enough.
258
298
// decode last 1 or 2 chars
259
299
if n < 10 {
260
300
curr -= 1 ;
@@ -273,11 +313,10 @@ macro_rules! impl_Display {
273
313
slice:: from_raw_parts( buf_ptr. add( curr) , buf. len( ) - curr) )
274
314
} ;
275
315
f. pad_integral( is_nonnegative, "" , buf_slice)
276
- }
316
+ } ) *
277
317
278
318
#[ cfg( feature = "optimize_for_size" ) ]
279
- fn $name( mut n: $u, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
280
- // 2^128 is about 3*10^38, so 39 gives an extra byte of space
319
+ fn $gen_name( mut n: $u, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
281
320
let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; 39 ] ;
282
321
let mut curr = buf. len( ) ;
283
322
let buf_ptr = MaybeUninit :: slice_as_mut_ptr( & mut buf) ;
@@ -306,21 +345,6 @@ macro_rules! impl_Display {
306
345
} ;
307
346
f. pad_integral( is_nonnegative, "" , buf_slice)
308
347
}
309
-
310
- $( #[ stable( feature = "rust1" , since = "1.0.0" ) ]
311
- impl fmt:: Display for $t {
312
- #[ allow( unused_comparisons) ]
313
- fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
314
- let is_nonnegative = * self >= 0 ;
315
- let n = if is_nonnegative {
316
- self . $conv_fn( )
317
- } else {
318
- // convert the negative num to positive by summing 1 to it's 2 complement
319
- ( !self . $conv_fn( ) ) . wrapping_add( 1 )
320
- } ;
321
- $name( n, is_nonnegative, f)
322
- }
323
- } ) *
324
348
} ;
325
349
}
326
350
@@ -374,7 +398,6 @@ macro_rules! impl_Exp {
374
398
( n, exponent, exponent, added_precision)
375
399
} ;
376
400
377
- // 39 digits (worst case u128) + . = 40
378
401
// Since `curr` always decreases by the number of digits copied, this means
379
402
// that `curr >= 0`.
380
403
let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; 40 ] ;
@@ -469,7 +492,7 @@ macro_rules! impl_Exp {
469
492
let n = if is_nonnegative {
470
493
self . $conv_fn( )
471
494
} else {
472
- // convert the negative num to positive by summing 1 to it's 2 complement
495
+ // convert the negative num to positive by summing 1 to its 2s complement
473
496
( !self . $conv_fn( ) ) . wrapping_add( 1 )
474
497
} ;
475
498
$name( n, is_nonnegative, false , f)
@@ -484,7 +507,7 @@ macro_rules! impl_Exp {
484
507
let n = if is_nonnegative {
485
508
self . $conv_fn( )
486
509
} else {
487
- // convert the negative num to positive by summing 1 to it's 2 complement
510
+ // convert the negative num to positive by summing 1 to its 2s complement
488
511
( !self . $conv_fn( ) ) . wrapping_add( 1 )
489
512
} ;
490
513
$name( n, is_nonnegative, true , f)
@@ -499,8 +522,17 @@ macro_rules! impl_Exp {
499
522
mod imp {
500
523
use super :: * ;
501
524
impl_Display ! (
502
- i8 , u8 , i16 , u16 , i32 , u32 , i64 , u64 , usize , isize
503
- as u64 via to_u64 named fmt_u64
525
+ i8 => 3 as u8 in fmt_u8 => named fmt_i8,
526
+ u8 => 3 => named fmt_u8,
527
+ i16 => 5 as u16 in fmt_u16 => named fmt_i16,
528
+ u16 => 5 => named fmt_u16,
529
+ i32 => 10 as u32 in fmt_u32 => named fmt_i32,
530
+ u32 => 10 => named fmt_u32,
531
+ i64 => 20 as u64 in fmt_u64 => named fmt_i64,
532
+ u64 => 20 => named fmt_u64,
533
+ isize => 20 as usize in fmt_usize => named fmt_isize,
534
+ usize => 20 => named fmt_usize,
535
+ ; as u64 via to_u64 named fmt_u64
504
536
) ;
505
537
impl_Exp ! (
506
538
i8 , u8 , i16 , u16 , i32 , u32 , i64 , u64 , usize , isize
@@ -511,8 +543,21 @@ mod imp {
511
543
#[ cfg( not( any( target_pointer_width = "64" , target_arch = "wasm32" ) ) ) ]
512
544
mod imp {
513
545
use super :: * ;
514
- impl_Display ! ( i8 , u8 , i16 , u16 , i32 , u32 , isize , usize as u32 via to_u32 named fmt_u32) ;
515
- impl_Display ! ( i64 , u64 as u64 via to_u64 named fmt_u64) ;
546
+ impl_Display ! (
547
+ i8 => 3 as u8 in fmt_u8 => named fmt_i8,
548
+ u8 => 3 => named fmt_u8,
549
+ i16 => 5 as u16 in fmt_u16 => named fmt_i16,
550
+ u16 => 5 => named fmt_u16,
551
+ i32 => 10 as u32 in fmt_u32 => named fmt_i32,
552
+ u32 => 10 => named fmt_u32,
553
+ isize => 10 as usize in fmt_usize => named fmt_isize,
554
+ usize => 10 => named fmt_usize,
555
+ ; as u32 via to_u32 named fmt_u32) ;
556
+ impl_Display ! (
557
+ i64 => 20 as u64 in fmt_u64 => named fmt_i64,
558
+ u64 => 20 => named fmt_u64,
559
+ ; as u64 via to_u64 named fmt_u64) ;
560
+
516
561
impl_Exp ! ( i8 , u8 , i16 , u16 , i32 , u32 , isize , usize as u32 via to_u32 named exp_u32) ;
517
562
impl_Exp ! ( i64 , u64 as u64 via to_u64 named exp_u64) ;
518
563
}
@@ -619,7 +664,7 @@ impl fmt::Display for i128 {
619
664
let n = if is_nonnegative {
620
665
self . to_u128 ( )
621
666
} else {
622
- // convert the negative num to positive by summing 1 to it's 2 complement
667
+ // convert the negative num to positive by summing 1 to its 2s complement
623
668
( !self . to_u128 ( ) ) . wrapping_add ( 1 )
624
669
} ;
625
670
fmt_u128 ( n, is_nonnegative, f)
0 commit comments