@@ -1082,7 +1082,19 @@ fn render_memory_layout(
1082
1082
1083
1083
if config. niches {
1084
1084
if let Some ( niches) = layout. niches ( ) {
1085
- format_to ! ( label, "niches = {niches}, " ) ;
1085
+ if niches > 1024 {
1086
+ if is_pwr2 ( niches) {
1087
+ format_to ! ( label, "niches = 2{}, " , pwr2_to_exponent( niches) ) ;
1088
+ } else if is_pwr2plus1 ( niches) {
1089
+ format_to ! ( label, "niches = 2{} + 1, " , pwr2_to_exponent( niches - 1 ) ) ;
1090
+ } else if is_pwr2minus1 ( niches) {
1091
+ format_to ! ( label, "niches = 2{} - 1, " , pwr2_to_exponent( niches + 1 ) ) ;
1092
+ } else {
1093
+ format_to ! ( label, "niches = really rather quite large, " ) ;
1094
+ }
1095
+ } else {
1096
+ format_to ! ( label, "niches = {niches}, " ) ;
1097
+ }
1086
1098
}
1087
1099
}
1088
1100
label. pop ( ) ; // ' '
@@ -1210,3 +1222,85 @@ fn render_dyn_compatibility(
1210
1222
}
1211
1223
}
1212
1224
}
1225
+
1226
+ fn is_pwr2 ( val : u128 ) -> bool {
1227
+ val. count_ones ( ) == 1
1228
+ }
1229
+
1230
+ fn is_pwr2minus1 ( val : u128 ) -> bool {
1231
+ val == u128:: MAX || ( val + 1 ) . count_ones ( ) == 1
1232
+ }
1233
+
1234
+ fn is_pwr2plus1 ( val : u128 ) -> bool {
1235
+ val != 0 && ( val - 1 ) . count_ones ( ) == 1
1236
+ }
1237
+
1238
+ fn pwr2_to_exponent ( num : u128 ) -> String {
1239
+ const DIGITS : [ char ; 10 ] = [ '⁰' , '¹' , '²' , '³' , '⁴' , '⁵' , '⁶' , '⁷' , '⁸' , '⁹' ] ;
1240
+ ( 127 - num. leading_zeros ( ) )
1241
+ . to_string ( )
1242
+ . chars ( )
1243
+ . map ( |c| c. to_digit ( 10 ) . unwrap ( ) as usize )
1244
+ . map ( |idx| DIGITS [ idx] )
1245
+ . collect :: < String > ( )
1246
+ }
1247
+
1248
+ #[ cfg( test) ]
1249
+ mod tests {
1250
+ use super :: * ;
1251
+
1252
+ const TESTERS : [ u128 ; 10 ] = [ 0 , 1 , 2 , 3 , 4 , 255 , 256 , 257 , u128:: MAX - 1 , u128:: MAX ] ;
1253
+
1254
+ #[ test]
1255
+ fn test_is_pwr2 ( ) {
1256
+ const OUTCOMES : [ bool ; 10 ] =
1257
+ [ false , true , true , false , true , false , true , false , false , false ] ;
1258
+ for ( test, expected) in TESTERS . iter ( ) . zip ( OUTCOMES ) {
1259
+ let actual = is_pwr2 ( * test) ;
1260
+ assert_eq ! ( actual, expected, "is_pwr2({test}) gave {actual}, expected {expected}" ) ;
1261
+ }
1262
+ }
1263
+
1264
+ #[ test]
1265
+ fn test_is_pwr2minus1 ( ) {
1266
+ const OUTCOMES : [ bool ; 10 ] =
1267
+ [ true , true , false , true , false , true , false , false , false , true ] ;
1268
+ for ( test, expected) in TESTERS . iter ( ) . zip ( OUTCOMES ) {
1269
+ let actual = is_pwr2minus1 ( * test) ;
1270
+ assert_eq ! ( actual, expected, "is_pwr2minu1({test}) gave {actual}, expected {expected}" ) ;
1271
+ }
1272
+ }
1273
+
1274
+ #[ test]
1275
+ fn test_is_pwr2plus1 ( ) {
1276
+ const OUTCOMES : [ bool ; 10 ] =
1277
+ [ false , false , true , true , false , false , false , true , false , false ] ;
1278
+ for ( test, expected) in TESTERS . iter ( ) . zip ( OUTCOMES ) {
1279
+ let actual = is_pwr2plus1 ( * test) ;
1280
+ assert_eq ! ( actual, expected, "is_pwr2plus1({test}) gave {actual}, expected {expected}" ) ;
1281
+ }
1282
+ }
1283
+
1284
+ #[ test]
1285
+ fn test_pwr2_to_exponent ( ) {
1286
+ const TESTERS : [ u128 ; 9 ] = [
1287
+ 1 ,
1288
+ 2 ,
1289
+ 4 ,
1290
+ 8 ,
1291
+ 16 ,
1292
+ 9223372036854775808 ,
1293
+ 18446744073709551616 ,
1294
+ 36893488147419103232 ,
1295
+ 170141183460469231731687303715884105728 ,
1296
+ ] ;
1297
+ const OUTCOMES : [ & str ; 9 ] = [ "⁰" , "¹" , "²" , "³" , "⁴" , "⁶³" , "⁶⁴" , "⁶⁵" , "¹²⁷" ] ;
1298
+ for ( test, expected) in TESTERS . iter ( ) . zip ( OUTCOMES ) {
1299
+ let actual = pwr2_to_exponent ( * test) ;
1300
+ assert_eq ! (
1301
+ actual, expected,
1302
+ "pwr2_to_exponent({test}) returned {actual}, expected {expected}" ,
1303
+ ) ;
1304
+ }
1305
+ }
1306
+ }
0 commit comments