Skip to content

Commit

Permalink
Merge pull request #2097 from CosmWasm/mergify/bp/release/1.4/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 da9a979 + 77749ef commit 1f8964f
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

### Changed

- cosmwasm-vm: Read `Region` from Wasm memory as bytes and convert to `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 @@ -363,21 +363,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 @@ -781,10 +774,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 @@ -814,11 +803,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 @@ -435,14 +435,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 @@ -1289,10 +1282,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 @@ -1322,7 +1311,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 @@ -415,17 +415,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 @@ -993,14 +990,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 @@ -1026,9 +1015,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 @@ -326,17 +326,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 @@ -704,10 +701,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 @@ -727,6 +720,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 1f8964f

Please sign in to comment.