Skip to content

Commit 6b1cc86

Browse files
committed
Implement Zero, One, and Num for core::num::Saturating<T>
1 parent 022f250 commit 6b1cc86

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed

src/identities.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::num::Wrapping;
1+
use core::num::{Saturating, Wrapping};
22
use core::ops::{Add, Mul};
33

44
/// Defines an additive identity element for `Self`.
@@ -95,6 +95,30 @@ where
9595
const ZERO: Self = Wrapping(T::ZERO);
9696
}
9797

98+
impl<T: Zero> Zero for Saturating<T>
99+
where
100+
Saturating<T>: Add<Output = Saturating<T>>,
101+
{
102+
fn is_zero(&self) -> bool {
103+
self.0.is_zero()
104+
}
105+
106+
fn set_zero(&mut self) {
107+
self.0.set_zero();
108+
}
109+
110+
fn zero() -> Self {
111+
Saturating(T::zero())
112+
}
113+
}
114+
115+
impl<T: ConstZero> ConstZero for Saturating<T>
116+
where
117+
Saturating<T>: Add<Output = Saturating<T>>,
118+
{
119+
const ZERO: Self = Saturating(T::ZERO);
120+
}
121+
98122
/// Defines a multiplicative identity element for `Self`.
99123
///
100124
/// # Laws
@@ -196,6 +220,26 @@ where
196220
const ONE: Self = Wrapping(T::ONE);
197221
}
198222

223+
impl<T: One> One for Saturating<T>
224+
where
225+
Saturating<T>: Mul<Output = Saturating<T>>,
226+
{
227+
fn set_one(&mut self) {
228+
self.0.set_one();
229+
}
230+
231+
fn one() -> Self {
232+
Saturating(T::one())
233+
}
234+
}
235+
236+
impl<T: ConstOne> ConstOne for Saturating<T>
237+
where
238+
Saturating<T>: Mul<Output = Saturating<T>>,
239+
{
240+
const ONE: Self = Saturating(T::ONE);
241+
}
242+
199243
// Some helper functions provided for backwards compatibility.
200244

201245
/// Returns the additive identity, `0`.
@@ -236,3 +280,30 @@ fn wrapping_is_one() {
236280
fn require_one<T: One>(_: &T) {}
237281
require_one(&Wrapping(42));
238282
}
283+
284+
#[test]
285+
fn saturating_identities() {
286+
macro_rules! test_saturating_identities {
287+
($($t:ty)+) => {
288+
$(
289+
assert_eq!(zero::<$t>(), zero::<Saturating<$t>>().0);
290+
assert_eq!(one::<$t>(), one::<Saturating<$t>>().0);
291+
assert_eq!((0 as $t).is_zero(), Saturating(0 as $t).is_zero());
292+
assert_eq!((1 as $t).is_zero(), Saturating(1 as $t).is_zero());
293+
)+
294+
};
295+
}
296+
297+
test_saturating_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
298+
}
299+
300+
#[test]
301+
fn saturating_is_zero() {
302+
fn require_zero<T: Zero>(_: &T) {}
303+
require_zero(&Saturating(42));
304+
}
305+
#[test]
306+
fn saturating_is_one() {
307+
fn require_one<T: One>(_: &T) {}
308+
require_one(&Saturating(42));
309+
}

src/lib.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ where
184184
}
185185
}
186186

187+
impl<T: Num> Num for core::num::Saturating<T>
188+
where
189+
core::num::Saturating<T>: NumOps,
190+
{
191+
type FromStrRadixErr = T::FromStrRadixErr;
192+
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
193+
T::from_str_radix(str, radix).map(core::num::Saturating)
194+
}
195+
}
196+
187197
#[derive(Debug)]
188198
pub enum FloatErrorKind {
189199
Empty,
@@ -570,6 +580,29 @@ fn wrapping_from_str_radix() {
570580
test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
571581
}
572582

583+
#[test]
584+
fn saturating_is_num() {
585+
fn require_num<T: Num>(_: &T) {}
586+
require_num(&core::num::Saturating(42_u32));
587+
require_num(&core::num::Saturating(-42));
588+
}
589+
590+
#[test]
591+
fn saturating_from_str_radix() {
592+
macro_rules! test_saturating_from_str_radix {
593+
($($t:ty)+) => {
594+
$(
595+
for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
596+
let w = core::num::Saturating::<$t>::from_str_radix(s, r).map(|w| w.0);
597+
assert_eq!(w, <$t as Num>::from_str_radix(s, r));
598+
}
599+
)+
600+
};
601+
}
602+
603+
test_saturating_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
604+
}
605+
573606
#[test]
574607
fn check_num_ops() {
575608
fn compute<T: Num + Copy>(x: T, y: T) -> T {

0 commit comments

Comments
 (0)