1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.util;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Utilities for treating {@code int[]}s as bit sets.
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class Bits {
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * This class is uninstantiable.
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private Bits() {
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // This space intentionally left blank.
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a bit set to contain bits up to the given index (exclusive).
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param max {@code >= 0;} the maximum bit index (exclusive)
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} an appropriately-constructed instance
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static int[] makeBitSet(int max) {
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int size = (max + 0x1f) >> 5;
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return new int[size];
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the maximum index (exclusive) for the given bit set.
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set in question
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code >= 0;} the maximum index (exclusive) that may be set
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static int getMax(int[] bits) {
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return bits.length * 0x20;
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the value of the bit at the given index.
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param idx {@code >= 0, < getMax(set);} which bit
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return the value of the indicated bit
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static boolean get(int[] bits, int idx) {
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int arrayIdx = idx >> 5;
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int bit = 1 << (idx & 0x1f);
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return (bits[arrayIdx] & bit) != 0;
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Sets the given bit to the given value.
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param idx {@code >= 0, < getMax(set);} which bit
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param value the new value for the bit
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static void set(int[] bits, int idx, boolean value) {
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int arrayIdx = idx >> 5;
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int bit = 1 << (idx & 0x1f);
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (value) {
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            bits[arrayIdx] |= bit;
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        } else {
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            bits[arrayIdx] &= ~bit;
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Sets the given bit to {@code true}.
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param idx {@code >= 0, < getMax(set);} which bit
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static void set(int[] bits, int idx) {
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int arrayIdx = idx >> 5;
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int bit = 1 << (idx & 0x1f);
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        bits[arrayIdx] |= bit;
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Sets the given bit to {@code false}.
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param idx {@code >= 0, < getMax(set);} which bit
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static void clear(int[] bits, int idx) {
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int arrayIdx = idx >> 5;
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int bit = 1 << (idx & 0x1f);
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        bits[arrayIdx] &= ~bit;
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Returns whether or not the given bit set is empty, that is, whether
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * no bit is set to {@code true}.
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code true} iff all bits are {@code false}
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static boolean isEmpty(int[] bits) {
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int len = bits.length;
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < len; i++) {
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (bits[i] != 0) {
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                return false;
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return true;
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the number of bits set to {@code true} in the given bit set.
127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code >= 0;} the bit count (aka population count) of the set
130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static int bitCount(int[] bits) {
132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int len = bits.length;
133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int count = 0;
134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < len; i++) {
136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            count += Integer.bitCount(bits[i]);
137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return count;
140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Returns whether any bits are set to {@code true} in the
144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * specified range.
145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param start {@code >= 0;} index of the first bit in the range (inclusive)
148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param end {@code >= 0;} index of the last bit in the range (exclusive)
149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code true} if any bit is set to {@code true} in
150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * the indicated range
151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static boolean anyInRange(int[] bits, int start, int end) {
153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int idx = findFirst(bits, start);
154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return (idx >= 0) && (idx < end);
155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Finds the lowest-order bit set at or after the given index in the
159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * given bit set.
160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param bits {@code non-null;} bit set to operate on
162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param idx {@code >= 0;} minimum index to return
163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},
164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * or {@code -1} if there is no appropriate bit index to return
165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static int findFirst(int[] bits, int idx) {
167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int len = bits.length;
168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int minBit = idx & 0x1f;
169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) {
171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            int word = bits[arrayIdx];
172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (word != 0) {
173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                int bitIdx = findFirst(word, minBit);
174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                if (bitIdx >= 0) {
175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    return (arrayIdx << 5) + bitIdx;
176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                }
177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            minBit = 0;
179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return -1;
182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Finds the lowest-order bit set at or after the given index in the
186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * given {@code int}.
187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param value the value in question
189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param idx 0..31 the minimum bit index to return
190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code >= -1;} lowest-order bit set at or after {@code idx},
191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * or {@code -1} if there is no appropriate bit index to return
192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static int findFirst(int value, int idx) {
194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        value &= ~((1 << idx) - 1); // Mask off too-low bits.
195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int result = Integer.numberOfTrailingZeros(value);
196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return (result == 32) ? -1 : result;
197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Ors bit array {@code b} into bit array {@code a}.
201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * {@code a.length} must be greater than or equal to
202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * {@code b.length}.
203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param a {@code non-null;} int array to be ored with other argument. This
205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * argument is modified.
206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param b {@code non-null;} int array to be ored into {@code a}. This
207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * argument is not modified.
208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static void or(int[] a, int[] b) {
210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < b.length; i++) {
211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            a[i] |= b[i];
212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static String toHuman(int[] bits) {
216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        StringBuilder sb = new StringBuilder();
217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        boolean needsComma = false;
219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append('{');
221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int bitsLength = 32 * bits.length;
223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < bitsLength; i++) {
224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (Bits.get(bits, i)) {
225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                if (needsComma) {
226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    sb.append(',');
227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                }
228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                needsComma = true;
229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                sb.append(i);
230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        sb.append('}');
233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return sb.toString();
235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
237