• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef UTILS_BITSET_H
18 #define UTILS_BITSET_H
19 
20 #include <stdint.h>
21 #include <utils/TypeHelpers.h>
22 
23 /*
24  * A class to provide efficient manipulation of bitsets.
25  *
26  * Consider using std::bitset<32> or std::bitset<64> if all you want is a class to do basic bit
27  * manipulation (i.e. AND / OR / XOR / flip / etc). These classes are only needed if you want to
28  * efficiently perform operations like finding the first set bit in a bitset and you want to
29  * avoid using the built-in functions (e.g. __builtin_clz) on std::bitset::to_ulong.
30  */
31 
32 namespace android {
33 
34 // A simple set of 32 bits that can be individually marked or cleared.
35 struct BitSet32 {
36     uint32_t value;
37 
BitSet32BitSet3238     inline BitSet32() : value(0UL) { }
BitSet32BitSet3239     explicit inline BitSet32(uint32_t value) : value(value) { }
40 
41     // Gets the value associated with a particular bit index.
valueForBitBitSet3242     static inline uint32_t valueForBit(uint32_t n) { return 0x80000000UL >> n; }
43 
44     // Clears the bit set.
clearBitSet3245     inline void clear() { clear(value); }
46 
clearBitSet3247     static inline void clear(uint32_t& value) { value = 0UL; }
48 
49     // Returns the number of marked bits in the set.
countBitSet3250     inline uint32_t count() const { return count(value); }
51 
countBitSet3252     static inline uint32_t count(uint32_t value) {
53         return static_cast<uint32_t>(__builtin_popcountl(value));
54     }
55 
56     // Returns true if the bit set does not contain any marked bits.
isEmptyBitSet3257     inline bool isEmpty() const { return isEmpty(value); }
58 
isEmptyBitSet3259     static inline bool isEmpty(uint32_t value) { return ! value; }
60 
61     // Returns true if the bit set does not contain any unmarked bits.
isFullBitSet3262     inline bool isFull() const { return isFull(value); }
63 
isFullBitSet3264     static inline bool isFull(uint32_t value) { return value == 0xffffffffUL; }
65 
66     // Returns true if the specified bit is marked.
hasBitBitSet3267     inline bool hasBit(uint32_t n) const { return hasBit(value, n); }
68 
hasBitBitSet3269     static inline bool hasBit(uint32_t value, uint32_t n) { return value & valueForBit(n); }
70 
71     // Marks the specified bit.
markBitBitSet3272     inline void markBit(uint32_t n) { markBit(value, n); }
73 
markBitBitSet3274     static inline void markBit (uint32_t& value, uint32_t n) { value |= valueForBit(n); }
75 
76     // Clears the specified bit.
clearBitBitSet3277     inline void clearBit(uint32_t n) { clearBit(value, n); }
78 
clearBitBitSet3279     static inline void clearBit(uint32_t& value, uint32_t n) { value &= ~ valueForBit(n); }
80 
81     // Finds the first marked bit in the set.
82     // Result is undefined if all bits are unmarked.
firstMarkedBitBitSet3283     inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }
84 
firstMarkedBitBitSet3285     static uint32_t firstMarkedBit(uint32_t value) { return clz_checked(value); }
86 
87     // Finds the first unmarked bit in the set.
88     // Result is undefined if all bits are marked.
firstUnmarkedBitBitSet3289     inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }
90 
firstUnmarkedBitBitSet3291     static inline uint32_t firstUnmarkedBit(uint32_t value) { return clz_checked(~ value); }
92 
93     // Finds the last marked bit in the set.
94     // Result is undefined if all bits are unmarked.
lastMarkedBitBitSet3295     inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }
96 
lastMarkedBitBitSet3297     static inline uint32_t lastMarkedBit(uint32_t value) { return 31 - ctz_checked(value); }
98 
99     // Finds the first marked bit in the set and clears it.  Returns the bit index.
100     // Result is undefined if all bits are unmarked.
clearFirstMarkedBitBitSet32101     inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); }
102 
clearFirstMarkedBitBitSet32103     static inline uint32_t clearFirstMarkedBit(uint32_t& value) {
104         uint32_t n = firstMarkedBit(value);
105         clearBit(value, n);
106         return n;
107     }
108 
109     // Finds the first unmarked bit in the set and marks it.  Returns the bit index.
110     // Result is undefined if all bits are marked.
markFirstUnmarkedBitBitSet32111     inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); }
112 
markFirstUnmarkedBitBitSet32113     static inline uint32_t markFirstUnmarkedBit(uint32_t& value) {
114         uint32_t n = firstUnmarkedBit(value);
115         markBit(value, n);
116         return n;
117     }
118 
119     // Finds the last marked bit in the set and clears it.  Returns the bit index.
120     // Result is undefined if all bits are unmarked.
clearLastMarkedBitBitSet32121     inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); }
122 
clearLastMarkedBitBitSet32123     static inline uint32_t clearLastMarkedBit(uint32_t& value) {
124         uint32_t n = lastMarkedBit(value);
125         clearBit(value, n);
126         return n;
127     }
128 
129     // Gets the index of the specified bit in the set, which is the number of
130     // marked bits that appear before the specified bit.
getIndexOfBitBitSet32131     inline uint32_t getIndexOfBit(uint32_t n) const {
132         return getIndexOfBit(value, n);
133     }
134 
getIndexOfBitBitSet32135     static inline uint32_t getIndexOfBit(uint32_t value, uint32_t n) {
136         return static_cast<uint32_t>(__builtin_popcountl(value & ~(0xffffffffUL >> n)));
137     }
138 
139     inline bool operator== (const BitSet32& other) const { return value == other.value; }
140     inline bool operator!= (const BitSet32& other) const { return value != other.value; }
141     inline BitSet32 operator& (const BitSet32& other) const {
142         return BitSet32(value & other.value);
143     }
144     inline BitSet32& operator&= (const BitSet32& other) {
145         value &= other.value;
146         return *this;
147     }
148     inline BitSet32 operator| (const BitSet32& other) const {
149         return BitSet32(value | other.value);
150     }
151     inline BitSet32& operator|= (const BitSet32& other) {
152         value |= other.value;
153         return *this;
154     }
155 
156 private:
157     // We use these helpers as the signature of __builtin_c{l,t}z has "unsigned int" for the
158     // input, which is only guaranteed to be 16b, not 32. The compiler should optimize this away.
clz_checkedBitSet32159     static inline uint32_t clz_checked(uint32_t value) {
160         if (sizeof(unsigned int) == sizeof(uint32_t)) {
161             return static_cast<uint32_t>(__builtin_clz(value));
162         } else {
163             return static_cast<uint32_t>(__builtin_clzl(value));
164         }
165     }
166 
ctz_checkedBitSet32167     static inline uint32_t ctz_checked(uint32_t value) {
168         if (sizeof(unsigned int) == sizeof(uint32_t)) {
169             return static_cast<uint32_t>(__builtin_ctz(value));
170         } else {
171             return static_cast<uint32_t>(__builtin_ctzl(value));
172         }
173     }
174 };
175 
176 ANDROID_BASIC_TYPES_TRAITS(BitSet32)
177 
178 // A simple set of 64 bits that can be individually marked or cleared.
179 struct BitSet64 {
180     uint64_t value;
181 
BitSet64BitSet64182     inline BitSet64() : value(0ULL) { }
BitSet64BitSet64183     explicit inline BitSet64(uint64_t value) : value(value) { }
184 
185     // Gets the value associated with a particular bit index.
valueForBitBitSet64186     static inline uint64_t valueForBit(uint32_t n) { return 0x8000000000000000ULL >> n; }
187 
188     // Clears the bit set.
clearBitSet64189     inline void clear() { clear(value); }
190 
clearBitSet64191     static inline void clear(uint64_t& value) { value = 0ULL; }
192 
193     // Returns the number of marked bits in the set.
countBitSet64194     inline uint32_t count() const { return count(value); }
195 
countBitSet64196     static inline uint32_t count(uint64_t value) {
197         return static_cast<uint32_t>(__builtin_popcountll(value));
198     }
199 
200     // Returns true if the bit set does not contain any marked bits.
isEmptyBitSet64201     inline bool isEmpty() const { return isEmpty(value); }
202 
isEmptyBitSet64203     static inline bool isEmpty(uint64_t value) { return ! value; }
204 
205     // Returns true if the bit set does not contain any unmarked bits.
isFullBitSet64206     inline bool isFull() const { return isFull(value); }
207 
isFullBitSet64208     static inline bool isFull(uint64_t value) { return value == 0xffffffffffffffffULL; }
209 
210     // Returns true if the specified bit is marked.
hasBitBitSet64211     inline bool hasBit(uint32_t n) const { return hasBit(value, n); }
212 
hasBitBitSet64213     static inline bool hasBit(uint64_t value, uint32_t n) { return value & valueForBit(n); }
214 
215     // Marks the specified bit.
markBitBitSet64216     inline void markBit(uint32_t n) { markBit(value, n); }
217 
markBitBitSet64218     static inline void markBit(uint64_t& value, uint32_t n) { value |= valueForBit(n); }
219 
220     // Clears the specified bit.
clearBitBitSet64221     inline void clearBit(uint32_t n) { clearBit(value, n); }
222 
clearBitBitSet64223     static inline void clearBit(uint64_t& value, uint32_t n) { value &= ~ valueForBit(n); }
224 
225     // Finds the first marked bit in the set.
226     // Result is undefined if all bits are unmarked.
firstMarkedBitBitSet64227     inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); }
228 
firstMarkedBitBitSet64229     static inline uint32_t firstMarkedBit(uint64_t value) {
230         return static_cast<uint32_t>(__builtin_clzll(value));
231     }
232 
233     // Finds the first unmarked bit in the set.
234     // Result is undefined if all bits are marked.
firstUnmarkedBitBitSet64235     inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); }
236 
firstUnmarkedBitBitSet64237     static inline uint32_t firstUnmarkedBit(uint64_t value) {
238         return static_cast<uint32_t>(__builtin_clzll(~value));
239     }
240 
241     // Finds the last marked bit in the set.
242     // Result is undefined if all bits are unmarked.
lastMarkedBitBitSet64243     inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); }
244 
lastMarkedBitBitSet64245     static inline uint32_t lastMarkedBit(uint64_t value) {
246         return static_cast<uint32_t>(63 - __builtin_ctzll(value));
247     }
248 
249     // Finds the first marked bit in the set and clears it.  Returns the bit index.
250     // Result is undefined if all bits are unmarked.
clearFirstMarkedBitBitSet64251     inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); }
252 
clearFirstMarkedBitBitSet64253     static inline uint32_t clearFirstMarkedBit(uint64_t& value) {
254         uint32_t n = firstMarkedBit(value);
255         clearBit(value, n);
256         return n;
257     }
258 
259     // Finds the first unmarked bit in the set and marks it.  Returns the bit index.
260     // Result is undefined if all bits are marked.
markFirstUnmarkedBitBitSet64261     inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); }
262 
markFirstUnmarkedBitBitSet64263     static inline uint32_t markFirstUnmarkedBit(uint64_t& value) {
264         uint32_t n = firstUnmarkedBit(value);
265         markBit(value, n);
266         return n;
267     }
268 
269     // Finds the last marked bit in the set and clears it.  Returns the bit index.
270     // Result is undefined if all bits are unmarked.
clearLastMarkedBitBitSet64271     inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); }
272 
clearLastMarkedBitBitSet64273     static inline uint32_t clearLastMarkedBit(uint64_t& value) {
274         uint32_t n = lastMarkedBit(value);
275         clearBit(value, n);
276         return n;
277     }
278 
279     // Gets the index of the specified bit in the set, which is the number of
280     // marked bits that appear before the specified bit.
getIndexOfBitBitSet64281     inline uint32_t getIndexOfBit(uint32_t n) const { return getIndexOfBit(value, n); }
282 
getIndexOfBitBitSet64283     static inline uint32_t getIndexOfBit(uint64_t value, uint32_t n) {
284         return static_cast<uint32_t>(__builtin_popcountll(value & ~(0xffffffffffffffffULL >> n)));
285     }
286 
287     inline bool operator== (const BitSet64& other) const { return value == other.value; }
288     inline bool operator!= (const BitSet64& other) const { return value != other.value; }
289     inline BitSet64 operator& (const BitSet64& other) const {
290         return BitSet64(value & other.value);
291     }
292     inline BitSet64& operator&= (const BitSet64& other) {
293         value &= other.value;
294         return *this;
295     }
296     inline BitSet64 operator| (const BitSet64& other) const {
297         return BitSet64(value | other.value);
298     }
299     inline BitSet64& operator|= (const BitSet64& other) {
300         value |= other.value;
301         return *this;
302     }
303 };
304 
305 ANDROID_BASIC_TYPES_TRAITS(BitSet64)
306 
307 } // namespace android
308 
309 #endif // UTILS_BITSET_H
310