@@ -271,6 +271,83 @@ macro_rules! uint_module {
271271 assert_eq!( from_str:: <$T>( "x" ) , None ) ;
272272 }
273273
274+ // Not const because `catch_unwind` is not const yet.
275+ #[ test]
276+ fn strict_pow( ) {
277+ use std:: panic:: catch_unwind;
278+
279+ {
280+ const R : $T = 0 ;
281+ assert_eq!( R . strict_pow( 0 ) , 1 as $T) ;
282+ assert_eq!( R . strict_pow( 1 ) , 0 as $T) ;
283+ assert_eq!( R . strict_pow( 2 ) , 0 as $T) ;
284+ assert_eq!( R . strict_pow( 128 ) , 0 as $T) ;
285+ }
286+
287+ {
288+ const R : $T = 1 ;
289+ assert_eq!( R . strict_pow( 0 ) , 1 as $T) ;
290+ assert_eq!( R . strict_pow( 1 ) , 1 as $T) ;
291+ assert_eq!( R . strict_pow( 2 ) , 1 as $T) ;
292+ assert_eq!( R . strict_pow( 128 ) , 1 as $T) ;
293+ }
294+
295+ {
296+ const R : $T = 2 ;
297+ assert_eq!( R . strict_pow( 0 ) , 1 as $T) ;
298+ assert_eq!( R . strict_pow( 1 ) , 2 as $T) ;
299+ assert_eq!( R . strict_pow( 2 ) , 4 as $T) ;
300+ assert!( catch_unwind( || R . strict_pow( 128 ) ) . is_err( ) ) ;
301+ }
302+
303+ {
304+ const R : $T = $T:: MAX ;
305+ assert_eq!( R . strict_pow( 0 ) , 1 as $T) ;
306+ assert_eq!( R . strict_pow( 1 ) , R as $T) ;
307+ assert!( catch_unwind( || R . strict_pow( 2 ) ) . is_err( ) ) ;
308+ assert!( catch_unwind( || R . strict_pow( 128 ) ) . is_err( ) ) ;
309+ }
310+ }
311+
312+ // Not const because overflow always panics during const evaluation, and
313+ // `catch_unwind` is not const yet.
314+ #[ test]
315+ fn pow( ) {
316+ {
317+ const R : $T = 0 ;
318+ assert_eq!( R . pow( 0 ) , 1 as $T) ;
319+ assert_eq!( R . pow( 1 ) , 0 as $T) ;
320+ assert_eq!( R . pow( 2 ) , 0 as $T) ;
321+ assert_eq!( R . pow( 128 ) , 0 as $T) ;
322+ }
323+
324+ {
325+ const R : $T = 1 ;
326+ assert_eq!( R . pow( 0 ) , 1 as $T) ;
327+ assert_eq!( R . pow( 1 ) , 1 as $T) ;
328+ assert_eq!( R . pow( 2 ) , 1 as $T) ;
329+ assert_eq!( R . pow( 128 ) , 1 as $T) ;
330+ }
331+
332+ {
333+ const R : $T = 2 ;
334+ assert_eq!( R . pow( 0 ) , 1 as $T) ;
335+ assert_eq!( R . pow( 1 ) , 2 as $T) ;
336+ assert_eq!( R . pow( 2 ) , 4 as $T) ;
337+ assert_eq!( R . pow( 128 ) , 0 as $T) ;
338+ assert_eq!( R . pow( 129 ) , 0 as $T) ;
339+ }
340+
341+ {
342+ const R : $T = $T:: MAX ;
343+ assert_eq!( R . pow( 0 ) , 1 as $T) ;
344+ assert_eq!( R . pow( 1 ) , R as $T) ;
345+ assert_eq!( R . pow( 2 ) , 1 as $T) ;
346+ assert_eq!( R . pow( 128 ) , 1 as $T) ;
347+ assert_eq!( R . pow( 129 ) , R as $T) ;
348+ }
349+ }
350+
274351 test_runtime_and_compiletime! {
275352 fn test_parse_bytes( ) {
276353 assert_eq_const_safe!( Result <$T, ParseIntError >: $T:: from_str_radix( "123" , 10 ) , Ok ( 123 as $T) ) ;
@@ -285,30 +362,112 @@ macro_rules! uint_module {
285362 }
286363
287364 fn test_pow( ) {
365+ {
366+ const R : $T = 0 ;
367+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
368+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 0 as $T) ;
369+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 0 as $T) ;
370+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
371+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
372+
373+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
374+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 0 as $T) ) ;
375+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 0 as $T) ) ;
376+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 0 as $T) ) ;
377+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( 0 as $T) ) ;
378+
379+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
380+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 0 as $T, false ) ) ;
381+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 0 as $T, false ) ) ;
382+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, false ) ) ;
383+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, false ) ) ;
384+
385+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
386+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 0 as $T) ;
387+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 0 as $T) ;
388+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 0 as $T) ;
389+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , 0 as $T) ;
390+ }
391+
392+ {
393+ const R : $T = 1 ;
394+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
395+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 1 as $T) ;
396+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
397+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
398+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 1 as $T) ;
399+
400+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
401+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 1 as $T) ) ;
402+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 1 as $T) ) ;
403+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , Some ( 1 as $T) ) ;
404+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , Some ( 1 as $T) ) ;
405+
406+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
407+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 1 as $T, false ) ) ;
408+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 1 as $T, false ) ) ;
409+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, false ) ) ;
410+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 1 as $T, false ) ) ;
411+
412+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
413+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 1 as $T) ;
414+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 1 as $T) ;
415+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , 1 as $T) ;
416+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , 1 as $T) ;
417+ }
418+
288419 {
289420 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) ;
293421 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) ) ;
422+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , 2 as $T) ;
423+ assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 4 as $T) ;
424+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 0 as $T) ;
425+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , 0 as $T) ;
426+
295427 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 ) ) ;
428+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( 2 as $T) ) ;
429+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , Some ( 4 as $T) ) ;
430+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
431+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
432+
297433 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) ;
434+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( 2 as $T, false ) ) ;
435+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 2 ) , ( 4 as $T, false ) ) ;
436+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 0 as $T, true ) ) ;
437+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( 0 as $T, true ) ) ;
438+
299439 assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
440+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , 2 as $T) ;
441+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , 4 as $T) ;
442+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
443+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MAX ) ;
300444 }
301445
302446 {
303447 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.
448+ assert_eq_const_safe!( $T: R . wrapping_pow( 0 ) , 1 as $T) ;
449+ assert_eq_const_safe!( $T: R . wrapping_pow( 1 ) , R as $T) ;
308450 assert_eq_const_safe!( $T: R . wrapping_pow( 2 ) , 1 as $T) ;
451+ assert_eq_const_safe!( $T: R . wrapping_pow( 128 ) , 1 as $T) ;
452+ assert_eq_const_safe!( $T: R . wrapping_pow( 129 ) , R as $T) ;
453+
454+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 0 ) , Some ( 1 as $T) ) ;
455+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 1 ) , Some ( R as $T) ) ;
309456 assert_eq_const_safe!( Option <$T>: R . checked_pow( 2 ) , None ) ;
457+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 128 ) , None ) ;
458+ assert_eq_const_safe!( Option <$T>: R . checked_pow( 129 ) , None ) ;
459+
460+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 0 ) , ( 1 as $T, false ) ) ;
461+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 1 ) , ( R as $T, false ) ) ;
310462 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 ) ;
463+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 128 ) , ( 1 as $T, true ) ) ;
464+ assert_eq_const_safe!( ( $T, bool ) : R . overflowing_pow( 129 ) , ( R as $T, true ) ) ;
465+
466+ assert_eq_const_safe!( $T: R . saturating_pow( 0 ) , 1 as $T) ;
467+ assert_eq_const_safe!( $T: R . saturating_pow( 1 ) , R as $T) ;
468+ assert_eq_const_safe!( $T: R . saturating_pow( 2 ) , $T:: MAX ) ;
469+ assert_eq_const_safe!( $T: R . saturating_pow( 128 ) , $T:: MAX ) ;
470+ assert_eq_const_safe!( $T: R . saturating_pow( 129 ) , $T:: MAX ) ;
312471 }
313472 }
314473
0 commit comments