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