Skip to content

Commit 90f4ca8

Browse files
authored
Merge pull request #65 from bennofs/master
Add Sum/Product impls for NotNan
2 parents 06afbc9 + eae4033 commit 90f4ca8

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use core::hash::{Hash, Hasher};
1414
use core::fmt;
1515
use core::mem;
1616
use core::hint::unreachable_unchecked;
17+
use core::iter::{Sum, Product};
1718
use core::str::FromStr;
1819

1920
use num_traits::{Bounded, FromPrimitive, Num, NumCast, One, Signed, ToPrimitive, Zero};
@@ -322,6 +323,19 @@ impl<T: Float + AddAssign> AddAssign<T> for NotNan<T> {
322323
}
323324
}
324325

326+
327+
impl<T: Float + Sum> Sum for NotNan<T> {
328+
fn sum<I: Iterator<Item = NotNan<T>>>(iter: I) -> Self {
329+
NotNan::new(iter.map(|v| v.0).sum()).expect("Sum resulted in NaN")
330+
}
331+
}
332+
333+
impl<'a, T: Float + Sum> Sum<&'a NotNan<T>> for NotNan<T> {
334+
fn sum<I: Iterator<Item = &'a NotNan<T>>>(iter: I) -> Self {
335+
iter.map(|v| *v).sum()
336+
}
337+
}
338+
325339
impl<T: Float> Sub for NotNan<T> {
326340
type Output = Self;
327341

@@ -392,6 +406,18 @@ impl<T: Float + MulAssign> MulAssign<T> for NotNan<T> {
392406
}
393407
}
394408

409+
impl<T: Float + Product> Product for NotNan<T> {
410+
fn product<I: Iterator<Item = NotNan<T>>>(iter: I) -> Self {
411+
NotNan::new(iter.map(|v| v.0).product()).expect("Product resulted in NaN")
412+
}
413+
}
414+
415+
impl<'a, T: Float + Product> Product<&'a NotNan<T>> for NotNan<T> {
416+
fn product<I: Iterator<Item = &'a NotNan<T>>>(iter: I) -> Self {
417+
iter.map(|v| *v).product()
418+
}
419+
}
420+
395421
impl<T: Float> Div for NotNan<T> {
396422
type Output = Self;
397423

tests/test.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,37 @@ fn ordered_f32_neg() {
545545
fn ordered_f64_neg() {
546546
assert_eq!(OrderedFloat(-7.0f64), -OrderedFloat(7.0f64));
547547
}
548+
549+
#[test]
550+
#[should_panic]
551+
fn test_sum_fails_on_nan() {
552+
let a = NotNan::new(std::f32::INFINITY).unwrap();
553+
let b = NotNan::new(std::f32::NEG_INFINITY).unwrap();
554+
let _c: NotNan<_> = [a,b].iter().sum();
555+
}
556+
557+
#[test]
558+
#[should_panic]
559+
fn test_product_fails_on_nan() {
560+
let a = NotNan::new(std::f32::INFINITY).unwrap();
561+
let b = NotNan::new(0f32).unwrap();
562+
let _c: NotNan<_> = [a,b].iter().product();
563+
}
564+
565+
#[test]
566+
fn not_nan64_sum_product() {
567+
let a = NotNan::new(2138.1237).unwrap();
568+
let b = NotNan::new(132f64).unwrap();
569+
let c = NotNan::new(5.1).unwrap();
570+
571+
assert_eq!(std::iter::empty::<NotNan<f64>>().sum::<NotNan<_>>(), NotNan::new(0f64).unwrap());
572+
assert_eq!([a].iter().sum::<NotNan<_>>(), a);
573+
assert_eq!([a,b].iter().sum::<NotNan<_>>(), a + b);
574+
assert_eq!([a,b,c].iter().sum::<NotNan<_>>(), a + b + c);
575+
576+
assert_eq!(std::iter::empty::<NotNan<f64>>().product::<NotNan<_>>(), NotNan::new(1f64).unwrap());
577+
assert_eq!([a].iter().product::<NotNan<_>>(), a);
578+
assert_eq!([a,b].iter().product::<NotNan<_>>(), a * b);
579+
assert_eq!([a,b,c].iter().product::<NotNan<_>>(), a * b * c);
580+
581+
}

0 commit comments

Comments
 (0)