@@ -2131,23 +2131,10 @@ macro_rules! uint_impl {
21312131 without modifying the original"]
21322132 #[ inline]
21332133 #[ track_caller]
2134- pub const fn strict_pow( self , mut exp: u32 ) -> Self {
2135- if exp == 0 {
2136- return 1 ;
2137- }
2138- let mut base = self ;
2139- let mut acc: Self = 1 ;
2140-
2141- loop {
2142- if ( exp & 1 ) == 1 {
2143- acc = acc. strict_mul( base) ;
2144- // since exp!=0, finally the exp must be 1.
2145- if exp == 1 {
2146- return acc;
2147- }
2148- }
2149- exp /= 2 ;
2150- base = base. strict_mul( base) ;
2134+ pub const fn strict_pow( self , exp: u32 ) -> Self {
2135+ match self . checked_pow( exp) {
2136+ None => overflow_panic:: pow( ) ,
2137+ Some ( a) => a,
21512138 }
21522139 }
21532140
@@ -2609,43 +2596,9 @@ macro_rules! uint_impl {
26092596 #[ must_use = "this returns the result of the operation, \
26102597 without modifying the original"]
26112598 #[ inline]
2612- pub const fn wrapping_pow( self , mut exp: u32 ) -> Self {
2613- if exp == 0 {
2614- return 1 ;
2615- }
2616- let mut base = self ;
2617- let mut acc: Self = 1 ;
2618-
2619- if intrinsics:: is_val_statically_known( exp) {
2620- while exp > 1 {
2621- if ( exp & 1 ) == 1 {
2622- acc = acc. wrapping_mul( base) ;
2623- }
2624- exp /= 2 ;
2625- base = base. wrapping_mul( base) ;
2626- }
2627-
2628- // since exp!=0, finally the exp must be 1.
2629- // Deal with the final bit of the exponent separately, since
2630- // squaring the base afterwards is not necessary.
2631- acc. wrapping_mul( base)
2632- } else {
2633- // This is faster than the above when the exponent is not known
2634- // at compile time. We can't use the same code for the constant
2635- // exponent case because LLVM is currently unable to unroll
2636- // this loop.
2637- loop {
2638- if ( exp & 1 ) == 1 {
2639- acc = acc. wrapping_mul( base) ;
2640- // since exp!=0, finally the exp must be 1.
2641- if exp == 1 {
2642- return acc;
2643- }
2644- }
2645- exp /= 2 ;
2646- base = base. wrapping_mul( base) ;
2647- }
2648- }
2599+ pub const fn wrapping_pow( self , exp: u32 ) -> Self {
2600+ let ( a, _) = self . overflowing_pow( exp) ;
2601+ a
26492602 }
26502603
26512604 /// Calculates `self` + `rhs`.
@@ -3286,30 +3239,26 @@ macro_rules! uint_impl {
32863239 without modifying the original"]
32873240 #[ inline]
32883241 pub const fn overflowing_pow( self , mut exp: u32 ) -> ( Self , bool ) {
3289- if exp == 0 {
3290- return ( 1 , false ) ;
3242+ if exp == 0 {
3243+ return ( 1 , false ) ;
32913244 }
32923245 let mut base = self ;
32933246 let mut acc: Self = 1 ;
3294- let mut overflown = false ;
3295- // Scratch space for storing results of overflowing_mul.
3296- let mut r;
3247+ let mut overflow = false ;
3248+ let mut tmp_overflow;
32973249
32983250 loop {
32993251 if ( exp & 1 ) == 1 {
3300- r = acc. overflowing_mul( base) ;
3252+ ( acc, tmp_overflow) = acc. overflowing_mul( base) ;
3253+ overflow |= tmp_overflow;
33013254 // since exp!=0, finally the exp must be 1.
33023255 if exp == 1 {
3303- r. 1 |= overflown;
3304- return r;
3256+ return ( acc, overflow) ;
33053257 }
3306- acc = r. 0 ;
3307- overflown |= r. 1 ;
33083258 }
33093259 exp /= 2 ;
3310- r = base. overflowing_mul( base) ;
3311- base = r. 0 ;
3312- overflown |= r. 1 ;
3260+ ( base, tmp_overflow) = base. overflowing_mul( base) ;
3261+ overflow |= tmp_overflow;
33133262 }
33143263 }
33153264
@@ -3327,43 +3276,11 @@ macro_rules! uint_impl {
33273276 without modifying the original"]
33283277 #[ inline]
33293278 #[ rustc_inherit_overflow_checks]
3330- pub const fn pow( self , mut exp: u32 ) -> Self {
3331- if exp == 0 {
3332- return 1 ;
3333- }
3334- let mut base = self ;
3335- let mut acc = 1 ;
3336-
3337- if intrinsics:: is_val_statically_known( exp) {
3338- while exp > 1 {
3339- if ( exp & 1 ) == 1 {
3340- acc = acc * base;
3341- }
3342- exp /= 2 ;
3343- base = base * base;
3344- }
3345-
3346- // since exp!=0, finally the exp must be 1.
3347- // Deal with the final bit of the exponent separately, since
3348- // squaring the base afterwards is not necessary and may cause a
3349- // needless overflow.
3350- acc * base
3279+ pub const fn pow( self , exp: u32 ) -> Self {
3280+ if intrinsics:: overflow_checks( ) {
3281+ self . strict_pow( exp)
33513282 } else {
3352- // This is faster than the above when the exponent is not known
3353- // at compile time. We can't use the same code for the constant
3354- // exponent case because LLVM is currently unable to unroll
3355- // this loop.
3356- loop {
3357- if ( exp & 1 ) == 1 {
3358- acc = acc * base;
3359- // since exp!=0, finally the exp must be 1.
3360- if exp == 1 {
3361- return acc;
3362- }
3363- }
3364- exp /= 2 ;
3365- base = base * base;
3366- }
3283+ self . wrapping_pow( exp)
33673284 }
33683285 }
33693286
0 commit comments