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