A "builder"-style helper class for manipulating character classes represented as an array of pairs of runes [lo, hi], each denoting an inclusive interval. All methods mutate the internal state and return this, allowing operations to be chained.
| 16 | * All methods mutate the internal state and return {@code this}, allowing operations to be chained. |
| 17 | */ |
| 18 | class CharClass { |
| 19 | |
| 20 | private int[] r; // inclusive ranges, pairs of [lo,hi]. r.length is even. |
| 21 | private int len; // prefix of |r| that is defined. Even. |
| 22 | |
| 23 | // Constructs a CharClass with initial ranges |r|. |
| 24 | // The right to mutate |r| is passed to the callee. |
| 25 | CharClass(int[] r) { |
| 26 | this.r = r; |
| 27 | this.len = r.length; |
| 28 | } |
| 29 | |
| 30 | // Constructs an empty CharClass. |
| 31 | CharClass() { |
| 32 | this.r = Utils.EMPTY_INTS; |
| 33 | this.len = 0; |
| 34 | } |
| 35 | |
| 36 | // After a call to ensureCapacity(), |r.length| is at least |newLen|. |
| 37 | private void ensureCapacity(int newLen) { |
| 38 | if (r.length < newLen) { |
| 39 | // Expand by at least doubling, except when len == 0. |
| 40 | // TODO(adonovan): opt: perhaps it would be better to allocate exactly |
| 41 | // newLen, since the number of expansions is typically very small? |
| 42 | if (newLen < len * 2) { |
| 43 | newLen = len * 2; |
| 44 | } |
| 45 | int[] r2 = new int[newLen]; |
| 46 | System.arraycopy(r, 0, r2, 0, len); |
| 47 | r = r2; |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | // Returns the character class as an int array. Subsequent CharClass |
| 52 | // operations may mutate this array, so typically this is the last operation |
| 53 | // performed on a given CharClass instance. |
| 54 | int[] toArray() { |
| 55 | if (this.len == r.length) { |
| 56 | return r; |
| 57 | } else { |
| 58 | int[] r2 = new int[len]; |
| 59 | System.arraycopy(r, 0, r2, 0, len); |
| 60 | return r2; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | // cleanClass() sorts the ranges (pairs of elements) of this CharClass, |
| 65 | // merges them, and eliminates duplicates. |
| 66 | CharClass cleanClass() { |
| 67 | if (len < 4) { |
| 68 | return this; |
| 69 | } |
| 70 | |
| 71 | // Sort by lo increasing, hi decreasing to break ties. |
| 72 | qsortIntPair(r, 0, len - 2); |
| 73 | |
| 74 | // Merge abutting, overlapping. |
| 75 | int w = 2; // write index |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…