From 299703664a1236eb737f85643c5a5a2fb0fabfd4 Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 17 Apr 2024 14:01:50 +0100 Subject: [PATCH 1/2] feat: implement `Eq` trait on `BoundedVec` --- noir_stdlib/src/collections/bounded_vec.nr | 63 ++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/noir_stdlib/src/collections/bounded_vec.nr b/noir_stdlib/src/collections/bounded_vec.nr index 6d5fbd44247..f93d56218b8 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,64 @@ impl BoundedVec { ret } } + +impl Eq for BoundedVec where T: Eq { + fn eq(self, other: BoundedVec) -> bool { + let equal_lens = self.len == other.len; + + let mut ret = true; + 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]); + } + } + equal_lens & 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); + } +} From 5c38e70addc6858a3e9351a642e30be0bd10790b Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 17 Apr 2024 16:43:08 +0100 Subject: [PATCH 2/2] Update noir_stdlib/src/collections/bounded_vec.nr Co-authored-by: jfecher --- noir_stdlib/src/collections/bounded_vec.nr | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/noir_stdlib/src/collections/bounded_vec.nr b/noir_stdlib/src/collections/bounded_vec.nr index f93d56218b8..cc55ca80434 100644 --- a/noir_stdlib/src/collections/bounded_vec.nr +++ b/noir_stdlib/src/collections/bounded_vec.nr @@ -98,17 +98,15 @@ impl BoundedVec { impl Eq for BoundedVec where T: Eq { fn eq(self, other: BoundedVec) -> bool { - let equal_lens = self.len == other.len; - - let mut ret = true; + 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 &= self.storage[i] == other.storage[i]; } } - equal_lens & ret + ret } }