Skip to content

Commit

Permalink
Implement Iterator trait for Fragment and BoundedVec (#327)
Browse files Browse the repository at this point in the history
This PR creates Iterator trait with one function: `for_each` and
implements it for Fragment and BoundedVec.
It also migrates the code to use `for_each` where possible. I only found
2 places (1 for Fragment and 1 for BoundedVec) where it's possible to
use it. In the rest of the loops iterating over fragments or boundedvecs
`i` (loop iterator) is used in some way that makes it impossible to use
`for_each`.
  • Loading branch information
Pasifaee authored Jun 7, 2024
2 parents 4bac877 + 3e35876 commit d5b0cc4
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 13 deletions.
1 change: 1 addition & 0 deletions ethereum/circuits/lib/src/misc.nr
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mod types;
mod option;
mod bytes32;
mod bytes32_test;
mod iterator;
19 changes: 14 additions & 5 deletions ethereum/circuits/lib/src/misc/bounded_vecs.nr
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::misc::iterator::Iterator;

pub fn bounded_vec_from_array<T, N, M>(array: [T; N]) -> BoundedVec<T, M> {
assert(N <= M, "Array size exceeds bounded vector size");
let mut vec = BoundedVec::new();
Expand All @@ -10,11 +12,18 @@ pub fn bounded_vec_map<U, T, N, Env>(
bounded_vec: BoundedVec<T, N> ,
f: fn[Env](T) -> U
) -> BoundedVec<U, N> {
let mut result: BoundedVec<U, N> = BoundedVec::new();
for i in 0..N {
if (i < bounded_vec.len) {
result.push(f(bounded_vec.get(i)));
let result: &mut BoundedVec<U, N> = &mut BoundedVec::new();
bounded_vec.for_each(|x| result.push(f(x)));

*result
}

impl<T, N> Iterator<T> for BoundedVec<T, N> {
fn for_each<Env>(self, f: fn[Env](T) -> ()) {
for i in 0..N {
if i < self.len {
f(self.get(i));
}
}
}
result
}
23 changes: 15 additions & 8 deletions ethereum/circuits/lib/src/misc/fragment.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::misc::arrays::{memcpy_up_to_length, resize};
use crate::misc::{arrays::{memcpy_up_to_length, resize}, iterator::Iterator};
use dep::std::unsafe::zeroed;

struct Fragment<MAX_DATA_LEN, T> {
Expand Down Expand Up @@ -38,13 +38,10 @@ impl<MAX_DATA_LEN, T> Fragment<MAX_DATA_LEN, T> {

pub fn to_bounded_vec<N>(self) -> BoundedVec<T, N> {
assert(self.length <= N, "Fragment length exceeds BoundedVec max length");
let mut bounded_vec: BoundedVec<T, N> = BoundedVec::new();
for i in 0..N {
if (i < self.length) {
bounded_vec.push(self.at(i));
}
}
bounded_vec
let bounded_vec: &mut BoundedVec<T, N> = &mut BoundedVec::new();
self.for_each(|x| bounded_vec.push(x));

*bounded_vec
}

pub fn from_vec(vec: BoundedVec<T, MAX_DATA_LEN>) -> Fragment<MAX_DATA_LEN, T> {
Expand Down Expand Up @@ -150,3 +147,13 @@ impl<MAX_DATA_LEN, T> Eq for Fragment<MAX_DATA_LEN, T> where T: Eq {
res
}
}

impl<MAX_DATA_LEN, T> Iterator<T> for Fragment<MAX_DATA_LEN, T> {
fn for_each<Env>(self, f: fn[Env](T) -> ()) {
for i in 0..MAX_DATA_LEN {
if i < self.length {
f(self.at(i));
}
}
}
}
3 changes: 3 additions & 0 deletions ethereum/circuits/lib/src/misc/iterator.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trait Iterator<T> {
fn for_each<Env>(self, f: fn[Env](T) -> ());
}

0 comments on commit d5b0cc4

Please sign in to comment.