/src/mozilla-central/layout/style/nsCSSPropertyIDSet.h
Line | Count | Source (jump to first uncovered line) |
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 nsCSSPropertyIDSet_h__ |
8 | | #define nsCSSPropertyIDSet_h__ |
9 | | |
10 | | #include "mozilla/ArrayUtils.h" |
11 | | |
12 | | #include "nsCSSPropertyID.h" |
13 | | #include <limits.h> // for CHAR_BIT |
14 | | |
15 | | /** |
16 | | * nsCSSPropertyIDSet 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 nsCSSPropertyIDSet { |
21 | | public: |
22 | 0 | nsCSSPropertyIDSet() { Empty(); } |
23 | | // auto-generated copy-constructor OK |
24 | | |
25 | 0 | void AssertInSetRange(nsCSSPropertyID aProperty) const { |
26 | 0 | NS_ASSERTION(0 <= aProperty && |
27 | 0 | aProperty < eCSSProperty_COUNT_no_shorthands, |
28 | 0 | "out of bounds"); |
29 | 0 | } |
30 | | |
31 | | // Conversion of aProperty to |size_t| after AssertInSetRange |
32 | | // lets the compiler generate significantly tighter code. |
33 | | |
34 | 0 | void AddProperty(nsCSSPropertyID aProperty) { |
35 | 0 | AssertInSetRange(aProperty); |
36 | 0 | size_t p = aProperty; |
37 | 0 | mProperties[p / kBitsInChunk] |= |
38 | 0 | property_set_type(1) << (p % kBitsInChunk); |
39 | 0 | } |
40 | | |
41 | | void RemoveProperty(nsCSSPropertyID aProperty) { |
42 | | AssertInSetRange(aProperty); |
43 | | size_t p = aProperty; |
44 | | mProperties[p / kBitsInChunk] &= |
45 | | ~(property_set_type(1) << (p % kBitsInChunk)); |
46 | | } |
47 | | |
48 | 0 | bool HasProperty(nsCSSPropertyID aProperty) const { |
49 | 0 | AssertInSetRange(aProperty); |
50 | 0 | size_t p = aProperty; |
51 | 0 | return (mProperties[p / kBitsInChunk] & |
52 | 0 | (property_set_type(1) << (p % kBitsInChunk))) != 0; |
53 | 0 | } |
54 | | |
55 | 0 | void Empty() { |
56 | 0 | memset(mProperties, 0, sizeof(mProperties)); |
57 | 0 | } |
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 | 0 | bool Equals(const nsCSSPropertyIDSet& aOther) const { |
66 | 0 | return mozilla::ArrayEqual(mProperties, aOther.mProperties); |
67 | 0 | } |
68 | | |
69 | 0 | bool IsEmpty() const { |
70 | 0 | for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) { |
71 | 0 | if (mProperties[i] != 0) { |
72 | 0 | return false; |
73 | 0 | } |
74 | 0 | } |
75 | 0 | return true; |
76 | 0 | } |
77 | | |
78 | | // Return a new nsCSSPropertyIDSet which is the inverse of this set. |
79 | 0 | nsCSSPropertyIDSet Inverse() const { |
80 | 0 | nsCSSPropertyIDSet result; |
81 | 0 | for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) { |
82 | 0 | result.mProperties[i] = ~mProperties[i]; |
83 | 0 | } |
84 | 0 | return result; |
85 | 0 | } |
86 | | |
87 | | // Returns a new nsCSSPropertyIDSet with all properties that are both in |
88 | | // this set and |aOther|. |
89 | 0 | nsCSSPropertyIDSet Intersect(const nsCSSPropertyIDSet& aOther) const { |
90 | 0 | nsCSSPropertyIDSet result; |
91 | 0 | for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) { |
92 | 0 | result.mProperties[i] = mProperties[i] & aOther.mProperties[i]; |
93 | 0 | } |
94 | 0 | return result; |
95 | 0 | } |
96 | | |
97 | | // Return a new nsCSSPropertyIDSet with all properties that are in either |
98 | | // this set or |aOther| but not both. |
99 | 0 | nsCSSPropertyIDSet Xor(const nsCSSPropertyIDSet& aOther) const { |
100 | 0 | nsCSSPropertyIDSet result; |
101 | 0 | for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) { |
102 | 0 | result.mProperties[i] = mProperties[i] ^ aOther.mProperties[i]; |
103 | 0 | } |
104 | 0 | return result; |
105 | 0 | } |
106 | | |
107 | | private: |
108 | | typedef unsigned long property_set_type; |
109 | | public: |
110 | | // number of bits in |property_set_type|. |
111 | | static const size_t kBitsInChunk = sizeof(property_set_type)*CHAR_BIT; |
112 | | // number of |property_set_type|s in the set |
113 | | static const size_t kChunkCount = |
114 | | (eCSSProperty_COUNT_no_shorthands + kBitsInChunk - 1) / kBitsInChunk; |
115 | | |
116 | | /* |
117 | | * For fast enumeration of all the bits that are set, callers can |
118 | | * check each chunk against zero (since in normal cases few bits are |
119 | | * likely to be set). |
120 | | */ |
121 | | bool HasPropertyInChunk(size_t aChunk) const { |
122 | | return mProperties[aChunk] != 0; |
123 | | } |
124 | | bool HasPropertyAt(size_t aChunk, size_t aBit) const { |
125 | | return (mProperties[aChunk] & (property_set_type(1) << aBit)) != 0; |
126 | | } |
127 | | static nsCSSPropertyID CSSPropertyAt(size_t aChunk, size_t aBit) { |
128 | | return nsCSSPropertyID(aChunk * kBitsInChunk + aBit); |
129 | | } |
130 | | |
131 | | private: |
132 | | property_set_type mProperties[kChunkCount]; |
133 | | }; |
134 | | |
135 | | #endif /* !defined(nsCSSPropertyIDSet_h__) */ |