This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 359ee64eda GROOVY-11306: Provide left/right shift operators for BitSet
359ee64eda is described below
commit 359ee64eda6bdafde7fa5c53ccab38f5e89df493
Author: Paul King <[email protected]>
AuthorDate: Mon Feb 5 16:06:36 2024 +1000
GROOVY-11306: Provide left/right shift operators for BitSet
---
.../groovy/runtime/DefaultGroovyMethods.java | 52 ++++++++++++++++++++++
src/test/groovy/BitSetTest.groovy | 18 ++++++++
2 files changed, 70 insertions(+)
diff --git
a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 424bcdb476..1f78e16bb0 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -8561,6 +8561,26 @@ public class DefaultGroovyMethods extends
DefaultGroovyMethodsSupport {
return NumberMath.leftShift(self, operand);
}
+ /**
+ * Implementation of the left shift operator for BitSets,
+ * returning a new BitSet and leaving the original unchanged.
+ * The {@code intValue()} is taken for the shift distance for non-integer
operands.
+ *
+ * @param self a BitSet
+ * @param operand the shift distance by which to shift the BitSet left
+ * @return the resulting BitSet
+ * @since 5.0.0
+ */
+ public static BitSet leftShift(BitSet self, Number operand) {
+ BitSet result = new BitSet(self.size());
+ final int limit = self.size() - 1;
+ self.stream().forEach(i -> {
+ if (i < limit)
+ result.set(i + operand.intValue());
+ });
+ return result;
+ }
+
//--------------------------------------------------------------------------
// max
@@ -11397,6 +11417,23 @@ public class DefaultGroovyMethods extends
DefaultGroovyMethodsSupport {
return NumberMath.rightShift(self, operand);
}
+ /**
+ * Implementation of the right shift operator for BitSets,
+ * returning a new BitSet and leaving the original unchanged.
+ * The {@code intValue()} is taken for the shift distance for non-integer
operands.
+ *
+ * @param self a BitSet
+ * @param operand the shift distance by which to right shift the BitSet
+ * @return the resulting BitSet
+ * @since 5.0.0
+ */
+ public static BitSet rightShift(BitSet self, Number operand) {
+ boolean carry = self.get(self.size() - 1);
+ BitSet result = self.get(operand.intValue(),
Math.max(operand.intValue(), self.length()));
+ result.set(self.size() - 1, carry);
+ return result;
+ }
+
//--------------------------------------------------------------------------
// rightShiftUnsigned
@@ -11413,6 +11450,21 @@ public class DefaultGroovyMethods extends
DefaultGroovyMethodsSupport {
return NumberMath.rightShiftUnsigned(self, operand);
}
+ /**
+ * Implementation of the right shift (unsigned) operator for BitSets,
+ * returning a new BitSet and leaving the original unchanged.
+ * The {@code intValue()} is taken for the shift distance for non-integer
operands.
+ *
+ * @param self a BitSet
+ * @param operand the shift distance by which to right shift (unsigned)
the BitSet
+ * @return the resulting BitSet
+ * @since 5.0.0
+ */
+ public static BitSet rightShiftUnsigned(BitSet self, Number operand) {
+ return self.get(operand.intValue(), Math.max(operand.intValue(),
self.length()));
+ }
+
+
//--------------------------------------------------------------------------
// round
diff --git a/src/test/groovy/BitSetTest.groovy
b/src/test/groovy/BitSetTest.groovy
index 9910fca559..25a7192734 100644
--- a/src/test/groovy/BitSetTest.groovy
+++ b/src/test/groovy/BitSetTest.groovy
@@ -162,6 +162,24 @@ class BitSetTest extends GroovyTestCase{
assertBitFalse b, 3
}
+ void testLeftShift() {
+ def testCases = [
+ [1, -12L],
+ [3, 271],
+ [1, (Long.MAX_VALUE/2 - 10).longValue()],
+ [1, (Long.MAX_VALUE/2 + 10).longValue()]
+ ]
+ testCases.each { int operand, long value ->
+ def a = BitSet.valueOf(value)
+ def b = BitSet.valueOf(value << operand)
+ def c = BitSet.valueOf(value >> operand)
+ def d = BitSet.valueOf(value >>> operand)
+ assert b == a << operand
+ assert c == a >> operand
+ assert d == a >>> operand
+ }
+ }
+
private assertBitTrue(bitset, index) {
assertTrue 'index ' + index + ' should have been true', bitset[index]
}