/* * 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