3
3
use crate :: fmt:: NumBuffer ;
4
4
use crate :: mem:: MaybeUninit ;
5
5
use crate :: num:: fmt as numfmt;
6
- use crate :: ops:: { Div , Rem , Sub } ;
7
6
use crate :: { fmt, ptr, slice, str} ;
8
7
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
-
35
8
/// Formatting of integers with a non-decimal radix.
36
9
macro_rules! radix_integer {
37
10
( 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 {
146
119
}
147
120
148
121
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) => {
150
123
151
124
$(
125
+ const _: ( ) = {
126
+ assert!( $Signed:: BITS <= $T:: BITS , "need lossless conversion" ) ;
127
+ assert!( $Unsigned:: BITS <= $T:: BITS , "need lossless conversion" ) ;
128
+ } ;
129
+
152
130
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
153
- impl fmt:: Display for $unsigned {
131
+ impl fmt:: Display for $Unsigned {
154
132
fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
155
133
#[ cfg( not( feature = "optimize_for_size" ) ) ]
156
134
{
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.
159
137
let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; MAX_DEC_N ] ;
160
138
161
139
// SAFETY: `buf` is always big enough to contain all the digits.
162
140
unsafe { f. pad_integral( true , "" , self . _fmt( & mut buf) ) }
163
141
}
164
142
#[ cfg( feature = "optimize_for_size" ) ]
165
143
{
166
- $gen_name( self . $conv_fn( ) , true , f)
144
+ // Lossless conversion (with as) is asserted at the top of
145
+ // this macro.
146
+ $fmt_fn( self as $T, true , f)
167
147
}
168
148
}
169
149
}
170
150
171
151
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
172
- impl fmt:: Display for $signed {
152
+ impl fmt:: Display for $Signed {
173
153
fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
174
154
#[ cfg( not( feature = "optimize_for_size" ) ) ]
175
155
{
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.
178
158
let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; MAX_DEC_N ] ;
179
159
180
160
// SAFETY: `buf` is always big enough to contain all the digits.
181
161
unsafe { f. pad_integral( * self >= 0 , "" , self . unsigned_abs( ) . _fmt( & mut buf) ) }
182
162
}
183
163
#[ cfg( feature = "optimize_for_size" ) ]
184
164
{
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 $fmt_fn( self . unsigned_abs( ) as $T, * self >= 0 , f) ;
186
168
}
187
169
}
188
170
}
189
171
190
172
#[ cfg( not( feature = "optimize_for_size" ) ) ]
191
- impl $unsigned {
173
+ impl $Unsigned {
192
174
#[ doc( hidden) ]
193
175
#[ unstable(
194
176
feature = "fmt_internals" ,
@@ -209,7 +191,7 @@ macro_rules! impl_Display {
209
191
let mut remain = self ;
210
192
211
193
// 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.
213
195
while size_of:: <Self >( ) > 1 && remain > 999 . try_into( ) . expect( "branch is not hit for types that cannot fit 999 (u8)" ) {
214
196
// SAFETY: All of the decimals fit in buf due to MAX_DEC_N
215
197
// and the while condition ensures at least 4 more decimals.
@@ -268,7 +250,7 @@ macro_rules! impl_Display {
268
250
}
269
251
}
270
252
271
- impl $signed {
253
+ impl $Signed {
272
254
/// Allows users to write an integer (in signed decimal format) into a variable `buf` of
273
255
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
274
256
///
@@ -278,15 +260,15 @@ macro_rules! impl_Display {
278
260
/// #![feature(int_format_into)]
279
261
/// use core::fmt::NumBuffer;
280
262
///
281
- #[ doc = concat!( "let n = 0" , stringify!( $signed ) , ";" ) ]
263
+ #[ doc = concat!( "let n = 0" , stringify!( $Signed ) , ";" ) ]
282
264
/// let mut buf = NumBuffer::new();
283
265
/// assert_eq!(n.format_into(&mut buf), "0");
284
266
///
285
- #[ doc = concat!( "let n1 = 32" , stringify!( $signed ) , ";" ) ]
267
+ #[ doc = concat!( "let n1 = 32" , stringify!( $Signed ) , ";" ) ]
286
268
/// assert_eq!(n1.format_into(&mut buf), "32");
287
269
///
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());" ) ]
290
272
/// ```
291
273
#[ unstable( feature = "int_format_into" , issue = "138215" ) ]
292
274
pub fn format_into( self , buf: & mut NumBuffer <Self >) -> & str {
@@ -299,7 +281,9 @@ macro_rules! impl_Display {
299
281
}
300
282
#[ cfg( feature = "optimize_for_size" ) ]
301
283
{
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( _inner_slow_integer_to_str, $fmt_fn) } ( self . unsigned_abs( ) as $T, & mut buf. buf) ;
303
287
}
304
288
// Only difference between signed and unsigned are these 4 lines.
305
289
if self < 0 {
@@ -311,7 +295,7 @@ macro_rules! impl_Display {
311
295
}
312
296
}
313
297
314
- impl $unsigned {
298
+ impl $Unsigned {
315
299
/// Allows users to write an integer (in signed decimal format) into a variable `buf` of
316
300
/// type [`NumBuffer`] that is passed by the caller by mutable reference.
317
301
///
@@ -321,15 +305,15 @@ macro_rules! impl_Display {
321
305
/// #![feature(int_format_into)]
322
306
/// use core::fmt::NumBuffer;
323
307
///
324
- #[ doc = concat!( "let n = 0" , stringify!( $unsigned ) , ";" ) ]
308
+ #[ doc = concat!( "let n = 0" , stringify!( $Unsigned ) , ";" ) ]
325
309
/// let mut buf = NumBuffer::new();
326
310
/// assert_eq!(n.format_into(&mut buf), "0");
327
311
///
328
- #[ doc = concat!( "let n1 = 32" , stringify!( $unsigned ) , ";" ) ]
312
+ #[ doc = concat!( "let n1 = 32" , stringify!( $Unsigned ) , ";" ) ]
329
313
/// assert_eq!(n1.format_into(&mut buf), "32");
330
314
///
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());" ) ]
333
317
/// ```
334
318
#[ unstable( feature = "int_format_into" , issue = "138215" ) ]
335
319
pub fn format_into( self , buf: & mut NumBuffer <Self >) -> & str {
@@ -342,7 +326,9 @@ macro_rules! impl_Display {
342
326
}
343
327
#[ cfg( feature = "optimize_for_size" ) ]
344
328
{
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( _inner_slow_integer_to_str, $fmt_fn) } ( * self as $T, & mut buf. buf) ;
346
332
}
347
333
// SAFETY: Starting from `offset`, all elements of the slice have been set.
348
334
unsafe { slice_buffer_to_str( & buf. buf, offset) }
@@ -353,7 +339,7 @@ macro_rules! impl_Display {
353
339
) *
354
340
355
341
#[ 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( _inner_slow_integer_to_str, $fmt_fn ) } ( mut n: $T , buf: & mut [ MaybeUninit :: <u8 >] ) -> usize {
357
343
let mut curr = buf. len( ) ;
358
344
359
345
// 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 {
374
360
}
375
361
376
362
#[ 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 $fmt_fn ( n: $T , is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
364
+ const MAX_DEC_N : usize = $T :: MAX . ilog( 10 ) as usize + 1 ;
379
365
let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; MAX_DEC_N ] ;
380
366
381
- let offset = ${ concat( _inner_slow_integer_to_str, $gen_name ) } ( n, & mut buf) ;
367
+ let offset = ${ concat( _inner_slow_integer_to_str, $fmt_fn ) } ( n, & mut buf) ;
382
368
// SAFETY: Starting from `offset`, all elements of the slice have been set.
383
369
let buf_slice = unsafe { slice_buffer_to_str( & buf, offset) } ;
384
370
f. pad_integral( is_nonnegative, "" , buf_slice)
@@ -387,9 +373,9 @@ macro_rules! impl_Display {
387
373
}
388
374
389
375
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 ,
393
379
is_nonnegative: bool ,
394
380
upper: bool ,
395
381
f: & mut fmt:: Formatter <' _>
@@ -523,32 +509,41 @@ macro_rules! impl_Exp {
523
509
524
510
$(
525
511
#[ 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 {
528
513
fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
529
514
let is_nonnegative = * self >= 0 ;
530
515
let n = if is_nonnegative {
531
- self . $conv_fn ( )
516
+ * self as $T
532
517
} 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
535
519
} ;
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)
537
527
}
538
528
} ) *
529
+
539
530
$(
540
531
#[ 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 {
543
533
fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
544
534
let is_nonnegative = * self >= 0 ;
545
535
let n = if is_nonnegative {
546
- self . $conv_fn ( )
536
+ * self as $T
547
537
} 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
550
539
} ;
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)
552
547
}
553
548
} ) *
554
549
} ;
@@ -564,37 +559,20 @@ impl_Debug! {
564
559
#[ cfg( any( target_pointer_width = "64" , target_arch = "wasm32" ) ) ]
565
560
mod imp {
566
561
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 fmt_u64) ;
563
+ impl_Exp ! ( i8 , u8 , i16 , u16 , i32 , u32 , i64 , u64 , isize , usize ; as u64 into exp_u64) ;
579
564
}
580
565
581
566
#[ cfg( not( any( target_pointer_width = "64" , target_arch = "wasm32" ) ) ) ]
582
567
mod imp {
583
568
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 fmt_u32) ;
570
+ impl_Display ! ( i64 , u64 ; as u64 into fmt_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) ;
596
574
}
597
- impl_Exp ! ( i128 , u128 as u128 via to_u128 named exp_u128) ;
575
+ impl_Exp ! ( i128 , u128 ; as u128 into exp_u128) ;
598
576
599
577
const U128_MAX_DEC_N : usize = u128:: MAX . ilog10 ( ) as usize + 1 ;
600
578
0 commit comments