[SQUASHME] bitset: fix logical operations.
This commit is contained in:
@@ -344,26 +344,54 @@ fun testLogic() {
|
|||||||
65, 67,
|
65, 67,
|
||||||
70, 72)
|
70, 72)
|
||||||
|
|
||||||
|
// and
|
||||||
var b1 = BitSet(73)
|
var b1 = BitSet(73)
|
||||||
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
b1.and(b2)
|
b1.and(b2)
|
||||||
assertContainsOnly(b1, setOf(3, 63, 67, 72), 76)
|
assertContainsOnly(b1, setOf(3, 63, 67, 72), 76)
|
||||||
|
b1 = BitSet(73)
|
||||||
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
|
b1.set(128)
|
||||||
|
b1.and(b2)
|
||||||
|
assertContainsOnly(b1, setOf(3, 63, 67, 72), 129)
|
||||||
|
|
||||||
|
// or
|
||||||
b1 = BitSet(73)
|
b1 = BitSet(73)
|
||||||
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
b1.or(b2)
|
b1.or(b2)
|
||||||
assertContainsOnly(b1, setOf(1, 2, 3, 61, 62, 63, 65, 66, 67, 70, 71, 72), 76)
|
assertContainsOnly(b1, setOf(1, 2, 3, 61, 62, 63, 65, 66, 67, 70, 71, 72), 76)
|
||||||
|
|
||||||
|
b1 = BitSet(73)
|
||||||
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
|
b1.set(128)
|
||||||
|
b1.or(b2)
|
||||||
|
assertContainsOnly(b1, setOf(1, 2, 3, 61, 62, 63, 65, 66, 67, 70, 71, 72, 128), 129)
|
||||||
|
|
||||||
|
// xor
|
||||||
b1 = BitSet(73)
|
b1 = BitSet(73)
|
||||||
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
b1.xor(b2)
|
b1.xor(b2)
|
||||||
assertContainsOnly(b1, setOf(1, 2, 61, 62, 65, 66, 70, 71), 76)
|
assertContainsOnly(b1, setOf(1, 2, 61, 62, 65, 66, 70, 71), 76)
|
||||||
|
|
||||||
|
b1 = BitSet(73)
|
||||||
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
|
b1.set(128)
|
||||||
|
b1.xor(b2)
|
||||||
|
assertContainsOnly(b1, setOf(1, 2, 61, 62, 65, 66, 70, 71, 128), 129)
|
||||||
|
|
||||||
|
// andNot
|
||||||
b1 = BitSet(73)
|
b1 = BitSet(73)
|
||||||
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
b1.andNot(b2)
|
b1.andNot(b2)
|
||||||
assertContainsOnly(b1, setOf(2, 62, 66, 71), 76)
|
assertContainsOnly(b1, setOf(2, 62, 66, 71), 76)
|
||||||
|
|
||||||
|
b1 = BitSet(73)
|
||||||
|
b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72)
|
||||||
|
b1.set(128)
|
||||||
|
b1.andNot(b2)
|
||||||
|
assertContainsOnly(b1, setOf(2, 62, 66, 71, 128), 129)
|
||||||
|
|
||||||
|
// intersects
|
||||||
b1 = BitSet(73)
|
b1 = BitSet(73)
|
||||||
b1.set(0..1); b1.set(62..63); b1.set(64..65); b1.set(71..72)
|
b1.set(0..1); b1.set(62..63); b1.set(64..65); b1.set(71..72)
|
||||||
b2.clear(); b2.set(0)
|
b2.clear(); b2.set(0)
|
||||||
@@ -374,6 +402,8 @@ fun testLogic() {
|
|||||||
assertTrue(b1.intersects(b2))
|
assertTrue(b1.intersects(b2))
|
||||||
b2.clear()
|
b2.clear()
|
||||||
assertFalse(b1.intersects(b2))
|
assertFalse(b1.intersects(b2))
|
||||||
|
b2.set(128)
|
||||||
|
assertFalse(b1.intersects(b2))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on Harmony tests.
|
// Based on Harmony tests.
|
||||||
|
|||||||
@@ -280,8 +280,7 @@ class BitSet(size: Int = ELEMENT_SIZE) {
|
|||||||
/**
|
/**
|
||||||
* Returns the biggest index of a bit which value is [lookFor] before [startIndex] (inclusive).
|
* Returns the biggest index of a bit which value is [lookFor] before [startIndex] (inclusive).
|
||||||
* Returns -1 if there is no such bits before [startIndex].
|
* Returns -1 if there is no such bits before [startIndex].
|
||||||
* If [startIndex] >= [size] will search from [size] - 1 (if [lookFor] == true)
|
* If [startIndex] >= [size] returns -1
|
||||||
* or return [startIndex] (if [lookFor == false]).
|
|
||||||
*/
|
*/
|
||||||
fun previousBit(startIndex: Int, lookFor: Boolean): Int {
|
fun previousBit(startIndex: Int, lookFor: Boolean): Int {
|
||||||
var correctStartIndex = startIndex
|
var correctStartIndex = startIndex
|
||||||
@@ -326,6 +325,7 @@ class BitSet(size: Int = ELEMENT_SIZE) {
|
|||||||
/**
|
/**
|
||||||
* Returns the biggest index of a bit which value is `true` before [startIndex] (inclusive).
|
* Returns the biggest index of a bit which value is `true` before [startIndex] (inclusive).
|
||||||
* Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1.
|
* Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1.
|
||||||
|
* If [startIndex] >= size will search from (size - 1)-th bit.
|
||||||
* Throws IndexOutOfBoundException if [startIndex] < -1.
|
* Throws IndexOutOfBoundException if [startIndex] < -1.
|
||||||
*/
|
*/
|
||||||
fun previousSetBit(startIndex: Int): Int = previousBit(startIndex, true)
|
fun previousSetBit(startIndex: Int): Int = previousBit(startIndex, true)
|
||||||
@@ -351,35 +351,39 @@ class BitSet(size: Int = ELEMENT_SIZE) {
|
|||||||
return bits[elementIndex] and offset.asMask != 0L
|
return bits[elementIndex] and offset.asMask != 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
private inline fun doOperation(another: BitSet, operation: Long.(Long) -> Long) {
|
||||||
fun and(another: BitSet) {
|
|
||||||
ensureCapacity(another.lastIndex)
|
ensureCapacity(another.lastIndex)
|
||||||
for (index in bits.indices) {
|
var index = 0
|
||||||
bits[index] = bits[index] and another.bits[index]
|
while (index < another.bits.size) {
|
||||||
|
bits[index] = operation(bits[index], another.bits[index])
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
while (index < bits.size) {
|
||||||
|
bits[index] = operation(bits[index], ALL_FALSE)
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
||||||
|
fun and(another: BitSet) = doOperation(another, Long::and)
|
||||||
|
|
||||||
/** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
/** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
||||||
fun or(another: BitSet) {
|
fun or(another: BitSet) = doOperation(another, Long::or)
|
||||||
ensureCapacity(another.lastIndex)
|
|
||||||
for (index in bits.indices) {
|
/** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
||||||
bits[index] = bits[index] or another.bits[index]
|
fun xor(another: BitSet) = doOperation(another, Long::xor)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
/** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
||||||
fun andNot(another: BitSet) {
|
fun andNot(another: BitSet) {
|
||||||
ensureCapacity(another.lastIndex)
|
ensureCapacity(another.lastIndex)
|
||||||
for (index in bits.indices) {
|
var index = 0
|
||||||
|
while (index < another.bits.size) {
|
||||||
bits[index] = bits[index] and another.bits[index].inv()
|
bits[index] = bits[index] and another.bits[index].inv()
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
}
|
while (index < bits.size) {
|
||||||
|
bits[index] = bits[index] and ALL_TRUE
|
||||||
/** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */
|
index++
|
||||||
fun xor(another: BitSet) {
|
|
||||||
ensureCapacity(another.lastIndex)
|
|
||||||
for (index in bits.indices) {
|
|
||||||
bits[index] = bits[index] xor another.bits[index]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user