@@ -208,7 +208,7 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\
208
208
8081828384858687888990919293949596979899";
209
209
210
210
macro_rules! impl_Display {
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) => {
211
+ ( $( $t: ident => $size: literal $( as $positive: ident) ? named $name: ident, ) * ; as $u: ident via $conv_fn: ident named $gen_name: ident) => {
212
212
213
213
$(
214
214
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -222,102 +222,105 @@ macro_rules! impl_Display {
222
222
{
223
223
if !is_nonnegative {
224
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) ;
225
+ return ( !self as $positive) . wrapping_add( 1 ) . _fmt ( false , f) ;
226
226
}
227
227
}
228
228
#[ cfg( feature = "optimize_for_size" ) ]
229
229
{
230
230
if !is_nonnegative {
231
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) ;
232
+ return $gen_name ( ( !self . $conv_fn( ) ) . wrapping_add( 1 ) , false , f) ;
233
233
}
234
234
}
235
235
) ?
236
236
// If it's a positive integer.
237
237
#[ cfg( not( feature = "optimize_for_size" ) ) ]
238
238
{
239
- $name ( * self , true , f)
239
+ self . _fmt ( true , f)
240
240
}
241
241
#[ cfg( feature = "optimize_for_size" ) ]
242
242
{
243
- $gen_name( * self , true , f)
243
+ $gen_name( self . $conv_fn ( ) , true , f)
244
244
}
245
245
}
246
246
}
247
247
248
248
#[ cfg( not( feature = "optimize_for_size" ) ) ]
249
- fn $name( mut n: $t, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
250
- let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; $size] ;
251
- let mut curr = buf. len( ) ;
252
- let buf_ptr = MaybeUninit :: slice_as_mut_ptr( & mut buf) ;
253
- let lut_ptr = DEC_DIGITS_LUT . as_ptr( ) ;
254
-
255
- // SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
256
- // can copy from `lut_ptr[d1..d1 + 1]` and `lut_ptr[d2..d2 + 1]`. To show
257
- // that it's OK to copy into `buf_ptr`, notice that at the beginning
258
- // `curr == buf.len() == 39 > log(n)` since `n < 2^128 < 10^39`, and at
259
- // each step this is kept the same as `n` is divided. Since `n` is always
260
- // non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]`
261
- // is safe to access.
262
- unsafe {
263
- // need at least 16 bits for the 4-characters-at-a-time to work.
264
- #[ allow( overflowing_literals) ]
265
- #[ allow( unused_comparisons) ]
266
- // This block will be removed for smaller types at compile time and in the worst
267
- // case, it will prevent to have the `10000` literal to overflow for `i8` and `u8`.
268
- if core:: mem:: size_of:: <$t>( ) >= 2 {
269
- // eagerly decode 4 characters at a time
270
- while n >= 10000 {
271
- let rem = ( n % 10000 ) as usize ;
272
- n /= 10000 ;
273
-
274
- let d1 = ( rem / 100 ) << 1 ;
275
- let d2 = ( rem % 100 ) << 1 ;
276
- curr -= 4 ;
277
-
278
- // We are allowed to copy to `buf_ptr[curr..curr + 3]` here since
279
- // otherwise `curr < 0`. But then `n` was originally at least `10000^10`
280
- // which is `10^40 > 2^128 > n`.
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 ) ;
249
+ impl $t {
250
+ fn _fmt( mut self : $t, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
251
+ let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; $size] ;
252
+ let mut curr = $size;
253
+ let buf_ptr = MaybeUninit :: slice_as_mut_ptr( & mut buf) ;
254
+ let lut_ptr = DEC_DIGITS_LUT . as_ptr( ) ;
255
+
256
+ // SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
257
+ // can copy from `lut_ptr[d1..d1 + 1]` and `lut_ptr[d2..d2 + 1]`. To show
258
+ // that it's OK to copy into `buf_ptr`, notice that at the beginning
259
+ // `curr == buf.len() == 39 > log(n)` since `n < 2^128 < 10^39`, and at
260
+ // each step this is kept the same as `n` is divided. Since `n` is always
261
+ // non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]`
262
+ // is safe to access.
263
+ unsafe {
264
+ // need at least 16 bits for the 4-characters-at-a-time to work.
265
+ #[ allow( overflowing_literals) ]
266
+ #[ allow( unused_comparisons) ]
267
+ // This block will be removed for smaller types at compile time and in the worst
268
+ // case, it will prevent to have the `10000` literal to overflow for `i8` and `u8`.
269
+ if core:: mem:: size_of:: <$t>( ) >= 2 {
270
+ // eagerly decode 4 characters at a time
271
+ while self >= 10000 {
272
+ let rem = ( self % 10000 ) as usize ;
273
+ self /= 10000 ;
274
+
275
+ let d1 = ( rem / 100 ) << 1 ;
276
+ let d2 = ( rem % 100 ) << 1 ;
277
+ curr -= 4 ;
278
+
279
+ // We are allowed to copy to `buf_ptr[curr..curr + 3]` here since
280
+ // otherwise `curr < 0`. But then `n` was originally at least `10000^10`
281
+ // which is `10^40 > 2^128 > n`.
282
+ ptr:: copy_nonoverlapping( lut_ptr. add( d1 as usize ) , buf_ptr. add( curr) , 2 ) ;
283
+ ptr:: copy_nonoverlapping( lut_ptr. add( d2 as usize ) , buf_ptr. add( curr + 2 ) , 2 ) ;
284
+ }
283
285
}
284
- }
285
286
286
- // if we reach here numbers are <= 9999, so at most 4 chars long
287
- let mut n = n as usize ; // possibly reduce 64bit math
287
+ // if we reach here numbers are <= 9999, so at most 4 chars long
288
+ let mut n = self as usize ; // possibly reduce 64bit math
288
289
289
- // decode 2 more chars, if > 2 chars
290
- if n >= 100 {
291
- let d1 = ( n % 100 ) << 1 ;
292
- n /= 100 ;
293
- curr -= 2 ;
294
- ptr:: copy_nonoverlapping( lut_ptr. add( d1) , buf_ptr. add( curr) , 2 ) ;
295
- }
290
+ // decode 2 more chars, if > 2 chars
291
+ if n >= 100 {
292
+ let d1 = ( n % 100 ) << 1 ;
293
+ n /= 100 ;
294
+ curr -= 2 ;
295
+ ptr:: copy_nonoverlapping( lut_ptr. add( d1) , buf_ptr. add( curr) , 2 ) ;
296
+ }
296
297
297
- // if we reach here numbers are <= 100, so at most 2 chars long
298
- // The biggest it can be is 99, and 99 << 1 == 198, so a `u8` is enough.
299
- // decode last 1 or 2 chars
300
- if n < 10 {
301
- curr -= 1 ;
302
- * buf_ptr. add( curr) = ( n as u8 ) + b'0' ;
303
- } else {
304
- let d1 = n << 1 ;
305
- curr -= 2 ;
306
- ptr:: copy_nonoverlapping( lut_ptr. add( d1) , buf_ptr. add( curr) , 2 ) ;
298
+ // if we reach here numbers are <= 100, so at most 2 chars long
299
+ // The biggest it can be is 99, and 99 << 1 == 198, so a `u8` is enough.
300
+ // decode last 1 or 2 chars
301
+ if n < 10 {
302
+ curr -= 1 ;
303
+ * buf_ptr. add( curr) = ( n as u8 ) + b'0' ;
304
+ } else {
305
+ let d1 = n << 1 ;
306
+ curr -= 2 ;
307
+ ptr:: copy_nonoverlapping( lut_ptr. add( d1) , buf_ptr. add( curr) , 2 ) ;
308
+ }
307
309
}
308
- }
309
310
310
- // SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid
311
- // UTF-8 since `DEC_DIGITS_LUT` is
312
- let buf_slice = unsafe {
313
- str :: from_utf8_unchecked(
314
- slice:: from_raw_parts( buf_ptr. add( curr) , buf. len( ) - curr) )
315
- } ;
316
- f. pad_integral( is_nonnegative, "" , buf_slice)
311
+ // SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid
312
+ // UTF-8 since `DEC_DIGITS_LUT` is
313
+ let buf_slice = unsafe {
314
+ str :: from_utf8_unchecked(
315
+ slice:: from_raw_parts( buf_ptr. add( curr) , buf. len( ) - curr) )
316
+ } ;
317
+ f. pad_integral( is_nonnegative, "" , buf_slice)
318
+ }
317
319
} ) *
318
320
319
321
#[ cfg( feature = "optimize_for_size" ) ]
320
322
fn $gen_name( mut n: $u, is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
323
+ // 2^128 is about 3*10^38, so 39 gives an extra byte of space
321
324
let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; 39 ] ;
322
325
let mut curr = buf. len( ) ;
323
326
let buf_ptr = MaybeUninit :: slice_as_mut_ptr( & mut buf) ;
@@ -523,16 +526,16 @@ macro_rules! impl_Exp {
523
526
mod imp {
524
527
use super :: * ;
525
528
impl_Display ! (
526
- i8 => 3 as u8 in fmt_u8 => named fmt_i8,
527
- u8 => 3 => named fmt_u8,
528
- i16 => 5 as u16 in fmt_u16 => named fmt_i16,
529
- u16 => 5 => named fmt_u16,
530
- i32 => 10 as u32 in fmt_u32 => named fmt_i32,
531
- u32 => 10 => named fmt_u32,
532
- i64 => 19 as u64 in fmt_u64 => named fmt_i64,
533
- u64 => 20 => named fmt_u64,
534
- isize => 19 as usize in fmt_usize => named fmt_isize,
535
- usize => 20 => named fmt_usize,
529
+ i8 => 3 as u8 named fmt_i8,
530
+ u8 => 3 named fmt_u8,
531
+ i16 => 5 as u16 named fmt_i16,
532
+ u16 => 5 named fmt_u16,
533
+ i32 => 10 as u32 named fmt_i32,
534
+ u32 => 10 named fmt_u32,
535
+ i64 => 19 as u64 named fmt_i64,
536
+ u64 => 20 named fmt_u64,
537
+ isize => 19 as usize named fmt_isize,
538
+ usize => 20 named fmt_usize,
536
539
; as u64 via to_u64 named fmt_u64
537
540
) ;
538
541
impl_Exp ! (
@@ -545,18 +548,18 @@ mod imp {
545
548
mod imp {
546
549
use super :: * ;
547
550
impl_Display ! (
548
- i8 => 3 as u8 in fmt_u8 => named fmt_i8,
549
- u8 => 3 => named fmt_u8,
550
- i16 => 5 as u16 in fmt_u16 => named fmt_i16,
551
- u16 => 5 => named fmt_u16,
552
- i32 => 10 as u32 in fmt_u32 => named fmt_i32,
553
- u32 => 10 => named fmt_u32,
554
- isize => 10 as usize in fmt_usize => named fmt_isize,
555
- usize => 10 => named fmt_usize,
551
+ i8 => 3 as u8 named fmt_i8,
552
+ u8 => 3 named fmt_u8,
553
+ i16 => 5 as u16 named fmt_i16,
554
+ u16 => 5 named fmt_u16,
555
+ i32 => 10 as u32 named fmt_i32,
556
+ u32 => 10 named fmt_u32,
557
+ isize => 19 as usize named fmt_isize,
558
+ usize => 20 named fmt_usize,
556
559
; as u32 via to_u32 named fmt_u32) ;
557
560
impl_Display ! (
558
- i64 => 19 as u64 in fmt_u64 => named fmt_i64,
559
- u64 => 20 => named fmt_u64,
561
+ i64 => 19 as u64 named fmt_i64,
562
+ u64 => 20 named fmt_u64,
560
563
; as u64 via to_u64 named fmt_u64) ;
561
564
562
565
impl_Exp ! ( i8 , u8 , i16 , u16 , i32 , u32 , isize , usize as u32 via to_u32 named exp_u32) ;
0 commit comments