Skip to content

Commit

Permalink
Merge pull request #2096 from CosmWasm/mergify/bp/release/1.5/pr-2092
Browse files Browse the repository at this point in the history
Implement add for Uint* more consistently (backport #2092)
  • Loading branch information
webmaster128 authored Apr 9, 2024
2 parents 5215d3b + a39a171 commit 98d37d7
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 62 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and this project adheres to

## [Unreleased]

### Added

- cosmwasm-std: Implement `&T + T` and `&T op &T` for `Uint64`, `Uint128`,
`Uint256` and `Uint512`; improve panic message for `Uint64::add` and
`Uint512::add` ([#2092])

[#2092]: https://github.com/CosmWasm/cosmwasm/pull/2092

### Fixed

- cosmwasm-std: Correctly deallocate vectors that were turned into a `Region`
Expand Down
44 changes: 27 additions & 17 deletions packages/std/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,21 +372,14 @@ impl Add<Uint128> for Uint128 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Uint128(
Self(
self.u128()
.checked_add(rhs.u128())
.expect("attempt to add with overflow"),
)
}
}

impl<'a> Add<&'a Uint128> for Uint128 {
type Output = Self;

fn add(self, rhs: &'a Uint128) -> Self {
self + *rhs
}
}
forward_ref_binop!(impl Add, add for Uint128, Uint128);

impl Sub<Uint128> for Uint128 {
type Output = Self;
Expand Down Expand Up @@ -811,10 +804,6 @@ mod tests {
let a = Uint128(12345);
let b = Uint128(23456);

// test + with owned and reference right hand side
assert_eq!(a + b, Uint128(35801));
assert_eq!(a + &b, Uint128(35801));

// test - with owned and reference right hand side
assert_eq!(b - a, Uint128(11111));
assert_eq!(b - &a, Uint128(11111));
Expand Down Expand Up @@ -844,11 +833,32 @@ mod tests {
}

#[test]
#[should_panic]
#[allow(clippy::op_ref)]
fn uint128_add_works() {
assert_eq!(
Uint128::from(2u32) + Uint128::from(1u32),
Uint128::from(3u32)
);
assert_eq!(
Uint128::from(2u32) + Uint128::from(0u32),
Uint128::from(2u32)
);

// works for refs
let a = Uint128::from(10u32);
let b = Uint128::from(3u32);
let expected = Uint128::from(13u32);
assert_eq!(a + b, expected);
assert_eq!(a + &b, expected);
assert_eq!(&a + b, expected);
assert_eq!(&a + &b, expected);
}

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint128_add_overflow_panics() {
// almost_max is 2^128 - 10
let almost_max = Uint128(340282366920938463463374607431768211446);
let _ = almost_max + Uint128(12);
let max = Uint128::MAX;
let _ = max + Uint128(12);
}

#[test]
Expand Down
37 changes: 24 additions & 13 deletions packages/std/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,7 @@ impl Add<Uint256> for Uint256 {
)
}
}

impl<'a> Add<&'a Uint256> for Uint256 {
type Output = Self;

fn add(self, rhs: &'a Uint256) -> Self {
self + *rhs
}
}
forward_ref_binop!(impl Add, add for Uint256, Uint256);

impl Sub<Uint256> for Uint256 {
type Output = Self;
Expand Down Expand Up @@ -1328,10 +1321,6 @@ mod tests {
let a = Uint256::from(12345u32);
let b = Uint256::from(23456u32);

// test + with owned and reference right hand side
assert_eq!(a + b, Uint256::from(35801u32));
assert_eq!(a + &b, Uint256::from(35801u32));

// test - with owned and reference right hand side
assert_eq!(b - a, Uint256::from(11111u32));
assert_eq!(b - &a, Uint256::from(11111u32));
Expand Down Expand Up @@ -1361,7 +1350,29 @@ mod tests {
}

#[test]
#[should_panic]
#[allow(clippy::op_ref)]
fn uint256_add_works() {
assert_eq!(
Uint256::from(2u32) + Uint256::from(1u32),
Uint256::from(3u32)
);
assert_eq!(
Uint256::from(2u32) + Uint256::from(0u32),
Uint256::from(2u32)
);

// works for refs
let a = Uint256::from(10u32);
let b = Uint256::from(3u32);
let expected = Uint256::from(13u32);
assert_eq!(a + b, expected);
assert_eq!(a + &b, expected);
assert_eq!(&a + b, expected);
assert_eq!(&a + &b, expected);
}

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint256_add_overflow_panics() {
let max = Uint256::new([255u8; 32]);
let _ = max + Uint256::from(12u32);
Expand Down
49 changes: 30 additions & 19 deletions packages/std/src/math/uint512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,17 +424,14 @@ impl Add<Uint512> for Uint512 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Uint512(self.0.checked_add(rhs.0).unwrap())
}
}

impl<'a> Add<&'a Uint512> for Uint512 {
type Output = Self;

fn add(self, rhs: &'a Uint512) -> Self {
Uint512(self.0.checked_add(rhs.0).unwrap())
Self(
self.0
.checked_add(rhs.0)
.expect("attempt to add with overflow"),
)
}
}
forward_ref_binop!(impl Add, add for Uint512, Uint512);

impl Sub<Uint512> for Uint512 {
type Output = Self;
Expand Down Expand Up @@ -1034,14 +1031,6 @@ mod tests {
let a = Uint512::from(12345u32);
let b = Uint512::from(23456u32);

// test + with owned and reference right hand side
assert_eq!(a + b, Uint512::from(35801u32));
assert_eq!(a + &b, Uint512::from(35801u32));

// test - with owned and reference right hand side
assert_eq!(b - a, Uint512::from(11111u32));
assert_eq!(b - &a, Uint512::from(11111u32));

// test += with owned and reference right hand side
let mut c = Uint512::from(300000u32);
c += b;
Expand All @@ -1067,9 +1056,31 @@ mod tests {
}

#[test]
#[should_panic]
#[allow(clippy::op_ref)]
fn uint512_add_works() {
assert_eq!(
Uint512::from(2u32) + Uint512::from(1u32),
Uint512::from(3u32)
);
assert_eq!(
Uint512::from(2u32) + Uint512::from(0u32),
Uint512::from(2u32)
);

// works for refs
let a = Uint512::from(10u32);
let b = Uint512::from(3u32);
let expected = Uint512::from(13u32);
assert_eq!(a + b, expected);
assert_eq!(a + &b, expected);
assert_eq!(&a + b, expected);
assert_eq!(&a + &b, expected);
}

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint512_add_overflow_panics() {
let max = Uint512::new([255u8; 64]);
let max = Uint512::MAX;
let _ = max + Uint512::from(12u32);
}

Expand Down
42 changes: 29 additions & 13 deletions packages/std/src/math/uint64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,17 +345,14 @@ impl Add<Uint64> for Uint64 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Uint64(self.u64().checked_add(rhs.u64()).unwrap())
}
}

impl<'a> Add<&'a Uint64> for Uint64 {
type Output = Self;

fn add(self, rhs: &'a Uint64) -> Self {
Uint64(self.u64().checked_add(rhs.u64()).unwrap())
Self(
self.u64()
.checked_add(rhs.u64())
.expect("attempt to add with overflow"),
)
}
}
forward_ref_binop!(impl Add, add for Uint64, Uint64);

impl Sub<Uint64> for Uint64 {
type Output = Self;
Expand Down Expand Up @@ -732,10 +729,6 @@ mod tests {
let a = Uint64(12345);
let b = Uint64(23456);

// test + with owned and reference right hand side
assert_eq!(a + b, Uint64(35801));
assert_eq!(a + &b, Uint64(35801));

// test - with owned and reference right hand side
assert_eq!((b.checked_sub(a)).unwrap(), Uint64(11111));

Expand All @@ -755,6 +748,29 @@ mod tests {
assert_eq!((operand1, operand2), (a.to_string(), b.to_string()));
}

#[test]
#[allow(clippy::op_ref)]
fn uint64_add_works() {
assert_eq!(Uint64::from(2u32) + Uint64::from(1u32), Uint64::from(3u32));
assert_eq!(Uint64::from(2u32) + Uint64::from(0u32), Uint64::from(2u32));

// works for refs
let a = Uint64::from(10u32);
let b = Uint64::from(3u32);
let expected = Uint64::from(13u32);
assert_eq!(a + b, expected);
assert_eq!(a + &b, expected);
assert_eq!(&a + b, expected);
assert_eq!(&a + &b, expected);
}

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint64_add_overflow_panics() {
let max = Uint64::MAX;
let _ = max + Uint64(12);
}

#[test]
#[allow(clippy::op_ref)]
fn uint64_sub_works() {
Expand Down

0 comments on commit 98d37d7

Please sign in to comment.