Skip to content

Commit

Permalink
Rename math functions to strict_add/strict_sub (backport #2107) (#2110)
Browse files Browse the repository at this point in the history
* Rename math functions to strict_add/strict_sub (#2107)

(cherry picked from commit 3b59561)

# Conflicts:
#	CHANGELOG.md

* Fix CHANGELOG

---------

Co-authored-by: Simon Warta <[email protected]>
Co-authored-by: Simon Warta <[email protected]>
  • Loading branch information
3 people authored Apr 15, 2024
1 parent 695970c commit 41b1d16
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 58 deletions.
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ and this project adheres to
- 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])
- cosmwasm-std: Add `Uint{64,128,256,512}::panicking_add` and `::panicking_sub`
which are like the `Add`/`Sub` implementations but `const`. ([#2098])
- cosmwasm-std: Let `Timestamp::plus_nanos`/`::minus_nanos` use
`Uint64::panicking_add`/`::panicking_sub` and document overflows. ([#2098])
- cosmwasm-std: Add `Uint{64,128,256,512}::strict_add` and `::strict_sub` which
are like the `Add`/`Sub` implementations but `const`. ([#2098], [#2107])

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

### Changed

- cosmwasm-std: Let `Timestamp::plus_nanos`/`::minus_nanos` use
`Uint64::strict_add`/`::strict_sub` and document overflows. ([#2098], [#2107])

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

### Fixed

Expand Down
42 changes: 29 additions & 13 deletions packages/std/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,22 +263,22 @@ impl Uint128 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint128::add`] but const.
/// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint128::add`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.u128()) {
pub const fn strict_add(self, rhs: Self) -> Self {
match self.0.checked_add(rhs.u128()) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint128::sub`] but const.
/// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint128::sub`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
pub const fn strict_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.u128()) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
Expand Down Expand Up @@ -394,7 +394,7 @@ impl Add<Uint128> for Uint128 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
self.panicking_add(rhs)
self.strict_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint128, Uint128);
Expand All @@ -403,7 +403,7 @@ impl Sub<Uint128> for Uint128 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
self.panicking_sub(rhs)
self.strict_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
Expand Down Expand Up @@ -1193,18 +1193,34 @@ mod tests {
}

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

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint128_strict_add_panics_on_overflow() {
let a = Uint128::MAX;
let b = Uint128::ONE;
let _ = a.strict_add(b);
}

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

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

#[test]
Expand Down
42 changes: 29 additions & 13 deletions packages/std/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,22 +335,22 @@ impl Uint256 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint256::add`] but const.
/// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint256::add`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.0) {
pub const fn strict_add(self, rhs: Self) -> Self {
match self.0.checked_add(rhs.0) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint256::sub`] but const.
/// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint256::sub`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
pub const fn strict_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.0) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
Expand Down Expand Up @@ -462,7 +462,7 @@ impl Add<Uint256> for Uint256 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
self.panicking_add(rhs)
self.strict_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint256, Uint256);
Expand All @@ -471,7 +471,7 @@ impl Sub<Uint256> for Uint256 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
self.panicking_sub(rhs)
self.strict_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint256, Uint256);
Expand Down Expand Up @@ -1744,18 +1744,34 @@ mod tests {
}

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

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint256_strict_add_panics_on_overflow() {
let a = Uint256::MAX;
let b = Uint256::ONE;
let _ = a.strict_add(b);
}

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

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

#[test]
Expand Down
42 changes: 29 additions & 13 deletions packages/std/src/math/uint512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,22 +297,22 @@ impl Uint512 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint512::add`] but const.
/// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint512::add`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.0) {
pub const fn strict_add(self, rhs: Self) -> Self {
match self.0.checked_add(rhs.0) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint512::sub`] but const.
/// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint512::sub`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
pub const fn strict_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.0) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
Expand Down Expand Up @@ -446,7 +446,7 @@ impl Add<Uint512> for Uint512 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
self.panicking_add(rhs)
self.strict_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint512, Uint512);
Expand All @@ -455,7 +455,7 @@ impl Sub<Uint512> for Uint512 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
self.panicking_sub(rhs)
self.strict_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
Expand Down Expand Up @@ -1398,18 +1398,34 @@ mod tests {
}

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

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint512_strict_add_panics_on_overflow() {
let a = Uint512::MAX;
let b = Uint512::ONE;
let _ = a.strict_add(b);
}

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

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

#[test]
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 @@ -257,22 +257,22 @@ impl Uint64 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint64::add`] but const.
/// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint64::add`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_add(self, other: Self) -> Self {
match self.0.checked_add(other.u64()) {
pub const fn strict_add(self, rhs: Self) -> Self {
match self.0.checked_add(rhs.u64()) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// This is the same as [`Uint64::sub`] but const.
/// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
///
/// Panics on overflow.
/// This is the same as [`Uint64::sub`] but const.
#[must_use = "this returns the result of the operation, without modifying the original"]
pub const fn panicking_sub(self, other: Self) -> Self {
pub const fn strict_sub(self, other: Self) -> Self {
match self.0.checked_sub(other.u64()) {
None => panic!("attempt to subtract with overflow"),
Some(diff) => Self(diff),
Expand Down Expand Up @@ -367,7 +367,7 @@ impl Add<Uint64> for Uint64 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
self.panicking_add(rhs)
self.strict_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint64, Uint64);
Expand All @@ -376,7 +376,7 @@ impl Sub<Uint64> for Uint64 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
self.panicking_sub(rhs)
self.strict_sub(rhs)
}
}
forward_ref_binop!(impl Sub, sub for Uint64, Uint64);
Expand Down Expand Up @@ -1105,18 +1105,34 @@ mod tests {
}

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

#[test]
#[should_panic(expected = "attempt to add with overflow")]
fn uint64_strict_add_panics_on_overflow() {
let a = Uint64::MAX;
let b = Uint64::ONE;
let _ = a.strict_add(b);
}

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

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

#[test]
Expand Down
4 changes: 2 additions & 2 deletions packages/std/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl Timestamp {
#[must_use = "this returns the result of the operation, without modifying the original"]
// no #[inline] here as this could be shared with all the callers
pub const fn plus_nanos(&self, addition: u64) -> Timestamp {
let nanos = self.0.panicking_add(Uint64::new(addition));
let nanos = self.0.strict_add(Uint64::new(addition));
Timestamp(nanos)
}

Expand Down Expand Up @@ -136,7 +136,7 @@ impl Timestamp {
#[must_use = "this returns the result of the operation, without modifying the original"]
// no #[inline] here as this could be shared with all the callers
pub const fn minus_nanos(&self, subtrahend: u64) -> Timestamp {
Timestamp(self.0.panicking_sub(Uint64::new(subtrahend)))
Timestamp(self.0.strict_sub(Uint64::new(subtrahend)))
}

/// Returns nanoseconds since epoch
Expand Down

0 comments on commit 41b1d16

Please sign in to comment.