@@ -285,30 +285,125 @@ macro_rules! uint_module {
285285 }
286286
287287 fn test_pow( ) {
288+ {
289+ const R : $T = 0 ;
290+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
291+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 0 as $T) ;
292+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 0 as $T) ;
293+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
294+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
295+
296+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
297+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 0 as $T) ) ;
298+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 0 as $T) ) ;
299+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 0 as $T) ) ;
300+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( 0 as $T) ) ;
301+
302+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
303+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 0 as $T, false ) ) ;
304+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 0 as $T, false ) ) ;
305+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, false ) ) ;
306+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, false ) ) ;
307+
308+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
309+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 0 as $T) ;
310+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 0 as $T) ;
311+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 0 as $T) ;
312+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , 0 as $T) ;
313+ }
314+
315+ {
316+ const R : $T = 1 ;
317+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
318+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 1 as $T) ;
319+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
320+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
321+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 1 as $T) ;
322+
323+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
324+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 1 as $T) ) ;
325+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 1 as $T) ) ;
326+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 1 as $T) ) ;
327+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( 1 as $T) ) ;
328+
329+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
330+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 1 as $T, false ) ) ;
331+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 1 as $T, false ) ) ;
332+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, false ) ) ;
333+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 1 as $T, false ) ) ;
334+
335+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
336+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 1 as $T) ;
337+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 1 as $T) ;
338+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 1 as $T) ;
339+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , 1 as $T) ;
340+ }
341+
288342 {
289343 const R : $T = 2 ;
290- assert_eq_const_safe!( $T: R . pow( 2 ) , 4 as $T) ;
291- assert_eq_const_safe!( $T: R . pow( 0 ) , 1 as $T) ;
292- assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
293344 assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
294- assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
345+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 2 as $T) ;
346+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
347+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
348+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
349+
295350 assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
296- assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 4 as $T, false ) ) ;
351+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 2 as $T) ) ;
352+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
353+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
354+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
355+
297356 assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
298- assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 4 as $T) ;
357+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 2 as $T, false ) ) ;
358+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 4 as $T, false ) ) ;
359+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, true ) ) ;
360+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, true ) ) ;
361+
299362 assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
363+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 2 as $T) ;
364+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 4 as $T) ;
365+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
366+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MAX ) ;
367+ }
368+
369+ // Overflow in the shift caclculation should result in the final
370+ // result being 0 rather than accidentally succeeding due to a
371+ // shift within the word size.
372+ // eg `4 ** 0x8000_0000` should give 0 rather than 1 << 0
373+ {
374+ const R : $T = 4 ;
375+ const HALF : u32 = u32 :: MAX / 2 + 1 ;
376+ assert_eq_const_safe!( $T: R . wrapping_pow( HALF ) , 0 as $T) ;
377+ assert_eq_const_safe!( Option <$T>: R . checked_pow( HALF ) , None ) ;
378+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( HALF ) , ( 0 as $T, true ) ) ;
379+ assert_eq_const_safe!( $T: R . saturating_pow( HALF ) , $T:: MAX ) ;
300380 }
301381
302382 {
303383 const R : $T = $T:: MAX ;
304- // use `^` to represent .pow() with no overflow.
305- // if itest::MAX == 2^j-1, then itest is a `j` bit int,
306- // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
307- // thussaturating_pow the overflowing result is exactly 1.
384+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
385+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , R as $T) ;
308386 assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
387+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
388+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , R as $T) ;
389+
390+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
391+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( R as $T) ) ;
309392 assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , None ) ;
393+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
394+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
395+
396+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
397+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( R as $T, false ) ) ;
310398 assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 1 as $T, true ) ) ;
311- assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , MAX ) ;
399+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, true ) ) ;
400+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( R as $T, true ) ) ;
401+
402+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
403+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , R as $T) ;
404+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , $T:: MAX ) ;
405+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
406+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MAX ) ;
312407 }
313408 }
314409
0 commit comments