| /* | |
| * 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<typename T> | |
| void setAll(T* array, int len) { | |
| static_assert(std::is_integral<T>::value, "T is integral"); | |
| for (int i = 0; i < len; ++i) { | |
| this->set(static_cast<int>(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<typename T> | |
| void exportTo(SkTDArray<T>* array) const { | |
| static_assert(std::is_integral<T>::value, "T is integral"); | |
| SkASSERT(array); | |
| uint32_t* data = reinterpret_cast<uint32_t*>(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_back(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 |