92 lines
3.4 KiB
Rust
92 lines
3.4 KiB
Rust
use std::ops::{Add, Sub, Mul, Div};
|
|
|
|
/// Performs addition that returns `None` instead of wrapping around on
|
|
/// overflow.
|
|
pub trait CheckedAdd: Sized + Add<Self, Output=Self> {
|
|
/// Adds two numbers, checking for overflow. If overflow happens, `None` is
|
|
/// returned.
|
|
fn checked_add(&self, v: &Self) -> Option<Self>;
|
|
}
|
|
|
|
macro_rules! checked_impl {
|
|
($trait_name:ident, $method:ident, $t:ty) => {
|
|
impl $trait_name for $t {
|
|
#[inline]
|
|
fn $method(&self, v: &$t) -> Option<$t> {
|
|
<$t>::$method(*self, *v)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
checked_impl!(CheckedAdd, checked_add, u8);
|
|
checked_impl!(CheckedAdd, checked_add, u16);
|
|
checked_impl!(CheckedAdd, checked_add, u32);
|
|
checked_impl!(CheckedAdd, checked_add, u64);
|
|
checked_impl!(CheckedAdd, checked_add, usize);
|
|
|
|
checked_impl!(CheckedAdd, checked_add, i8);
|
|
checked_impl!(CheckedAdd, checked_add, i16);
|
|
checked_impl!(CheckedAdd, checked_add, i32);
|
|
checked_impl!(CheckedAdd, checked_add, i64);
|
|
checked_impl!(CheckedAdd, checked_add, isize);
|
|
|
|
/// Performs subtraction that returns `None` instead of wrapping around on underflow.
|
|
pub trait CheckedSub: Sized + Sub<Self, Output=Self> {
|
|
/// Subtracts two numbers, checking for underflow. If underflow happens,
|
|
/// `None` is returned.
|
|
fn checked_sub(&self, v: &Self) -> Option<Self>;
|
|
}
|
|
|
|
checked_impl!(CheckedSub, checked_sub, u8);
|
|
checked_impl!(CheckedSub, checked_sub, u16);
|
|
checked_impl!(CheckedSub, checked_sub, u32);
|
|
checked_impl!(CheckedSub, checked_sub, u64);
|
|
checked_impl!(CheckedSub, checked_sub, usize);
|
|
|
|
checked_impl!(CheckedSub, checked_sub, i8);
|
|
checked_impl!(CheckedSub, checked_sub, i16);
|
|
checked_impl!(CheckedSub, checked_sub, i32);
|
|
checked_impl!(CheckedSub, checked_sub, i64);
|
|
checked_impl!(CheckedSub, checked_sub, isize);
|
|
|
|
/// Performs multiplication that returns `None` instead of wrapping around on underflow or
|
|
/// overflow.
|
|
pub trait CheckedMul: Sized + Mul<Self, Output=Self> {
|
|
/// Multiplies two numbers, checking for underflow or overflow. If underflow
|
|
/// or overflow happens, `None` is returned.
|
|
fn checked_mul(&self, v: &Self) -> Option<Self>;
|
|
}
|
|
|
|
checked_impl!(CheckedMul, checked_mul, u8);
|
|
checked_impl!(CheckedMul, checked_mul, u16);
|
|
checked_impl!(CheckedMul, checked_mul, u32);
|
|
checked_impl!(CheckedMul, checked_mul, u64);
|
|
checked_impl!(CheckedMul, checked_mul, usize);
|
|
|
|
checked_impl!(CheckedMul, checked_mul, i8);
|
|
checked_impl!(CheckedMul, checked_mul, i16);
|
|
checked_impl!(CheckedMul, checked_mul, i32);
|
|
checked_impl!(CheckedMul, checked_mul, i64);
|
|
checked_impl!(CheckedMul, checked_mul, isize);
|
|
|
|
/// Performs division that returns `None` instead of panicking on division by zero and instead of
|
|
/// wrapping around on underflow and overflow.
|
|
pub trait CheckedDiv: Sized + Div<Self, Output=Self> {
|
|
/// Divides two numbers, checking for underflow, overflow and division by
|
|
/// zero. If any of that happens, `None` is returned.
|
|
fn checked_div(&self, v: &Self) -> Option<Self>;
|
|
}
|
|
|
|
checked_impl!(CheckedDiv, checked_div, u8);
|
|
checked_impl!(CheckedDiv, checked_div, u16);
|
|
checked_impl!(CheckedDiv, checked_div, u32);
|
|
checked_impl!(CheckedDiv, checked_div, u64);
|
|
checked_impl!(CheckedDiv, checked_div, usize);
|
|
|
|
checked_impl!(CheckedDiv, checked_div, i8);
|
|
checked_impl!(CheckedDiv, checked_div, i16);
|
|
checked_impl!(CheckedDiv, checked_div, i32);
|
|
checked_impl!(CheckedDiv, checked_div, i64);
|
|
checked_impl!(CheckedDiv, checked_div, isize);
|