Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / wtf / BitVector.h
blobe540725cd8b06d01583a10ca27d41116bc5450f0
1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef BitVector_h
27 #define BitVector_h
29 #include "wtf/Assertions.h"
30 #include "wtf/StdLibExtras.h"
31 #include "wtf/WTFExport.h"
33 namespace WTF {
35 class PrintStream;
37 // This is a space-efficient, resizeable bitvector class. In the common case it
38 // occupies one word, but if necessary, it will inflate this one word to point
39 // to a single chunk of out-of-line allocated storage to store an arbitrary number
40 // of bits.
42 // - The bitvector remembers the bound of how many bits can be stored, but this
43 // may be slightly greater (by as much as some platform-specific constant)
44 // than the last argument passed to ensureSize().
46 // - The bitvector can resize itself automatically (set, clear, get) or can be used
47 // in a manual mode, which is faster (quickSet, quickClear, quickGet, ensureSize).
49 // - Accesses ASSERT that you are within bounds.
51 // - Bits are automatically initialized to zero.
53 // On the other hand, this BitVector class may not be the fastest around, since
54 // it does conditionals on every get/set/clear. But it is great if you need to
55 // juggle a lot of variable-length BitVectors and you're worried about wasting
56 // space.
58 class WTF_EXPORT BitVector {
59 public:
60 BitVector()
61 : m_bitsOrPointer(makeInlineBits(0))
65 explicit BitVector(size_t numBits)
66 : m_bitsOrPointer(makeInlineBits(0))
68 ensureSize(numBits);
71 BitVector(const BitVector& other)
72 : m_bitsOrPointer(makeInlineBits(0))
74 (*this) = other;
78 ~BitVector()
80 if (isInline())
81 return;
82 OutOfLineBits::destroy(outOfLineBits());
85 BitVector& operator=(const BitVector& other)
87 if (isInline() && other.isInline())
88 m_bitsOrPointer = other.m_bitsOrPointer;
89 else
90 setSlow(other);
91 return *this;
94 size_t size() const
96 if (isInline())
97 return maxInlineBits();
98 return outOfLineBits()->numBits();
101 void ensureSize(size_t numBits)
103 if (numBits <= size())
104 return;
105 resizeOutOfLine(numBits);
108 // Like ensureSize(), but supports reducing the size of the bitvector.
109 void resize(size_t numBits);
111 void clearAll();
113 bool quickGet(size_t bit) const
115 ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
116 return !!(bits()[bit / bitsInPointer()] & (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1))));
119 void quickSet(size_t bit)
121 ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
122 bits()[bit / bitsInPointer()] |= (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
125 void quickClear(size_t bit)
127 ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
128 bits()[bit / bitsInPointer()] &= ~(static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
131 void quickSet(size_t bit, bool value)
133 if (value)
134 quickSet(bit);
135 else
136 quickClear(bit);
139 bool get(size_t bit) const
141 if (bit >= size())
142 return false;
143 return quickGet(bit);
146 void set(size_t bit)
148 ensureSize(bit + 1);
149 quickSet(bit);
152 void ensureSizeAndSet(size_t bit, size_t size)
154 ensureSize(size);
155 quickSet(bit);
158 void clear(size_t bit)
160 if (bit >= size())
161 return;
162 quickClear(bit);
165 void set(size_t bit, bool value)
167 if (value)
168 set(bit);
169 else
170 clear(bit);
173 void dump(PrintStream& out);
175 private:
176 static unsigned bitsInPointer()
178 return sizeof(void*) << 3;
181 static unsigned maxInlineBits()
183 return bitsInPointer() - 1;
186 static size_t byteCount(size_t bitCount)
188 return (bitCount + 7) >> 3;
191 static uintptr_t makeInlineBits(uintptr_t bits)
193 ASSERT(!(bits & (static_cast<uintptr_t>(1) << maxInlineBits())));
194 return bits | (static_cast<uintptr_t>(1) << maxInlineBits());
197 class WTF_EXPORT OutOfLineBits {
198 public:
199 size_t numBits() const { return m_numBits; }
200 size_t numWords() const { return (m_numBits + bitsInPointer() - 1) / bitsInPointer(); }
201 uintptr_t* bits() { return bitwise_cast<uintptr_t*>(this + 1); }
202 const uintptr_t* bits() const { return bitwise_cast<const uintptr_t*>(this + 1); }
204 static OutOfLineBits* create(size_t numBits);
206 static void destroy(OutOfLineBits*);
208 private:
209 OutOfLineBits(size_t numBits)
210 : m_numBits(numBits)
214 size_t m_numBits;
217 bool isInline() const { return m_bitsOrPointer >> maxInlineBits(); }
219 const OutOfLineBits* outOfLineBits() const { return bitwise_cast<const OutOfLineBits*>(m_bitsOrPointer << 1); }
220 OutOfLineBits* outOfLineBits() { return bitwise_cast<OutOfLineBits*>(m_bitsOrPointer << 1); }
222 void resizeOutOfLine(size_t numBits);
223 void setSlow(const BitVector& other);
225 uintptr_t* bits()
227 if (isInline())
228 return &m_bitsOrPointer;
229 return outOfLineBits()->bits();
232 const uintptr_t* bits() const
234 if (isInline())
235 return &m_bitsOrPointer;
236 return outOfLineBits()->bits();
239 uintptr_t m_bitsOrPointer;
242 } // namespace WTF
244 using WTF::BitVector;
246 #endif // BitVector_h