malachite_base/num/arithmetic/
checked_pow.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::arithmetic::traits::{CheckedPow, Parity};
10
11macro_rules! impl_checked_pow_unsigned {
12    ($t:ident) => {
13        impl CheckedPow<u64> for $t {
14            type Output = $t;
15
16            /// This is a wrapper over the `checked_pow` functions in the standard library, for
17            /// example [this one](u32::checked_pow).
18            #[inline]
19            fn checked_pow(self, exp: u64) -> Option<$t> {
20                if exp == 0 {
21                    Some(1)
22                } else if self < 2 {
23                    Some(self)
24                } else {
25                    self.checked_pow(u32::try_from(exp).ok()?)
26                }
27            }
28        }
29    };
30}
31apply_to_unsigneds!(impl_checked_pow_unsigned);
32
33macro_rules! impl_checked_pow_signed {
34    ($t:ident) => {
35        impl CheckedPow<u64> for $t {
36            type Output = $t;
37
38            /// This is a wrapper over the `checked_pow` functions in the standard library, for
39            /// example [this one](i32::checked_pow).
40            #[inline]
41            fn checked_pow(self, exp: u64) -> Option<$t> {
42                if exp == 0 {
43                    Some(1)
44                } else if self == 0 || self == 1 {
45                    Some(self)
46                } else if self == -1 {
47                    Some(if exp.even() { 1 } else { -1 })
48                } else {
49                    self.checked_pow(u32::try_from(exp).ok()?)
50                }
51            }
52        }
53    };
54}
55apply_to_signeds!(impl_checked_pow_signed);