Skip to content

Commit

Permalink
feat(corelib): Iterator::Sum (#7142)
Browse files Browse the repository at this point in the history
  • Loading branch information
MagisterDaIlis authored Jan 27, 2025
1 parent 1fba177 commit f02c8b8
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 3 deletions.
2 changes: 1 addition & 1 deletion corelib/src/iter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,4 @@
mod adapters;
mod traits;
pub use adapters::PeekableTrait;
pub use traits::{FromIterator, IntoIterator, Iterator, Product};
pub use traits::{FromIterator, IntoIterator, Iterator, Product, Sum};
2 changes: 1 addition & 1 deletion corelib/src/iter/traits.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod accum;
mod collect;
mod iterator;
pub use accum::Product;
pub use accum::{Product, Sum};
pub use collect::{FromIterator, IntoIterator};
pub use iterator::Iterator;
19 changes: 19 additions & 0 deletions corelib/src/iter/traits/accum.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
/// Trait to represent types that can be created by summing up an iterator.
///
/// This trait is used to implement [`Iterator::sum()`]. Types which implement
/// this trait can be generated by using the [`sum()`] method on an iterator.
/// Like [`FromIterator`], this trait should rarely be called directly.
///
/// [`sum()`]: crate::iter::Iterator::sum
/// [`FromIterator`]: crate::iter::FromIterator
pub trait Sum<A> {
/// Takes an iterator and generates `Self` from the elements by "summing up"
/// the items.
fn sum<I, +Iterator<I>[Item: A], +Destruct<I>, +Destruct<A>>(iter: I) -> A;
}

impl SumAddableTypesImpl<A, +Add<A>, impl ZeroA: core::num::traits::Zero<A>> of Sum<A> {
fn sum<I, +Iterator<I>[Item: A], +Destruct<I>, +Destruct<A>>(mut iter: I) -> A {
iter.fold(ZeroA::zero(), |acc, x| acc + x)
}
}
/// Trait to represent types that can be created by multiplying elements of an
/// iterator.
///
Expand Down
30 changes: 29 additions & 1 deletion corelib/src/iter/traits/iterator.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::iter::adapters::{
Enumerate, Map, Peekable, Zip, enumerated_iterator, mapped_iterator, peekable_iterator,
zipped_iterator,
};
use crate::iter::traits::Product;
use crate::iter::traits::{Product, Sum};

/// A trait for dealing with iterators.
///
Expand Down Expand Up @@ -473,6 +473,34 @@ pub trait Iterator<T> {
peekable_iterator(self)
}

/// Sums the elements of an iterator.
///
/// Takes each element, adds them together, and returns the result.
///
/// An empty iterator returns the zero value of the type.
///
/// `sum()` can be used to sum any type implementing [`Sum`][`core::iter::Sum`],
/// including [`Option`][`Option::sum`] and [`Result`][`Result::sum`].
///
/// # Panics
///
/// When calling `sum()` and a primitive integer type is being returned, this
/// method will panic if the computation overflows.
///
/// # Examples
///
/// ```
/// let mut iter = array![1, 2, 3].into_iter();
/// let sum: usize = iter.sum();
///
/// assert_eq!(sum, 6);
/// ```
fn sum<+Destruct<T>, +Destruct<Self::Item>, +Sum<Self::Item>>(
self: T,
) -> Self::Item {
Sum::<Self::Item>::sum::<T, Self>(self)
}

/// Iterates over the entire iterator, multiplying all the elements
///
/// An empty iterator returns the one value of the type.
Expand Down
6 changes: 6 additions & 0 deletions corelib/src/test/iter_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ fn test_iter_adapter_peekable() {
assert_eq!(iter.next(), Option::None);
}

#[test]
fn test_iter_accum_sum() {
assert_eq!(array![1, 2, 3].into_iter().sum(), 6);
assert_eq!(array![].into_iter().sum(), 0);
}

#[test]
fn test_iter_accum_product() {
assert_eq!((1_usize..=0).into_iter().product(), 1);
Expand Down

0 comments on commit f02c8b8

Please sign in to comment.