Skip to content

Commit

Permalink
Add panicking_sub to Uint64/Uint128/Uint256/Uint512
Browse files Browse the repository at this point in the history
  • Loading branch information
webmaster128 committed Apr 10, 2024
1 parent 5b4adab commit 547efed
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ and this project adheres to
`Uint512::add` ([#2092])
- cosmwasm-std: Add `{CosmosMsg,SubMsg,Response}::change_custom` to change the
custom message type ([#2099])
- cosmwasm-std: Add `Uint{64,128,256,512}::panicking_sub` which is like the
`Sub` implementation but `const`.

[#1983]: https://github.com/CosmWasm/cosmwasm/pull/1983
[#2057]: https://github.com/CosmWasm/cosmwasm/pull/2057
Expand Down
32 changes: 27 additions & 5 deletions packages/core/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,17 @@ impl Uint128 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint128::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.u128()) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(if self.0 < other.0 {
Expand Down Expand Up @@ -385,11 +396,7 @@ impl Sub<Uint128> for Uint128 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint128(
self.u128()
.checked_sub(rhs.u128())
.expect("attempt to subtract with overflow"),
)
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
Expand Down Expand Up @@ -1176,6 +1183,21 @@ mod tests {
assert_eq!(a, Uint128::from(1u32));
}

#[test]
fn uint128_panicking_sub_works() {
let a = Uint128::new(5);
let b = Uint128::new(3);
assert_eq!(a.panicking_sub(b), Uint128::new(2));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint128_panicking_sub_panics_on_overflow() {
let a = Uint128::ZERO;
let b = Uint128::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint128_abs_diff_works() {
let a = Uint128::from(42u32);
Expand Down
32 changes: 27 additions & 5 deletions packages/core/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,17 @@ impl Uint256 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint256::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.0) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(self.0.abs_diff(other.0))
Expand Down Expand Up @@ -455,11 +466,7 @@ impl Sub<Uint256> for Uint256 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Self(
self.0
.checked_sub(rhs.0)
.expect("attempt to subtract with overflow"),
)
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint256, Uint256);
Expand Down Expand Up @@ -1725,6 +1732,21 @@ mod tests {
assert_eq!(a, Uint256::from(1u32));
}

#[test]
fn uint256_panicking_sub_works() {
let a = Uint256::from(5u32);
let b = Uint256::from(3u32);
assert_eq!(a.panicking_sub(b), Uint256::from(2u32));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint256_panicking_sub_panics_on_overflow() {
let a = Uint256::ZERO;
let b = Uint256::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint256_abs_diff_works() {
let a = Uint256::from(42u32);
Expand Down
28 changes: 27 additions & 1 deletion packages/core/src/math/uint512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,17 @@ impl Uint512 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint512::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.0) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(self.0.abs_diff(other.0))
Expand Down Expand Up @@ -434,7 +445,7 @@ impl Sub<Uint512> for Uint512 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint512(self.0.checked_sub(rhs.0).unwrap())
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
Expand Down Expand Up @@ -1370,6 +1381,21 @@ mod tests {
assert_eq!(a, Uint512::from(1u32));
}

#[test]
fn uint512_panicking_sub_works() {
let a = Uint512::from(5u32);
let b = Uint512::from(3u32);
assert_eq!(a.panicking_sub(b), Uint512::from(2u32));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint512_panicking_sub_panics_on_overflow() {
let a = Uint512::ZERO;
let b = Uint512::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint512_abs_diff_works() {
let a = Uint512::from(42u32);
Expand Down
32 changes: 27 additions & 5 deletions packages/core/src/math/uint64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,17 @@ impl Uint64 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint64::sub`] but const.
///
/// Panics on overflow.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.u64()) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
}
}

#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn abs_diff(self, other: Self) -> Self {
Self(if self.0 < other.0 {
Expand Down Expand Up @@ -358,11 +369,7 @@ impl Sub<Uint64> for Uint64 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint64(
self.u64()
.checked_sub(rhs.u64())
.expect("attempt to subtract with overflow"),
)
self.panicking_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint64, Uint64);
Expand Down Expand Up @@ -1090,6 +1097,21 @@ mod tests {
assert_eq!(a, Uint64::from(1u32));
}

#[test]
fn uint64_panicking_sub_works() {
let a = Uint64::new(5);
let b = Uint64::new(3);
assert_eq!(a.panicking_sub(b), Uint64::new(2));
}

#[test]
#[should_panic(expected = "attempt to subtract with overflow")]
fn uint64_panicking_sub_panics_on_overflow() {
let a = Uint64::ZERO;
let b = Uint64::ONE;
let _diff = a.panicking_sub(b);
}

#[test]
fn uint64_abs_diff_works() {
let a = Uint64::from(42u32);
Expand Down

0 comments on commit 547efed

Please sign in to comment.