Skip to content

Commit

Permalink
Use newly added panicking_add/panicking_sub for Timestamp math (backp…
Browse files Browse the repository at this point in the history
…ort #2098) (#2105)

* Add panicking_sub to Uint64/Uint128/Uint256/Uint512

(cherry picked from commit 547efed)

# Conflicts:
#	CHANGELOG.md

* Improve docs of Timestamp::minus_* and use panicking_sub

(cherry picked from commit 242cc1f)

# Conflicts:
#	CHANGELOG.md

* Add Uint{64,128,256,512}::panicking_add

(cherry picked from commit a74aba0)

# Conflicts:
#	CHANGELOG.md

* Add #[inline] annotations to plus_seconds/minus_seconds

(cherry picked from commit bbb788d)

* Make overflow behaviour explicit for Timestamp

(cherry picked from commit b265b33)

# Conflicts:
#	CHANGELOG.md

* Add PR link to new CHANGELOG entries

(cherry picked from commit 198001e)

# Conflicts:
#	CHANGELOG.md

* Fix CHANGELOG

* Use zero() and one() from functions in tests

ZERO / ONE are not yet available in 1.4

---------

Co-authored-by: Simon Warta <simon@warta.it>
  • Loading branch information
mergify[bot] and webmaster128 authored Apr 10, 2024
1 parent 1f8964f commit e29dbf7
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 39 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ 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])

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

### Changed

Expand Down
49 changes: 39 additions & 10 deletions packages/std/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,28 @@ impl Uint128 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint128::add`] but const.
///
/// Panics on overflow.
#[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()) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// 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 @@ -363,11 +385,7 @@ impl Add<Uint128> for Uint128 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.u128()
.checked_add(rhs.u128())
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint128, Uint128);
Expand All @@ -376,11 +394,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 @@ -1148,6 +1162,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
49 changes: 39 additions & 10 deletions packages/std/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,28 @@ impl Uint256 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint256::add`] but const.
///
/// Panics on overflow.
#[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) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// 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 @@ -428,11 +450,7 @@ impl Add<Uint256> for Uint256 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.0
.checked_add(rhs.0)
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint256, Uint256);
Expand All @@ -441,11 +459,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 @@ -1690,6 +1704,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
45 changes: 39 additions & 6 deletions packages/std/src/math/uint512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,28 @@ impl Uint512 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint512::add`] but const.
///
/// Panics on overflow.
#[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) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// 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 @@ -415,11 +437,7 @@ impl Add<Uint512> for Uint512 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.0
.checked_add(rhs.0)
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint512, Uint512);
Expand All @@ -428,7 +446,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 @@ -1338,6 +1356,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
49 changes: 39 additions & 10 deletions packages/std/src/math/uint64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,28 @@ impl Uint64 {
Self(self.0.saturating_pow(exp))
}

/// This is the same as [`Uint64::add`] but const.
///
/// Panics on overflow.
#[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()) {
None => panic!("attempt to add with overflow"),
Some(sum) => Self(sum),
}
}

/// 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 @@ -326,11 +348,7 @@ impl Add<Uint64> for Uint64 {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self(
self.u64()
.checked_add(rhs.u64())
.expect("attempt to add with overflow"),
)
self.panicking_add(rhs)
}
}
forward_ref_binop!(impl Add, add for Uint64, Uint64);
Expand All @@ -339,11 +357,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 @@ -1062,6 +1076,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
Loading

0 comments on commit e29dbf7

Please sign in to comment.