/* * 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 "SkTDArray.h" #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; } template void setAll(T* array, int len) { static_assert(std::is_integral::value, "T is integral"); for (int i = 0; i < len; ++i) { this->set(static_cast(array[i])); } } bool has(int index) const { const uint32_t* chunk = this->internalGet(index); uint32_t mask = 1 << (index & 31); return chunk && SkToBool(*chunk & mask); } /** Export indices of set bits to T array. */ template void exportTo(SkTDArray* array) const { static_assert(std::is_integral::value, "T is integral"); SkASSERT(array); uint32_t* data = reinterpret_cast(fBitData.get()); for (unsigned int i = 0; i < fDwordCount; ++i) { uint32_t value = data[i]; if (value) { // There are set bits unsigned int index = i * 32; for (unsigned int j = 0; j < 32; ++j) { if (0x1 & (value >> j)) { array->push(index + j); } } } } } private: std::unique_ptr> 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