From 9c3e9791d2b563a8f4ddc955b96e6ad35dfc96c7 Mon Sep 17 00:00:00 2001 From: Yoan Lecoq Date: Sat, 29 Apr 2017 08:22:44 +0200 Subject: [PATCH] impl Checked* and Saturating for Wrapping --- traits/src/ops/checked.rs | 28 ++++++++++++++++++++++++++++ traits/src/ops/saturating.rs | 7 +++++++ 2 files changed, 35 insertions(+) diff --git a/traits/src/ops/checked.rs b/traits/src/ops/checked.rs index b6bf0d6..4437acb 100644 --- a/traits/src/ops/checked.rs +++ b/traits/src/ops/checked.rs @@ -1,4 +1,5 @@ use std::ops::{Add, Sub, Mul, Div}; +use std::num::Wrapping; /// Performs addition that returns `None` instead of wrapping around on /// overflow. @@ -89,3 +90,30 @@ checked_impl!(CheckedDiv, checked_div, i16); checked_impl!(CheckedDiv, checked_div, i32); checked_impl!(CheckedDiv, checked_div, i64); checked_impl!(CheckedDiv, checked_div, isize); + +// Was skeptical at first, since checked ops somewhat defeat the point of +// Wrapping, but there are more pros than cons IMO : +// - These are methods, so users still have to be explicit about their intent; +// - Wrapping could be used for to enforce wrapping semantics _most of the time_, +// and only have a handful of places where they want to perform checked ops; +// - This allows Wrapping to implement PrimInt. +impl CheckedAdd for Wrapping where Wrapping: Add>{ + fn checked_add(&self, v: &Self) -> Option { + self.0.checked_add(&v.0).map(Wrapping) + } +} +impl CheckedSub for Wrapping where Wrapping: Sub> { + fn checked_sub(&self, v: &Self) -> Option { + self.0.checked_sub(&v.0).map(Wrapping) + } +} +impl CheckedMul for Wrapping where Wrapping: Mul>{ + fn checked_mul(&self, v: &Self) -> Option { + self.0.checked_mul(&v.0).map(Wrapping) + } +} +impl CheckedDiv for Wrapping where Wrapping: Div> { + fn checked_div(&self, v: &Self) -> Option { + self.0.checked_div(&v.0).map(Wrapping) + } +} diff --git a/traits/src/ops/saturating.rs b/traits/src/ops/saturating.rs index e9db749..ebbbe51 100644 --- a/traits/src/ops/saturating.rs +++ b/traits/src/ops/saturating.rs @@ -1,3 +1,5 @@ +use std::num::Wrapping; + /// Saturating math operations pub trait Saturating { /// Saturating addition operator. @@ -26,3 +28,8 @@ macro_rules! saturating_impl { } saturating_impl!(Saturating for isize usize i8 u8 i16 u16 i32 u32 i64 u64); + +impl Saturating for Wrapping { + fn saturating_add(self, v: Self) -> Self { Wrapping(self.0.saturating_add(v.0)) } + fn saturating_sub(self, v: Self) -> Self { Wrapping(self.0.saturating_sub(v.0)) } +}