diff --git a/prism/src/common/IterableBitSet.java b/prism/src/common/IterableBitSet.java
index 9d2ec873..9697d18c 100644
--- a/prism/src/common/IterableBitSet.java
+++ b/prism/src/common/IterableBitSet.java
@@ -28,8 +28,10 @@
package common;
import java.util.BitSet;
-import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.PrimitiveIterator.OfInt;
+
+import common.iterable.IterableInt;
/**
* Convenience class to loop easily over the set/clear bits of a BitSet.
@@ -37,10 +39,11 @@ import java.util.NoSuchElementException;
* For example:
* for (Integer index : getSetBits(set)) { ... }
*/
-public class IterableBitSet implements Iterable
+public class IterableBitSet implements IterableInt
{
private BitSet set;
private boolean clearBits = false;
+ private boolean reversed = false;
private Integer maxIndex = null;
/**
@@ -50,59 +53,127 @@ public class IterableBitSet implements Iterable
{
this.set = set;
this.clearBits = false;
+ this.reversed = false;
+ }
+
+ /**
+ * Constructor for an Iterable that iterates over bits of the given set {@code set},
+ * up to the maximal index given by {@code maxIndex} (optional).
+ * If {@code clearBits} is {@code true}, iterate over the cleared bits instead of the set bits
+ * (requires {@code maxIndex} to be non-null).
+ * @param set the underlying BitSet
+ * @param maxIndex the maximal index for iteration (negative = iterate over the empty set, {@code null} = no restrictions)
+ * @param clearBits if true, iterate over the cleared bits in the BitSet
+ */
+ public IterableBitSet(BitSet set, Integer maxIndex, boolean clearBits)
+ {
+ this(set, maxIndex, clearBits, false);
}
/**
* Constructor for an Iterable that iterates over bits of the given set {@code set},
- * up to the maximal index given by {@code maxIndex}. If {@code clearBits} is {@code true},
- * iterate over the cleared bits instead of the set bits.
+ * up to the maximal index given by {@code maxIndex} (optional).
+ * If {@code clearBits} is {@code true}, iterate over the cleared bits instead of the set bits
+ * (requires {@code maxIndex} to be non-null).
+ * If {@code reversed} is set, iterate in reverse order (highest to lowest).
* @param set the underlying BitSet
- * @param maxIndex the maximal index for iteration (negative = iterate over the empty set)
+ * @param maxIndex the maximal index for iteration (negative = iterate over the empty set, {@code null} = no restrictions)
* @param clearBits if true, iterate over the cleared bits in the BitSet
+ * @param reversed if true, iterate in reversed order
*/
- public IterableBitSet(BitSet set, int maxIndex, boolean clearBits)
+ public IterableBitSet(BitSet set, Integer maxIndex, boolean clearBits, boolean reversed)
{
this.set = set;
this.maxIndex = maxIndex;
this.clearBits = clearBits;
+ this.reversed = reversed;
}
/** Implementation of the iterator over the set bits */
- private class SetBitsIterator implements Iterator {
- private int index = set.nextSetBit(0);
+ private class SetBitsIterator implements OfInt
+ {
+ private int current = -1;
+ private int next = set.nextSetBit(0);
@Override
- public boolean hasNext() {
- if (maxIndex != null && index > maxIndex) {
+ public boolean hasNext()
+ {
+ if (maxIndex != null && next > maxIndex) {
// limit to 0 ... maxIndex
return false;
}
- return index >= 0;
+ return next >= 0;
+ }
+
+ @Override
+ public int nextInt()
+ {
+ if (hasNext()) {
+ current = next;
+ next = set.nextSetBit(current + 1);
+ return current;
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove()
+ {
+ set.clear(current);
+ }
+ }
+
+ /** Implementation of the iterator over the set bits (reverse order) */
+ private class SetBitsReversedIterator implements OfInt
+ {
+ private int current = -1;
+ private int next = set.nextSetBit(0);
+
+ public SetBitsReversedIterator()
+ {
+ current = -1;
+ if (maxIndex != null) {
+ // only consider set bits with index <= maxIndex
+ next = set.previousSetBit(maxIndex);
+ } else {
+ next = set.length() - 1; // highest set bit
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return next >= 0;
}
@Override
- public Integer next() {
+ public int nextInt()
+ {
if (hasNext()) {
- Integer next = index;
- index = set.nextSetBit(index + 1);
- return next;
+ current = next;
+ next = set.previousSetBit(current - 1);
+ return current;
}
throw new NoSuchElementException();
}
@Override
- public void remove() {
- throw new UnsupportedOperationException();
+ public void remove()
+ {
+ set.clear(current);
}
}
/** Implementation of the iterator over the cleared bits, requires that {@code maxIndex != null} */
- private class ClearBitsIterator implements Iterator {
- private int index = set.nextClearBit(0);
+ private class ClearBitsIterator implements OfInt
+ {
+ private int current = -1;
+ private int next = set.nextClearBit(0);
@Override
- public boolean hasNext() {
- if (index > maxIndex) {
+ public boolean hasNext()
+ {
+ if (next > maxIndex) {
// limit to 0 ... maxIndex
return false;
}
@@ -110,27 +181,75 @@ public class IterableBitSet implements Iterable
}
@Override
- public Integer next() {
+ public int nextInt()
+ {
if (hasNext()) {
- Integer next = index;
- index = set.nextClearBit(index + 1);
- return next;
+ current = next;
+ next = set.nextClearBit(current + 1);
+ return current;
}
throw new NoSuchElementException();
}
@Override
- public void remove() {
- throw new UnsupportedOperationException();
+ public void remove()
+ {
+ set.set(current);
+ }
+ }
+
+ /** Implementation of the iterator over the clear bits (reverse order), requires that {@code maxIndex != null} */
+ private class ClearBitsReversedIterator implements OfInt
+ {
+ private int current = -1;
+ private int next = set.nextSetBit(0);
+
+ public ClearBitsReversedIterator()
+ {
+ current = -1;
+ // only consider clear bits with index <= maxIndex
+ next = set.previousClearBit(maxIndex);
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return next >= 0;
+ }
+
+ @Override
+ public int nextInt()
+ {
+ if (hasNext()) {
+ current = next;
+ next = set.previousClearBit(current - 1);
+ return current;
+ }
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove()
+ {
+ set.clear(current);
}
}
@Override
- public Iterator iterator() {
+ public OfInt iterator()
+ {
if (clearBits == false) {
- return new SetBitsIterator();
+ if (reversed) {
+ return new SetBitsReversedIterator();
+ } else {
+ return new SetBitsIterator();
+ }
} else {
- return new ClearBitsIterator();
+ if (reversed) {
+ return new ClearBitsReversedIterator();
+ } else {
+ return new ClearBitsIterator();
+ }
}
}
@@ -144,6 +263,17 @@ public class IterableBitSet implements Iterable
return new IterableBitSet(set);
}
+ /**
+ * Get an IterableBitSet that iterates over the bits of {@code set} that are set,
+ * in reverse order (highest to lowest index).
+ * @param set a BitSet
+ * @return an IterableBitSet over the set bits
+ */
+ public static IterableBitSet getSetBitsReversed(BitSet set)
+ {
+ return new IterableBitSet(set, null, false, true);
+ }
+
/**
* Get an IterableBitSet that iterates over the cleared bits of {@code set}, up to {@code maxIndex}
* @param set a BitSet
@@ -155,6 +285,17 @@ public class IterableBitSet implements Iterable
return new IterableBitSet(set, maxIndex, true);
}
+ /**
+ * Get an IterableBitSet that iterates over the cleared bits of {@code set}, up to {@code maxIndex},
+ * in reverse order (highest to lowest index).
+ * @param set a BitSet
+ * @return an IterableBitSet over the set bits
+ */
+ public static IterableBitSet getClearBitsReversed(BitSet set, int maxIndex)
+ {
+ return new IterableBitSet(set, maxIndex, true, true);
+ }
+
/**
* Simple test method.
*
@@ -177,7 +318,8 @@ public class IterableBitSet implements Iterable
}
test.clear();
- for (@SuppressWarnings("unused") Integer index : getSetBits(test)) {
+ for (@SuppressWarnings("unused")
+ Integer index : getSetBits(test)) {
throw new RuntimeException("BitSet should be empty!");
}
}