1 use std::ops::{Add, Sub, Mul, Div}; 2 3 /// Performs addition that returns `None` instead of wrapping around on 4 /// overflow. 5 pub trait CheckedAdd: Sized + Add<Self, Output=Self> { 6 /// Adds two numbers, checking for overflow. If overflow happens, `None` is 7 /// returned. checked_add(&self, v: &Self) -> Option<Self>8 fn checked_add(&self, v: &Self) -> Option<Self>; 9 } 10 11 macro_rules! checked_impl { 12 ($trait_name:ident, $method:ident, $t:ty) => { 13 impl $trait_name for $t { 14 #[inline] 15 fn $method(&self, v: &$t) -> Option<$t> { 16 <$t>::$method(*self, *v) 17 } 18 } 19 } 20 } 21 22 checked_impl!(CheckedAdd, checked_add, u8); 23 checked_impl!(CheckedAdd, checked_add, u16); 24 checked_impl!(CheckedAdd, checked_add, u32); 25 checked_impl!(CheckedAdd, checked_add, u64); 26 checked_impl!(CheckedAdd, checked_add, usize); 27 28 checked_impl!(CheckedAdd, checked_add, i8); 29 checked_impl!(CheckedAdd, checked_add, i16); 30 checked_impl!(CheckedAdd, checked_add, i32); 31 checked_impl!(CheckedAdd, checked_add, i64); 32 checked_impl!(CheckedAdd, checked_add, isize); 33 34 /// Performs subtraction that returns `None` instead of wrapping around on underflow. 35 pub trait CheckedSub: Sized + Sub<Self, Output=Self> { 36 /// Subtracts two numbers, checking for underflow. If underflow happens, 37 /// `None` is returned. checked_sub(&self, v: &Self) -> Option<Self>38 fn checked_sub(&self, v: &Self) -> Option<Self>; 39 } 40 41 checked_impl!(CheckedSub, checked_sub, u8); 42 checked_impl!(CheckedSub, checked_sub, u16); 43 checked_impl!(CheckedSub, checked_sub, u32); 44 checked_impl!(CheckedSub, checked_sub, u64); 45 checked_impl!(CheckedSub, checked_sub, usize); 46 47 checked_impl!(CheckedSub, checked_sub, i8); 48 checked_impl!(CheckedSub, checked_sub, i16); 49 checked_impl!(CheckedSub, checked_sub, i32); 50 checked_impl!(CheckedSub, checked_sub, i64); 51 checked_impl!(CheckedSub, checked_sub, isize); 52 53 /// Performs multiplication that returns `None` instead of wrapping around on underflow or 54 /// overflow. 55 pub trait CheckedMul: Sized + Mul<Self, Output=Self> { 56 /// Multiplies two numbers, checking for underflow or overflow. If underflow 57 /// or overflow happens, `None` is returned. checked_mul(&self, v: &Self) -> Option<Self>58 fn checked_mul(&self, v: &Self) -> Option<Self>; 59 } 60 61 checked_impl!(CheckedMul, checked_mul, u8); 62 checked_impl!(CheckedMul, checked_mul, u16); 63 checked_impl!(CheckedMul, checked_mul, u32); 64 checked_impl!(CheckedMul, checked_mul, u64); 65 checked_impl!(CheckedMul, checked_mul, usize); 66 67 checked_impl!(CheckedMul, checked_mul, i8); 68 checked_impl!(CheckedMul, checked_mul, i16); 69 checked_impl!(CheckedMul, checked_mul, i32); 70 checked_impl!(CheckedMul, checked_mul, i64); 71 checked_impl!(CheckedMul, checked_mul, isize); 72 73 /// Performs division that returns `None` instead of panicking on division by zero and instead of 74 /// wrapping around on underflow and overflow. 75 pub trait CheckedDiv: Sized + Div<Self, Output=Self> { 76 /// Divides two numbers, checking for underflow, overflow and division by 77 /// zero. If any of that happens, `None` is returned. checked_div(&self, v: &Self) -> Option<Self>78 fn checked_div(&self, v: &Self) -> Option<Self>; 79 } 80 81 checked_impl!(CheckedDiv, checked_div, u8); 82 checked_impl!(CheckedDiv, checked_div, u16); 83 checked_impl!(CheckedDiv, checked_div, u32); 84 checked_impl!(CheckedDiv, checked_div, u64); 85 checked_impl!(CheckedDiv, checked_div, usize); 86 87 checked_impl!(CheckedDiv, checked_div, i8); 88 checked_impl!(CheckedDiv, checked_div, i16); 89 checked_impl!(CheckedDiv, checked_div, i32); 90 checked_impl!(CheckedDiv, checked_div, i64); 91 checked_impl!(CheckedDiv, checked_div, isize); 92 93