Repository: intel/rohd (dart)

Issue:
An equality operator for `LogicValues` that supports "don't care"
## Motivation
There are cases where you want to compare two `LogicValues` values for some bits, but not all bits.  It would be nice to support an equality check that enables a comparison of two `LogicValues` where any `x` is treated as a "don't care if this bit is equal".  Some thought would need to be put into whether only one side of the comparison should consider `x` as don't care or both sides, or maybe that should be configurable.  This feature is similar to a `casez` but for values instead of hardware.

## Desired solution
Add a function for comparison with don't care to `LogicValues`.

## Alternatives considered  
Let users implement this functionality themselves as needed.

Pull request:
## Description & Motivation 

There are cases where you want to compare two LogicValues values for some bits, but not all bits. It would be nice to support an equality check that enables a comparison of two LogicValues where any x is treated as a "don't care if this bit is equal". Some thought would need to be put into whether only one side of the comparison should consider x as don't care or both sides, or maybe that should be configurable. This feature is similar to a casez but for values instead of hardware.

## Description of changes, and motivation for adding them.

fix #93 



## Testing

<!-- Please describe how you tested your changes. -->

## Backwards-compatibility

> Is this a breaking change that will not be backwards-compatible? If yes, how so?

<!-- Answer here. -->

## Documentation

> Does the change require any updates to documentation? If so, where? Are they included?

<!-- Answer here. -->

Patch:
diff --git a/lib/src/values/logic_value.dart b/lib/src/values/logic_value.dart
index 764723038..4de1f7530 100644
--- a/lib/src/values/logic_value.dart
+++ b/lib/src/values/logic_value.dart
@@ -928,6 +928,41 @@ abstract class LogicValue {
     ].swizzle();
   }
 
+  /// Checks if `this` is equal to [other], except ignoring bits of
+  /// which are not valid.
+  ///
+  /// Returns `true` if each bit of `this` which [isValid] is equal
+  /// to each bit of [other] which [isValid].
+  ///
+  /// For example:
+  /// ```dart
+  /// // Returns false
+  /// LogicValue.ofString('1010xz').equalsWithDontCare(
+  ///   LogicValue.ofString('10111x'));
+  ///
+  /// // Returns true
+  /// LogicValue.ofString('10x111').equalsWithDontCare(
+  ///   LogicValue.ofString('10111x'));
+  ///
+  /// // Returns false
+  /// LogicValue.ofString('10x1z1').equalsWithDontCare(
+  ///   LogicValue.ofString('10101x'));
+  /// ```
+  bool equalsWithDontCare(LogicValue other) {
+    if (width == other.width) {
+      for (var i = 0; i < width; i++) {
+        if (!this[i].isValid || !other[i].isValid) {
+          continue;
+        } else if (this[i] != other[i]) {
+          return false;
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   /// Returns new [LogicValue] replicated [multiplier] times. An exception will
   /// be thrown in case the multiplier is <1
   LogicValue replicate(int multiplier) {


Test patch:
diff --git a/test/logic_value_test.dart b/test/logic_value_test.dart
index f587bdb7f..4860aee4c 100644
--- a/test/logic_value_test.dart
+++ b/test/logic_value_test.dart
@@ -428,6 +428,32 @@ void main() {
     });
   });
   group('comparison operations', () {
+    test('equalsWithDontCare', () {
+      expect(
+          // == not equal
+          LogicValue.ofString('1010xz')
+              .equalsWithDontCare(LogicValue.ofString('10111x')),
+          equals(false));
+      expect(
+          // == equal
+          LogicValue.ofString('1010xz')
+              .equalsWithDontCare(LogicValue.ofString('101z1x')),
+          equals(true));
+      expect(
+          // == not equal
+          LogicValue.ofString('10x1z1')
+              .equalsWithDontCare(LogicValue.ofString('10101x')),
+          equals(false));
+      expect(
+          //
+          LogicValue.ofString('10x1z1')
+              .equalsWithDontCare(LogicValue.ofString('10101x')),
+          equals(false));
+      expect(
+          LogicValue.ofString('10x1z1')
+              .equalsWithDontCare(LogicValue.ofString('101x11')),
+          equals(true));
+    });
     test('equality', () {
       expect(
           // == equal
@@ -740,7 +766,6 @@ void main() {
           equals(LogicValue.ofBigInt(BigInt.from(3), 512)));
     });
   });
-
   group('FilledLogicValue', () {
     test('overrides', () {
       expect(