public void Collections_BitSetOperationsWithEmptyInputTest() { var bs_empty = new BitSet(); var bits = new bool[] { false, false, true, }; var bs = new BitSet(bits); void bs_verify_unchanged_func() { Assert.AreEqual(1, bs.Cardinality); Assert.AreEqual(2, bs.CardinalityZeros); Assert.AreEqual(bs[0], false); Assert.AreEqual(bs[1], false); Assert.AreEqual(bs[2], true); } bs.Or(bs_empty); bs_verify_unchanged_func(); bs.AndNot(bs_empty); bs_verify_unchanged_func(); bs.And(bs_empty); bs_verify_unchanged_func(); bs.Xor(bs_empty); bs_verify_unchanged_func(); }
public void Collections_BitSetOperationsTest() { var lhs_bits = new bool[] { false, false, true, }; var lhs_bs = new BitSet(lhs_bits); // rhs is our operation input, and it needs to be longer than lhs to also validate // ClearAlignmentOnlyBitsForBitOperation's logic is working as intended var rhs_bits = new bool[] { false, true, false, true, }; var rhs_bs = new BitSet(rhs_bits); lhs_bs.Or(rhs_bs); Assert.AreEqual(2, lhs_bs.Cardinality); Assert.AreEqual(1, lhs_bs.CardinalityZeros); Assert.AreEqual(lhs_bs[0], false); Assert.AreEqual(lhs_bs[1], true); Assert.AreEqual(lhs_bs[2], true); // also undoes the OR operation lhs_bs.AndNot(rhs_bs); Assert.AreEqual(1, lhs_bs.Cardinality); Assert.AreEqual(2, lhs_bs.CardinalityZeros); Assert.AreEqual(lhs_bs[0], false); Assert.AreEqual(lhs_bs[1], false); Assert.AreEqual(lhs_bs[2], true); lhs_bs.And(rhs_bs); Assert.AreEqual(0, lhs_bs.Cardinality); Assert.AreEqual(3, lhs_bs.CardinalityZeros); Assert.AreEqual(lhs_bs[0], false); Assert.AreEqual(lhs_bs[1], false); Assert.AreEqual(lhs_bs[2], false); // at this point lhs is zero, and the only bit in rhs which is on (relative to lhs's bit-space) is the 2nd lhs_bs.Xor(rhs_bs); Assert.AreEqual(1, lhs_bs.Cardinality); Assert.AreEqual(2, lhs_bs.CardinalityZeros); Assert.AreEqual(lhs_bs[0], false); Assert.AreEqual(lhs_bs[1], true); Assert.AreEqual(lhs_bs[2], false); lhs_bs.Not(); Assert.AreEqual(2, lhs_bs.Cardinality); Assert.AreEqual(1, lhs_bs.CardinalityZeros); Assert.AreEqual(lhs_bs[0], true); Assert.AreEqual(lhs_bs[1], false); Assert.AreEqual(lhs_bs[2], true); }
internal virtual void DoRandomSets(int maxSize, int iter, int mode) { BitSet a0 = null; OpenBitSet b0 = null; for (int i = 0; i < iter; i++) { int sz = Random.Next(maxSize); BitSet a = new BitSet(sz); OpenBitSet b = new OpenBitSet(sz); // test the various ways of setting bits if (sz > 0) { int nOper = Random.Next(sz); for (int j = 0; j < nOper; j++) { int idx; idx = Random.Next(sz); a.Set(idx, true); b.FastSet(idx); idx = Random.Next(sz); a.Set(idx, true); b.FastSet((long)idx); idx = Random.Next(sz); a.Set(idx, false); b.FastClear(idx); idx = Random.Next(sz); a.Set(idx, false); b.FastClear((long)idx); idx = Random.Next(sz); a.Set(idx, !a.Get(idx)); b.FastFlip(idx); bool val = b.FlipAndGet(idx); bool val2 = b.FlipAndGet(idx); Assert.IsTrue(val != val2); idx = Random.Next(sz); a.Set(idx, !a.Get(idx)); b.FastFlip((long)idx); val = b.FlipAndGet((long)idx); val2 = b.FlipAndGet((long)idx); Assert.IsTrue(val != val2); val = b.GetAndSet(idx); Assert.IsTrue(val2 == val); Assert.IsTrue(b.Get(idx)); if (!val) { b.FastClear(idx); } Assert.IsTrue(b.Get(idx) == val); } } // test that the various ways of accessing the bits are equivalent DoGet(a, b); DoGetFast(a, b, sz); // test ranges, including possible extension int fromIndex, toIndex; fromIndex = Random.Next(sz + 80); toIndex = fromIndex + Random.Next((sz >> 1) + 1); BitSet aa = (BitSet)a.Clone(); aa.Flip(fromIndex, toIndex); OpenBitSet bb = (OpenBitSet)b.Clone(); bb.Flip(fromIndex, toIndex); DoIterate(aa, bb, mode); // a problem here is from flip or doIterate fromIndex = Random.Next(sz + 80); toIndex = fromIndex + Random.Next((sz >> 1) + 1); aa = (BitSet)a.Clone(); aa.Clear(fromIndex, toIndex); bb = (OpenBitSet)b.Clone(); bb.Clear(fromIndex, toIndex); DoNextSetBit(aa, bb); // a problem here is from clear() or nextSetBit DoNextSetBitLong(aa, bb); DoPrevSetBit(aa, bb); DoPrevSetBitLong(aa, bb); fromIndex = Random.Next(sz + 80); toIndex = fromIndex + Random.Next((sz >> 1) + 1); aa = (BitSet)a.Clone(); aa.Set(fromIndex, toIndex); bb = (OpenBitSet)b.Clone(); bb.Set(fromIndex, toIndex); DoNextSetBit(aa, bb); // a problem here is from set() or nextSetBit DoNextSetBitLong(aa, bb); DoPrevSetBit(aa, bb); DoPrevSetBitLong(aa, bb); if (a0 != null) { Assert.AreEqual(a.Equals(a0), b.Equals(b0)); Assert.AreEqual(a.Cardinality, b.Cardinality); BitSet a_and = (BitSet)a.Clone(); a_and.And(a0); BitSet a_or = (BitSet)a.Clone(); a_or.Or(a0); BitSet a_xor = (BitSet)a.Clone(); a_xor.Xor(a0); BitSet a_andn = (BitSet)a.Clone(); a_andn.AndNot(a0); OpenBitSet b_and = (OpenBitSet)b.Clone(); Assert.AreEqual(b, b_and); b_and.And(b0); OpenBitSet b_or = (OpenBitSet)b.Clone(); b_or.Or(b0); OpenBitSet b_xor = (OpenBitSet)b.Clone(); b_xor.Xor(b0); OpenBitSet b_andn = (OpenBitSet)b.Clone(); b_andn.AndNot(b0); DoIterate(a_and, b_and, mode); DoIterate(a_or, b_or, mode); DoIterate(a_xor, b_xor, mode); DoIterate(a_andn, b_andn, mode); Assert.AreEqual(a_and.Cardinality, b_and.Cardinality); Assert.AreEqual(a_or.Cardinality, b_or.Cardinality); Assert.AreEqual(a_xor.Cardinality, b_xor.Cardinality); Assert.AreEqual(a_andn.Cardinality, b_andn.Cardinality); // test non-mutating popcounts Assert.AreEqual(b_and.Cardinality, OpenBitSet.IntersectionCount(b, b0)); Assert.AreEqual(b_or.Cardinality, OpenBitSet.UnionCount(b, b0)); Assert.AreEqual(b_xor.Cardinality, OpenBitSet.XorCount(b, b0)); Assert.AreEqual(b_andn.Cardinality, OpenBitSet.AndNotCount(b, b0)); } a0 = a; b0 = b; } }
/* * The difference between add(AbstractCharClass) and union(AbstractCharClass) * is that add() is used for constructions like "[^abc\\d]" * (this pattern doesn't match "1") * while union is used for constructions like "[^abc[\\d]]" * (this pattern matches "1"). */ public CharClass Add(AbstractCharClass cc_0) { if (!mayContainSupplCodepoints && cc_0.mayContainSupplCodepoints) { mayContainSupplCodepoints = true; } if (!invertedSurrogates) { //A | !B = ! ((A ^ B) & B) if (cc_0.altSurrogates) { lowHighSurrogates.Xor(cc_0.GetLowHighSurrogates()); lowHighSurrogates.And(cc_0.GetLowHighSurrogates()); altSurrogates = !altSurrogates; invertedSurrogates = true; //A | B } else { lowHighSurrogates.Or(cc_0.GetLowHighSurrogates()); } } else { //!A | !B = !(A & B) if (cc_0.altSurrogates) { lowHighSurrogates.And(cc_0.GetLowHighSurrogates()); //!A | B = !(A & !B) } else { lowHighSurrogates.AndNot(cc_0.GetLowHighSurrogates()); } } if (!hideBits && cc_0.GetBits() != null) { if (!inverted) { //A | !B = ! ((A ^ B) & B) if (cc_0.IsNegative()) { bits.Xor(cc_0.GetBits()); bits.And(cc_0.GetBits()); alt = !alt; inverted = true; //A | B } else { bits.Or(cc_0.GetBits()); } } else { //!A | !B = !(A & B) if (cc_0.IsNegative()) { bits.And(cc_0.GetBits()); //!A | B = !(A & !B) } else { bits.AndNot(cc_0.GetBits()); } } } else { bool curAlt_1 = alt; if (nonBitSet == null) { if (curAlt_1 && !inverted && bits.IsEmpty()) { nonBitSet = new CharClass.Anonymous_C17(cc_0); //alt = true; } else { /* * We keep the value of alt unchanged for * constructions like [^[abc]fgb] by using * the formula a ^ b == !a ^ !b. */ if (curAlt_1) { nonBitSet = new CharClass.Anonymous_C16(this, curAlt_1, cc_0); //alt = true } else { nonBitSet = new CharClass.Anonymous_C15(this, curAlt_1, cc_0); //alt = false } } hideBits = true; } else { AbstractCharClass nb_2 = nonBitSet; if (curAlt_1) { nonBitSet = new CharClass.Anonymous_C14(curAlt_1, cc_0, nb_2); //alt = true } else { nonBitSet = new CharClass.Anonymous_C13(curAlt_1, cc_0, nb_2); //alt = false } } } return(this); }