diff --git a/src/Arch.Tests/BitSetTest.cs b/src/Arch.Tests/BitSetTest.cs
index 6e500933..01f99008 100644
--- a/src/Arch.Tests/BitSetTest.cs
+++ b/src/Arch.Tests/BitSetTest.cs
@@ -152,16 +152,58 @@ public void BitsetNone(int[] values, int multiplier)
That(allResult, Is.EqualTo(false));
}
+ ///
+ /// Checks exclusive.
+ /// The values being set or cleared.
+ /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.
+ ///
+ [Test]
+ [TestCase(new []{5,6,25}, 1)]
+ [TestCase(new []{5,6,25}, 100)]
+ public void BitsetExclusive(int[] values, int multiplier)
+ {
+ var bitSet1 = new BitSet();
+ bitSet1.SetBit(values[0] * multiplier);
+ bitSet1.SetBit(values[1] * multiplier);
+ var bitSet2 = new BitSet();
+ bitSet2.SetBit(values[0] * multiplier);
+ bitSet2.SetBit(values[1] * multiplier);
+
+ // Both are totally equal
+ var exclusive = bitSet2.Exclusive(bitSet1);
+ That(exclusive, Is.EqualTo(true));
+
+ // Bitset2 is not equal anymore
+ bitSet2.SetBit(values[2] * multiplier);
+ exclusive = bitSet2.Exclusive(bitSet1);
+ That(exclusive, Is.EqualTo(false));
+
+ // Bitset2 is back to default, but bitset1 is now different -> both differ, should be false
+ bitSet2.ClearBit(values[2] * multiplier);
+ bitSet1.SetBit(values[2] * multiplier);
+ exclusive = bitSet2.Exclusive(bitSet1);
+ That(exclusive, Is.EqualTo(false));
+
+ // Bitset2 is now the same as bitset 1 -> should be true
+ bitSet2.SetBit(values[2] * multiplier);
+ exclusive = bitSet2.Exclusive(bitSet1);
+ That(exclusive, Is.EqualTo(true));
+ }
+
///
/// Checks whether different sized 's work correctly.
+ /// The values being set or cleared.
+ /// The multiplier for the passed values. Mainly for vectorization-testing to increase the set bits.
///
[Test]
- public void AllWithDifferentLengthBitSet()
+ [TestCase(new []{5,33}, 1)]
+ [TestCase(new []{5,33}, 100)]
+ public void AllWithDifferentLengthBitSet(int[] values, int multiplier)
{
var bitSet1 = new BitSet();
- bitSet1.SetBit(5);
+ bitSet1.SetBit(values[0] * multiplier);
var bitSet2 = new BitSet();
- bitSet2.SetBit(33);
+ bitSet2.SetBit(values[1] * multiplier);
var allResult = bitSet2.All(bitSet1);
var anyResult = bitSet2.Any(bitSet1);
diff --git a/src/Arch/Core/Utils/BitSet.cs b/src/Arch/Core/Utils/BitSet.cs
index 2b012ac3..0d623bdd 100644
--- a/src/Arch/Core/Utils/BitSet.cs
+++ b/src/Arch/Core/Utils/BitSet.cs
@@ -324,26 +324,56 @@ public bool None(BitSet other)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Exclusive(BitSet other)
{
- var bits = _bits.AsSpan();
- var otherBits = other._bits.AsSpan();
- var count = Math.Min(_bits.Length, otherBits.Length);
+ var max = (_highestBit/sizeof(uint)/Padding)+1;
+ var min = Math.Min(Math.Min(Length, other.Length), max);
- for (var i = 0; i < count; i++)
+ if (!Vector.IsHardwareAccelerated || min < Padding)
{
- var bit = bits[i];
- if ((bit ^ otherBits[i]) != 0)
+ var bits = _bits.AsSpan();
+ var otherBits = other._bits.AsSpan();
+
+ // Bitwise xor, if both are not totally equal, return false
+ for (var i = 0; i < min; i++)
{
- return false;
+ var bit = bits[i];
+ if ((bit ^ otherBits[i]) != 0)
+ {
+ return false;
+ }
}
- }
- // handle extra bits on our side that might just be all zero
- var bitCount = _bits.Length;
- for (var i = count; i < bitCount; i++)
+ // handle extra bits on our side that might just be all zero
+ for (var i = min; i < max; i++)
+ {
+ if (bits[i] != 0)
+ {
+ return false;
+ }
+ }
+ }
+ else
{
- if (bits[i] != 0)
+ // Vectorized bitwise xor, return true since any is met
+ for (var i = 0; i < min; i += Padding)
+ {
+ var vector = new Vector(_bits, i);
+ var otherVector = new Vector(other._bits, i);
+
+ var resultVector = Vector.Xor(vector, otherVector);
+ if (!Vector.EqualsAll(resultVector, Vector.Zero))
+ {
+ return false;
+ }
+ }
+
+ // Handle extra bits on our side that might just be all zero.
+ for (var i = min; i < max; i += Padding)
{
- return false;
+ var vector = new Vector(_bits, i);
+ if (!Vector.EqualsAll(vector, Vector.Zero)) // Vectors are not zero bits[0] != 0 basically
+ {
+ return false;
+ }
}
}