diff --git a/noir_stdlib/src/collections/bounded_vec.nr b/noir_stdlib/src/collections/bounded_vec.nr index 6d5fbd44247..cc55ca80434 100644 --- a/noir_stdlib/src/collections/bounded_vec.nr +++ b/noir_stdlib/src/collections/bounded_vec.nr @@ -1,3 +1,5 @@ +use crate::cmp::Eq; + struct BoundedVec { storage: [T; MaxLen], len: u64, @@ -93,3 +95,62 @@ impl BoundedVec { ret } } + +impl Eq for BoundedVec where T: Eq { + fn eq(self, other: BoundedVec) -> bool { + let mut ret = self.len == other.len; + let mut exceeded_len = false; + for i in 0..MaxLen { + exceeded_len |= i == self.len; + if !exceeded_len { + ret &= self.storage[i] == other.storage[i]; + } + } + ret + } +} + +mod bounded_vec_tests { + // TODO: Allow imports from "super" + use crate::collections::bounded_vec::BoundedVec; + + #[test] + fn empty_equality() { + let mut bounded_vec1: BoundedVec = BoundedVec::new(); + let mut bounded_vec2: BoundedVec = BoundedVec::new(); + + assert_eq(bounded_vec1, bounded_vec2); + } + + #[test] + fn inequality() { + let mut bounded_vec1: BoundedVec = BoundedVec::new(); + let mut bounded_vec2: BoundedVec = BoundedVec::new(); + bounded_vec1.push(1); + bounded_vec2.push(2); + + assert(bounded_vec1 != bounded_vec2); + } + + #[test] + fn equality_respects_specified_length() { + let mut bounded_vec1: BoundedVec = BoundedVec::new(); + bounded_vec1.push(1); + + // This BoundedVec has an extra value past the end of its specified length, + // this should be ignored when checking equality so they are considered equal. + let mut bounded_vec2: BoundedVec = BoundedVec { storage: [1, 2, 0], len: 1 }; + + assert_eq(bounded_vec1, bounded_vec2); + + // Pushing another entry onto `bounded_vec1` to make the underlying arrays equal should + // result in the `BoundedVec`s being unequal as their lengths are different. + bounded_vec1.push(2); + + assert(bounded_vec1 != bounded_vec2); + + bounded_vec2.push(2); + + assert_eq(bounded_vec1, bounded_vec2); + } +}