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);