|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /* bit vectors for sets of CSS properties */ |
|
6 |
|
7 #ifndef nsCSSPropertySet_h__ |
|
8 #define nsCSSPropertySet_h__ |
|
9 |
|
10 #include "mozilla/ArrayUtils.h" |
|
11 |
|
12 #include "nsCSSProperty.h" |
|
13 #include <limits.h> // for CHAR_BIT |
|
14 |
|
15 /** |
|
16 * nsCSSPropertySet maintains a set of non-shorthand CSS properties. In |
|
17 * other words, for each longhand CSS property we support, it has a bit |
|
18 * for whether that property is in the set. |
|
19 */ |
|
20 class nsCSSPropertySet { |
|
21 public: |
|
22 nsCSSPropertySet() { Empty(); } |
|
23 // auto-generated copy-constructor OK |
|
24 |
|
25 void AssertInSetRange(nsCSSProperty aProperty) const { |
|
26 NS_ASSERTION(0 <= aProperty && |
|
27 aProperty < eCSSProperty_COUNT_no_shorthands, |
|
28 "out of bounds"); |
|
29 } |
|
30 |
|
31 // Conversion of aProperty to |size_t| after AssertInSetRange |
|
32 // lets the compiler generate significantly tighter code. |
|
33 |
|
34 void AddProperty(nsCSSProperty aProperty) { |
|
35 AssertInSetRange(aProperty); |
|
36 size_t p = aProperty; |
|
37 mProperties[p / kBitsInChunk] |= |
|
38 property_set_type(1) << (p % kBitsInChunk); |
|
39 } |
|
40 |
|
41 void RemoveProperty(nsCSSProperty aProperty) { |
|
42 AssertInSetRange(aProperty); |
|
43 size_t p = aProperty; |
|
44 mProperties[p / kBitsInChunk] &= |
|
45 ~(property_set_type(1) << (p % kBitsInChunk)); |
|
46 } |
|
47 |
|
48 bool HasProperty(nsCSSProperty aProperty) const { |
|
49 AssertInSetRange(aProperty); |
|
50 size_t p = aProperty; |
|
51 return (mProperties[p / kBitsInChunk] & |
|
52 (property_set_type(1) << (p % kBitsInChunk))) != 0; |
|
53 } |
|
54 |
|
55 void Empty() { |
|
56 memset(mProperties, 0, sizeof(mProperties)); |
|
57 } |
|
58 |
|
59 void AssertIsEmpty(const char* aText) const { |
|
60 for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) { |
|
61 NS_ASSERTION(mProperties[i] == 0, aText); |
|
62 } |
|
63 } |
|
64 |
|
65 private: |
|
66 typedef unsigned long property_set_type; |
|
67 public: |
|
68 // number of bits in |property_set_type|. |
|
69 static const size_t kBitsInChunk = sizeof(property_set_type)*CHAR_BIT; |
|
70 // number of |property_set_type|s in the set |
|
71 static const size_t kChunkCount = |
|
72 (eCSSProperty_COUNT_no_shorthands + kBitsInChunk - 1) / kBitsInChunk; |
|
73 |
|
74 /* |
|
75 * For fast enumeration of all the bits that are set, callers can |
|
76 * check each chunk against zero (since in normal cases few bits are |
|
77 * likely to be set). |
|
78 */ |
|
79 bool HasPropertyInChunk(size_t aChunk) const { |
|
80 return mProperties[aChunk] != 0; |
|
81 } |
|
82 bool HasPropertyAt(size_t aChunk, size_t aBit) const { |
|
83 return (mProperties[aChunk] & (property_set_type(1) << aBit)) != 0; |
|
84 } |
|
85 static nsCSSProperty CSSPropertyAt(size_t aChunk, size_t aBit) { |
|
86 return nsCSSProperty(aChunk * kBitsInChunk + aBit); |
|
87 } |
|
88 |
|
89 private: |
|
90 property_set_type mProperties[kChunkCount]; |
|
91 }; |
|
92 |
|
93 #endif /* !defined(nsCSSPropertySet_h__) */ |