@@ -267,8 +267,9 @@ $EndFeature, "
267
267
```
268
268
" ) ,
269
269
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
270
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
270
271
#[ inline]
271
- pub fn count_ones( self ) -> u32 { ( self as $UnsignedT) . count_ones( ) }
272
+ pub const fn count_ones( self ) -> u32 { ( self as $UnsignedT) . count_ones( ) }
272
273
}
273
274
274
275
doc_comment! {
@@ -282,8 +283,9 @@ Basic usage:
282
283
" , $Feature, "assert_eq!(" , stringify!( $SelfT) , "::max_value().count_zeros(), 1);" , $EndFeature, "
283
284
```" ) ,
284
285
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
286
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
285
287
#[ inline]
286
- pub fn count_zeros( self ) -> u32 {
288
+ pub const fn count_zeros( self ) -> u32 {
287
289
( !self ) . count_ones( )
288
290
}
289
291
}
@@ -302,8 +304,9 @@ assert_eq!(n.leading_zeros(), 0);",
302
304
$EndFeature, "
303
305
```" ) ,
304
306
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
307
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
305
308
#[ inline]
306
- pub fn leading_zeros( self ) -> u32 {
309
+ pub const fn leading_zeros( self ) -> u32 {
307
310
( self as $UnsignedT) . leading_zeros( )
308
311
}
309
312
}
@@ -322,8 +325,9 @@ assert_eq!(n.trailing_zeros(), 2);",
322
325
$EndFeature, "
323
326
```" ) ,
324
327
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
328
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
325
329
#[ inline]
326
- pub fn trailing_zeros( self ) -> u32 {
330
+ pub const fn trailing_zeros( self ) -> u32 {
327
331
( self as $UnsignedT) . trailing_zeros( )
328
332
}
329
333
}
@@ -396,8 +400,9 @@ $EndFeature, "
396
400
/// assert_eq!(m, 21760);
397
401
/// ```
398
402
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
403
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
399
404
#[ inline]
400
- pub fn swap_bytes( self ) -> Self {
405
+ pub const fn swap_bytes( self ) -> Self {
401
406
( self as $UnsignedT) . swap_bytes( ) as Self
402
407
}
403
408
@@ -447,9 +452,17 @@ if cfg!(target_endian = \"big\") {
447
452
$EndFeature, "
448
453
```" ) ,
449
454
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
455
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
450
456
#[ inline]
451
- pub fn from_be( x: Self ) -> Self {
452
- if cfg!( target_endian = "big" ) { x } else { x. swap_bytes( ) }
457
+ pub const fn from_be( x: Self ) -> Self {
458
+ #[ cfg( target_endian = "big" ) ]
459
+ {
460
+ x
461
+ }
462
+ #[ cfg( not( target_endian = "big" ) ) ]
463
+ {
464
+ x. swap_bytes( )
465
+ }
453
466
}
454
467
}
455
468
@@ -473,9 +486,17 @@ if cfg!(target_endian = \"little\") {
473
486
$EndFeature, "
474
487
```" ) ,
475
488
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
489
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
476
490
#[ inline]
477
- pub fn from_le( x: Self ) -> Self {
478
- if cfg!( target_endian = "little" ) { x } else { x. swap_bytes( ) }
491
+ pub const fn from_le( x: Self ) -> Self {
492
+ #[ cfg( target_endian = "little" ) ]
493
+ {
494
+ x
495
+ }
496
+ #[ cfg( not( target_endian = "little" ) ) ]
497
+ {
498
+ x. swap_bytes( )
499
+ }
479
500
}
480
501
}
481
502
@@ -499,9 +520,17 @@ if cfg!(target_endian = \"big\") {
499
520
$EndFeature, "
500
521
```" ) ,
501
522
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
523
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
502
524
#[ inline]
503
- pub fn to_be( self ) -> Self { // or not to be?
504
- if cfg!( target_endian = "big" ) { self } else { self . swap_bytes( ) }
525
+ pub const fn to_be( self ) -> Self { // or not to be?
526
+ #[ cfg( target_endian = "big" ) ]
527
+ {
528
+ self
529
+ }
530
+ #[ cfg( not( target_endian = "big" ) ) ]
531
+ {
532
+ self . swap_bytes( )
533
+ }
505
534
}
506
535
}
507
536
@@ -525,9 +554,17 @@ if cfg!(target_endian = \"little\") {
525
554
$EndFeature, "
526
555
```" ) ,
527
556
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
557
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
528
558
#[ inline]
529
- pub fn to_le( self ) -> Self {
530
- if cfg!( target_endian = "little" ) { self } else { self . swap_bytes( ) }
559
+ pub const fn to_le( self ) -> Self {
560
+ #[ cfg( target_endian = "little" ) ]
561
+ {
562
+ self
563
+ }
564
+ #[ cfg( not( target_endian = "little" ) ) ]
565
+ {
566
+ self . swap_bytes( )
567
+ }
531
568
}
532
569
}
533
570
@@ -1943,6 +1980,19 @@ impl isize {
1943
1980
int_impl ! { isize , i64 , u64 , 64 , -9223372036854775808 , 9223372036854775807 , "" , "" }
1944
1981
}
1945
1982
1983
+ // Emits the correct `cttz` call, depending on the size of the type.
1984
+ macro_rules! uint_cttz_call {
1985
+ // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
1986
+ // emits two conditional moves on x86_64. By promoting the value to
1987
+ // u16 and setting bit 8, we get better code without any conditional
1988
+ // operations.
1989
+ // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
1990
+ // pending, remove this workaround once LLVM generates better code
1991
+ // for cttz8.
1992
+ ( $value: expr, 8 ) => { intrinsics:: cttz( $value as u16 | 0x100 ) } ;
1993
+ ( $value: expr, $_BITS: expr) => { intrinsics:: cttz( $value) }
1994
+ }
1995
+
1946
1996
// `Int` + `UnsignedInt` implemented for unsigned integers
1947
1997
macro_rules! uint_impl {
1948
1998
( $SelfT: ty, $ActualT: ty, $BITS: expr, $MaxV: expr, $Feature: expr, $EndFeature: expr) => {
@@ -2020,8 +2070,9 @@ Basic usage:
2020
2070
assert_eq!(n.count_ones(), 3);" , $EndFeature, "
2021
2071
```" ) ,
2022
2072
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2073
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2023
2074
#[ inline]
2024
- pub fn count_ones( self ) -> u32 {
2075
+ pub const fn count_ones( self ) -> u32 {
2025
2076
unsafe { intrinsics:: ctpop( self as $ActualT) as u32 }
2026
2077
}
2027
2078
}
@@ -2037,8 +2088,9 @@ Basic usage:
2037
2088
" , $Feature, "assert_eq!(" , stringify!( $SelfT) , "::max_value().count_zeros(), 0);" , $EndFeature, "
2038
2089
```" ) ,
2039
2090
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2091
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2040
2092
#[ inline]
2041
- pub fn count_zeros( self ) -> u32 {
2093
+ pub const fn count_zeros( self ) -> u32 {
2042
2094
( !self ) . count_ones( )
2043
2095
}
2044
2096
}
@@ -2056,8 +2108,9 @@ Basic usage:
2056
2108
assert_eq!(n.leading_zeros(), 2);" , $EndFeature, "
2057
2109
```" ) ,
2058
2110
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2111
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2059
2112
#[ inline]
2060
- pub fn leading_zeros( self ) -> u32 {
2113
+ pub const fn leading_zeros( self ) -> u32 {
2061
2114
unsafe { intrinsics:: ctlz( self as $ActualT) as u32 }
2062
2115
}
2063
2116
}
@@ -2076,22 +2129,10 @@ Basic usage:
2076
2129
assert_eq!(n.trailing_zeros(), 3);" , $EndFeature, "
2077
2130
```" ) ,
2078
2131
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2132
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2079
2133
#[ inline]
2080
- pub fn trailing_zeros( self ) -> u32 {
2081
- // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
2082
- // emits two conditional moves on x86_64. By promoting the value to
2083
- // u16 and setting bit 8, we get better code without any conditional
2084
- // operations.
2085
- // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
2086
- // pending, remove this workaround once LLVM generates better code
2087
- // for cttz8.
2088
- unsafe {
2089
- if $BITS == 8 {
2090
- intrinsics:: cttz( self as u16 | 0x100 ) as u32
2091
- } else {
2092
- intrinsics:: cttz( self ) as u32
2093
- }
2094
- }
2134
+ pub const fn trailing_zeros( self ) -> u32 {
2135
+ unsafe { uint_cttz_call!( self , $BITS) as u32 }
2095
2136
}
2096
2137
}
2097
2138
@@ -2167,8 +2208,9 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
2167
2208
/// assert_eq!(m, 21760);
2168
2209
/// ```
2169
2210
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2211
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2170
2212
#[ inline]
2171
- pub fn swap_bytes( self ) -> Self {
2213
+ pub const fn swap_bytes( self ) -> Self {
2172
2214
unsafe { intrinsics:: bswap( self as $ActualT) as Self }
2173
2215
}
2174
2216
@@ -2218,9 +2260,17 @@ if cfg!(target_endian = \"big\") {
2218
2260
}" , $EndFeature, "
2219
2261
```" ) ,
2220
2262
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2263
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2221
2264
#[ inline]
2222
- pub fn from_be( x: Self ) -> Self {
2223
- if cfg!( target_endian = "big" ) { x } else { x. swap_bytes( ) }
2265
+ pub const fn from_be( x: Self ) -> Self {
2266
+ #[ cfg( target_endian = "big" ) ]
2267
+ {
2268
+ x
2269
+ }
2270
+ #[ cfg( not( target_endian = "big" ) ) ]
2271
+ {
2272
+ x. swap_bytes( )
2273
+ }
2224
2274
}
2225
2275
}
2226
2276
@@ -2244,9 +2294,17 @@ if cfg!(target_endian = \"little\") {
2244
2294
}" , $EndFeature, "
2245
2295
```" ) ,
2246
2296
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2297
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2247
2298
#[ inline]
2248
- pub fn from_le( x: Self ) -> Self {
2249
- if cfg!( target_endian = "little" ) { x } else { x. swap_bytes( ) }
2299
+ pub const fn from_le( x: Self ) -> Self {
2300
+ #[ cfg( target_endian = "little" ) ]
2301
+ {
2302
+ x
2303
+ }
2304
+ #[ cfg( not( target_endian = "little" ) ) ]
2305
+ {
2306
+ x. swap_bytes( )
2307
+ }
2250
2308
}
2251
2309
}
2252
2310
@@ -2270,9 +2328,17 @@ if cfg!(target_endian = \"big\") {
2270
2328
}" , $EndFeature, "
2271
2329
```" ) ,
2272
2330
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2331
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2273
2332
#[ inline]
2274
- pub fn to_be( self ) -> Self { // or not to be?
2275
- if cfg!( target_endian = "big" ) { self } else { self . swap_bytes( ) }
2333
+ pub const fn to_be( self ) -> Self { // or not to be?
2334
+ #[ cfg( target_endian = "big" ) ]
2335
+ {
2336
+ self
2337
+ }
2338
+ #[ cfg( not( target_endian = "big" ) ) ]
2339
+ {
2340
+ self . swap_bytes( )
2341
+ }
2276
2342
}
2277
2343
}
2278
2344
@@ -2296,9 +2362,17 @@ if cfg!(target_endian = \"little\") {
2296
2362
}" , $EndFeature, "
2297
2363
```" ) ,
2298
2364
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2365
+ #[ rustc_const_unstable( feature = "const_int_ops" ) ]
2299
2366
#[ inline]
2300
- pub fn to_le( self ) -> Self {
2301
- if cfg!( target_endian = "little" ) { self } else { self . swap_bytes( ) }
2367
+ pub const fn to_le( self ) -> Self {
2368
+ #[ cfg( target_endian = "little" ) ]
2369
+ {
2370
+ self
2371
+ }
2372
+ #[ cfg( not( target_endian = "little" ) ) ]
2373
+ {
2374
+ self . swap_bytes( )
2375
+ }
2302
2376
}
2303
2377
}
2304
2378
0 commit comments