1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SkBitSet_DEFINED
11#define SkBitSet_DEFINED
12
13#include "SkTypes.h"
14#include "SkTDArray.h"
15
16class SkBitSet {
17public:
18    /** NumberOfBits must be greater than zero.
19     */
20    explicit SkBitSet(int numberOfBits);
21    explicit SkBitSet(const SkBitSet& source);
22
23    SkBitSet& operator=(const SkBitSet& rhs);
24    bool operator==(const SkBitSet& rhs);
25    bool operator!=(const SkBitSet& rhs);
26
27    /** Clear all data.
28     */
29    void clearAll();
30
31    /** Set the value of the index-th bit.
32     */
33    void setBit(int index, bool value);
34
35    /** Test if bit index is set.
36     */
37    bool isBitSet(int index) const;
38
39    /** Or bits from source.  false is returned if this doesn't have the same
40     *  bit count as source.
41     */
42    bool orBits(const SkBitSet& source);
43
44    /** Export indices of set bits to T array.
45     */
46    template<typename T>
47    void exportTo(SkTDArray<T>* array) const {
48        SkASSERT(array);
49        uint32_t* data = reinterpret_cast<uint32_t*>(fBitData.get());
50        for (unsigned int i = 0; i < fDwordCount; ++i) {
51            uint32_t value = data[i];
52            if (value) {  // There are set bits
53                unsigned int index = i * 32;
54                for (unsigned int j = 0; j < 32; ++j) {
55                    if (0x1 & (value >> j)) {
56                        array->push(index + j);
57                    }
58                }
59            }
60        }
61    }
62
63private:
64    SkAutoFree fBitData;
65    // Dword (32-bit) count of the bitset.
66    size_t fDwordCount;
67    size_t fBitCount;
68
69    uint32_t* internalGet(int index) const {
70        SkASSERT((size_t)index < fBitCount);
71        size_t internalIndex = index / 32;
72        SkASSERT(internalIndex < fDwordCount);
73        return reinterpret_cast<uint32_t*>(fBitData.get()) + internalIndex;
74    }
75};
76
77
78#endif
79