@@ -317,50 +317,227 @@ macro_rules! int_module {
317317 }
318318
319319 fn test_pow( ) {
320+ {
321+ const R : $T = 0 ;
322+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
323+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 0 as $T) ;
324+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 0 as $T) ;
325+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
326+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
327+
328+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
329+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 0 as $T) ) ;
330+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 0 as $T) ) ;
331+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 0 as $T) ) ;
332+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( 0 as $T) ) ;
333+
334+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
335+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 0 as $T, false ) ) ;
336+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 0 as $T, false ) ) ;
337+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, false ) ) ;
338+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, false ) ) ;
339+
340+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
341+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 0 as $T) ;
342+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 0 as $T) ;
343+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 0 as $T) ;
344+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , 0 as $T) ;
345+ }
346+
347+ {
348+ const R : $T = 1 ;
349+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
350+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 1 as $T) ;
351+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
352+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
353+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 1 as $T) ;
354+
355+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
356+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 1 as $T) ) ;
357+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 1 as $T) ) ;
358+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 1 as $T) ) ;
359+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( 1 as $T) ) ;
360+
361+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
362+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 1 as $T, false ) ) ;
363+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 1 as $T, false ) ) ;
364+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, false ) ) ;
365+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 1 as $T, false ) ) ;
366+
367+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
368+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 1 as $T) ;
369+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 1 as $T) ;
370+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 1 as $T) ;
371+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , 1 as $T) ;
372+ }
373+
374+ {
375+ const R : $T = -1 ;
376+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
377+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , -1 as $T) ;
378+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
379+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
380+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , -1 as $T) ;
381+
382+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
383+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( -1 as $T) ) ;
384+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 1 as $T) ) ;
385+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 1 as $T) ) ;
386+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( -1 as $T) ) ;
387+
388+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
389+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( -1 as $T, false ) ) ;
390+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 1 as $T, false ) ) ;
391+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, false ) ) ;
392+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( -1 as $T, false ) ) ;
393+
394+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
395+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , -1 as $T) ;
396+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 1 as $T) ;
397+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 1 as $T) ;
398+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , -1 as $T) ;
399+ }
400+
320401 {
321402 const R : $T = 2 ;
322- assert_eq_const_safe!( $T: R . pow( 2 ) , 4 as $T) ;
323- assert_eq_const_safe!( $T: R . pow( 0 ) , 1 as $T) ;
324- assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
325403 assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
326- assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
404+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 2 as $T) ;
405+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
406+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
407+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
408+
327409 assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
328- assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 4 as $T, false ) ) ;
410+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 2 as $T) ) ;
411+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
412+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
413+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
414+
329415 assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
416+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 2 as $T, false ) ) ;
417+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 4 as $T, false ) ) ;
418+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, true ) ) ;
419+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, true ) ) ;
420+
421+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
422+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 2 as $T) ;
330423 assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 4 as $T) ;
424+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
425+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MAX ) ;
426+ }
427+
428+ {
429+ const R : $T = -2 ;
430+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
431+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , -2 as $T) ;
432+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
433+ assert_eq_const_safe!( $T: R . wrapping_pow( $T:: BITS - 1 ) , $T:: MIN ) ;
434+ assert_eq_const_safe!( $T: R . wrapping_pow( $T:: BITS ) , 0 as $T) ;
435+ assert_eq_const_safe!( $T: R . wrapping_pow( $T:: BITS + 1 ) , 0 as $T) ;
436+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
437+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
438+
439+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
440+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( -2 as $T) ) ;
441+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
442+ assert_eq_const_safe!( Option <$T>: R . checked_pow( $T:: BITS - 1 ) , Some ( $T:: MIN ) ) ;
443+ assert_eq_const_safe!( Option <$T>: R . checked_pow( $T:: BITS ) , None ) ;
444+ assert_eq_const_safe!( Option <$T>: R . checked_pow( $T:: BITS + 1 ) , None ) ;
445+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
446+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
447+
448+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
449+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( -2 as $T, false ) ) ;
450+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 4 as $T, false ) ) ;
451+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( $T:: BITS - 1 ) , ( $T:: MIN , false ) ) ;
452+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( $T:: BITS ) , ( 0 as $T, true ) ) ;
453+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( $T:: BITS + 1 ) , ( 0 as $T, true ) ) ;
454+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, true ) ) ;
455+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, true ) ) ;
456+
331457 assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
458+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , -2 as $T) ;
459+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 4 as $T) ;
460+ assert_eq_const_safe!( $T: R . saturating_pow( $T:: BITS - 1 ) , $T:: MIN ) ;
461+ assert_eq_const_safe!( $T: R . saturating_pow( $T:: BITS ) , $T:: MAX ) ;
462+ assert_eq_const_safe!( $T: R . saturating_pow( $T:: BITS + 1 ) , $T:: MIN ) ;
463+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
464+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MIN ) ;
465+ }
466+
467+ // Overflow in the shift caclculation should result in the final
468+ // result being 0 rather than accidentally succeeding due to a
469+ // shift within the word size.
470+ // eg `4 ** 0x8000_0000` should give 0 rather than 1 << 0
471+ {
472+ const R : $T = 4 ;
473+ const HALF : u32 = u32 :: MAX / 2 + 1 ;
474+ assert_eq_const_safe!( $T: R . wrapping_pow( HALF ) , 0 as $T) ;
475+ assert_eq_const_safe!( Option <$T>: R . checked_pow( HALF ) , None ) ;
476+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( HALF ) , ( 0 as $T, true ) ) ;
477+ assert_eq_const_safe!( $T: R . saturating_pow( HALF ) , $T:: MAX ) ;
332478 }
333479
334480 {
335- const R : $T = MAX ;
336- // use `^` to represent .pow() with no overflow.
337- // if itest::MAX == 2^j-1, then itest is a `j` bit int,
338- // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
339- // thussaturating_pow the overflowing result is exactly 1.
481+ const R : $T = -4 ;
482+ const HALF : u32 = u32 :: MAX / 2 + 1 ;
483+ assert_eq_const_safe!( $T: R . wrapping_pow( HALF ) , 0 as $T) ;
484+ assert_eq_const_safe!( Option <$T>: R . checked_pow( HALF ) , None ) ;
485+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( HALF ) , ( 0 as $T, true ) ) ;
486+ assert_eq_const_safe!( $T: R . saturating_pow( HALF ) , $T:: MAX ) ;
487+ }
488+
489+ {
490+ const R : $T = $T:: MAX ;
491+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
492+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , R as $T) ;
340493 assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
494+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
495+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , R as $T) ;
496+
497+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
498+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( R as $T) ) ;
341499 assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , None ) ;
500+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
501+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
502+
503+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
504+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( R as $T, false ) ) ;
342505 assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 1 as $T, true ) ) ;
343- assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , MAX ) ;
506+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, true ) ) ;
507+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( R as $T, true ) ) ;
508+
509+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
510+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , R as $T) ;
511+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , $T:: MAX ) ;
512+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
513+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MAX ) ;
344514 }
345515
346516 {
347- // test for negative exponent.
348- const R : $T = -2 ;
349- assert_eq_const_safe!( $T: R . pow( 2 ) , 4 as $T) ;
350- assert_eq_const_safe!( $T: R . pow( 3 ) , -8 as $T) ;
351- assert_eq_const_safe!( $T: R . pow( 0 ) , 1 as $T) ;
352- assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
353- assert_eq_const_safe!( $T: R . wrapping_pow( 3 ) , -8 as $T) ;
517+ const R : $T = $T:: MIN ;
354518 assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
355- assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
356- assert_eq_const_safe!( Option <$T>: R . checked_pow( 3 ) , Some ( -8 as $T) ) ;
519+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , R as $T) ;
520+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 0 as $T) ;
521+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
522+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
523+
357524 assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
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( 3 ) , ( -8 as $T, false ) ) ;
525+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( R as $T) ) ;
526+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , None ) ;
527+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
528+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
529+
360530 assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
361- assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 4 as $T) ;
362- assert_eq_const_safe!( $T: R . saturating_pow( 3 ) , -8 as $T) ;
531+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( R as $T, false ) ) ;
532+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 0 as $T, true ) ) ;
533+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, true ) ) ;
534+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, true ) ) ;
535+
363536 assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
537+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , R as $T) ;
538+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , $T:: MAX ) ;
539+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
540+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MIN ) ;
364541 }
365542 }
366543
0 commit comments