diff --git a/backend.native/tests/runtime/collections/BitSet.kt b/backend.native/tests/runtime/collections/BitSet.kt index ded33f65d2a..74615f31b8f 100644 --- a/backend.native/tests/runtime/collections/BitSet.kt +++ b/backend.native/tests/runtime/collections/BitSet.kt @@ -344,26 +344,54 @@ fun testLogic() { 65, 67, 70, 72) + // and var b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.and(b2) 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.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.or(b2) 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.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.xor(b2) 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.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.andNot(b2) 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.set(0..1); b1.set(62..63); b1.set(64..65); b1.set(71..72) b2.clear(); b2.set(0) @@ -374,6 +402,8 @@ fun testLogic() { assertTrue(b1.intersects(b2)) b2.clear() assertFalse(b1.intersects(b2)) + b2.set(128) + assertFalse(b1.intersects(b2)) } // Based on Harmony tests. diff --git a/runtime/src/main/kotlin/kotlin/BitSet.kt b/runtime/src/main/kotlin/kotlin/BitSet.kt index 3a13c3ec820..df4afb4832e 100644 --- a/runtime/src/main/kotlin/kotlin/BitSet.kt +++ b/runtime/src/main/kotlin/kotlin/BitSet.kt @@ -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 -1 if there is no such bits before [startIndex]. - * If [startIndex] >= [size] will search from [size] - 1 (if [lookFor] == true) - * or return [startIndex] (if [lookFor == false]). + * If [startIndex] >= [size] returns -1 */ fun previousBit(startIndex: Int, lookFor: Boolean): Int { 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 -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. */ 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 } - /** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - fun and(another: BitSet) { + private inline fun doOperation(another: BitSet, operation: Long.(Long) -> Long) { ensureCapacity(another.lastIndex) - for (index in bits.indices) { - bits[index] = bits[index] and another.bits[index] + var index = 0 + 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. */ - fun or(another: BitSet) { - ensureCapacity(another.lastIndex) - for (index in bits.indices) { - bits[index] = bits[index] or another.bits[index] - } - } + fun or(another: BitSet) = doOperation(another, Long::or) + + /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + 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. */ fun andNot(another: BitSet) { 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() + index++ } - } - - /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - fun xor(another: BitSet) { - ensureCapacity(another.lastIndex) - for (index in bits.indices) { - bits[index] = bits[index] xor another.bits[index] + while (index < bits.size) { + bits[index] = bits[index] and ALL_TRUE + index++ } }