1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/*
2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project
3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License.
6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at
7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and
14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License.
15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.util;
18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/**
20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Utilities for treating {@code int[]}s as bit sets.
21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class Bits {
23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * This class is uninstantiable.
25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private Bits() {
27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        // This space intentionally left blank.
28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Constructs a bit set to contain bits up to the given index (exclusive).
32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param max {@code >= 0;} the maximum bit index (exclusive)
34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} an appropriately-constructed instance
35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static int[] makeBitSet(int max) {
37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int size = (max + 0x1f) >> 5;
38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return new int[size];
39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the maximum index (exclusive) for the given bit set.
43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set in question
45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= 0;} the maximum index (exclusive) that may be set
46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static int getMax(int[] bits) {
48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return bits.length * 0x20;
49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the value of the bit at the given index.
53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param idx {@code >= 0, < getMax(set);} which bit
56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return the value of the indicated bit
57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static boolean get(int[] bits, int idx) {
59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int arrayIdx = idx >> 5;
60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int bit = 1 << (idx & 0x1f);
61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return (bits[arrayIdx] & bit) != 0;
62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Sets the given bit to the given value.
66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param idx {@code >= 0, < getMax(set);} which bit
69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param value the new value for the bit
70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static void set(int[] bits, int idx, boolean value) {
72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int arrayIdx = idx >> 5;
73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int bit = 1 << (idx & 0x1f);
74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (value) {
76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            bits[arrayIdx] |= bit;
77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        } else {
78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            bits[arrayIdx] &= ~bit;
79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Sets the given bit to {@code true}.
84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param idx {@code >= 0, < getMax(set);} which bit
87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static void set(int[] bits, int idx) {
89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int arrayIdx = idx >> 5;
90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int bit = 1 << (idx & 0x1f);
91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        bits[arrayIdx] |= bit;
92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Sets the given bit to {@code false}.
96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param idx {@code >= 0, < getMax(set);} which bit
99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static void clear(int[] bits, int idx) {
101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int arrayIdx = idx >> 5;
102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int bit = 1 << (idx & 0x1f);
103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        bits[arrayIdx] &= ~bit;
104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Returns whether or not the given bit set is empty, that is, whether
108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * no bit is set to {@code true}.
109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code true} iff all bits are {@code false}
112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static boolean isEmpty(int[] bits) {
114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int len = bits.length;
115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < len; i++) {
117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (bits[i] != 0) {
118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                return false;
119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return true;
123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the number of bits set to {@code true} in the given bit set.
127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= 0;} the bit count (aka population count) of the set
130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static int bitCount(int[] bits) {
132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int len = bits.length;
133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int count = 0;
134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < len; i++) {
136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            count += Integer.bitCount(bits[i]);
137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return count;
140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Returns whether any bits are set to {@code true} in the
144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * specified range.
145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param start {@code >= 0;} index of the first bit in the range (inclusive)
148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param end {@code >= 0;} index of the last bit in the range (exclusive)
149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code true} if any bit is set to {@code true} in
150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * the indicated range
151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static boolean anyInRange(int[] bits, int start, int end) {
153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int idx = findFirst(bits, start);
154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return (idx >= 0) && (idx < end);
155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Finds the lowest-order bit set at or after the given index in the
159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * given bit set.
160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param bits {@code non-null;} bit set to operate on
162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param idx {@code >= 0;} minimum index to return
163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},
164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * or {@code -1} if there is no appropriate bit index to return
165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static int findFirst(int[] bits, int idx) {
167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int len = bits.length;
168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int minBit = idx & 0x1f;
169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) {
171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            int word = bits[arrayIdx];
172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (word != 0) {
173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                int bitIdx = findFirst(word, minBit);
174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                if (bitIdx >= 0) {
175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    return (arrayIdx << 5) + bitIdx;
176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            minBit = 0;
179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return -1;
182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Finds the lowest-order bit set at or after the given index in the
186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * given {@code int}.
187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param value the value in question
189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param idx 0..31 the minimum bit index to return
190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},
191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * or {@code -1} if there is no appropriate bit index to return
192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static int findFirst(int value, int idx) {
194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        value &= ~((1 << idx) - 1); // Mask off too-low bits.
195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int result = Integer.numberOfTrailingZeros(value);
196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return (result == 32) ? -1 : result;
197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Ors bit array {@code b} into bit array {@code a}.
201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code a.length} must be greater than or equal to
202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code b.length}.
203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param a {@code non-null;} int array to be ored with other argument. This
205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * argument is modified.
206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param b {@code non-null;} int array to be ored into {@code a}. This
207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * argument is not modified.
208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static void or(int[] a, int[] b) {
210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < b.length; i++) {
211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            a[i] |= b[i];
212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static String toHuman(int[] bits) {
216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        StringBuilder sb = new StringBuilder();
217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        boolean needsComma = false;
219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        sb.append('{');
221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int bitsLength = 32 * bits.length;
223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < bitsLength; i++) {
224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (Bits.get(bits, i)) {
225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                if (needsComma) {
226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    sb.append(',');
227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                needsComma = true;
229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                sb.append(i);
230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        sb.append('}');
233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return sb.toString();
235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson}
237