/*
|
* Copyright 2011 Google Inc.
|
*
|
* Use of this source code is governed by a BSD-style license that can be
|
* found in the LICENSE file.
|
*/
|
|
#ifndef SkBitSet_DEFINED
|
#define SkBitSet_DEFINED
|
|
#include "SkTemplates.h"
|
|
class SkBitSet {
|
public:
|
explicit SkBitSet(int numberOfBits) {
|
SkASSERT(numberOfBits >= 0);
|
fDwordCount = (numberOfBits + 31) / 32; // Round up size to 32-bit boundary.
|
if (fDwordCount > 0) {
|
fBitData.reset((uint32_t*)sk_calloc_throw(fDwordCount * sizeof(uint32_t)));
|
}
|
}
|
|
/** Set the value of the index-th bit to true. */
|
void set(int index) {
|
uint32_t mask = 1 << (index & 31);
|
uint32_t* chunk = this->internalGet(index);
|
SkASSERT(chunk);
|
*chunk |= mask;
|
}
|
|
bool has(int index) const {
|
const uint32_t* chunk = this->internalGet(index);
|
uint32_t mask = 1 << (index & 31);
|
return chunk && SkToBool(*chunk & mask);
|
}
|
|
// Calls f(unsigned) for each set value.
|
template<typename FN>
|
void getSetValues(FN f) const {
|
const uint32_t* data = fBitData.get();
|
for (unsigned i = 0; i < fDwordCount; ++i) {
|
if (uint32_t value = data[i]) { // There are set bits
|
unsigned index = i * 32;
|
for (unsigned j = 0; j < 32; ++j) {
|
if (0x1 & (value >> j)) {
|
f(index | j);
|
}
|
}
|
}
|
}
|
}
|
|
private:
|
std::unique_ptr<uint32_t, SkFunctionWrapper<void, void, sk_free>> fBitData;
|
size_t fDwordCount; // Dword (32-bit) count of the bitset.
|
|
uint32_t* internalGet(int index) const {
|
size_t internalIndex = index / 32;
|
if (internalIndex >= fDwordCount) {
|
return nullptr;
|
}
|
return fBitData.get() + internalIndex;
|
}
|
};
|
|
|
#endif
|