Line data Source code
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 : #include "mozilla/PodOperations.h"
12 :
13 : #include "nsCSSPropertyID.h"
14 : #include <limits.h> // for CHAR_BIT
15 :
16 : /**
17 : * nsCSSPropertyIDSet maintains a set of non-shorthand CSS properties. In
18 : * other words, for each longhand CSS property we support, it has a bit
19 : * for whether that property is in the set.
20 : */
21 : class nsCSSPropertyIDSet {
22 : public:
23 170 : nsCSSPropertyIDSet() { Empty(); }
24 : // auto-generated copy-constructor OK
25 :
26 105888 : void AssertInSetRange(nsCSSPropertyID aProperty) const {
27 105888 : NS_ASSERTION(0 <= aProperty &&
28 : aProperty < eCSSProperty_COUNT_no_shorthands,
29 : "out of bounds");
30 105888 : }
31 :
32 : // Conversion of aProperty to |size_t| after AssertInSetRange
33 : // lets the compiler generate significantly tighter code.
34 :
35 31719 : void AddProperty(nsCSSPropertyID aProperty) {
36 31719 : AssertInSetRange(aProperty);
37 31719 : size_t p = aProperty;
38 63438 : mProperties[p / kBitsInChunk] |=
39 31719 : property_set_type(1) << (p % kBitsInChunk);
40 31719 : }
41 :
42 21796 : void RemoveProperty(nsCSSPropertyID aProperty) {
43 21796 : AssertInSetRange(aProperty);
44 21796 : size_t p = aProperty;
45 43592 : mProperties[p / kBitsInChunk] &=
46 21796 : ~(property_set_type(1) << (p % kBitsInChunk));
47 21796 : }
48 :
49 52373 : bool HasProperty(nsCSSPropertyID aProperty) const {
50 52373 : AssertInSetRange(aProperty);
51 52373 : size_t p = aProperty;
52 52373 : return (mProperties[p / kBitsInChunk] &
53 52373 : (property_set_type(1) << (p % kBitsInChunk))) != 0;
54 : }
55 :
56 6422 : void Empty() {
57 6422 : memset(mProperties, 0, sizeof(mProperties));
58 6422 : }
59 :
60 42270 : void AssertIsEmpty(const char* aText) const {
61 295890 : for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) {
62 253620 : NS_ASSERTION(mProperties[i] == 0, aText);
63 : }
64 42270 : }
65 :
66 0 : bool Equals(const nsCSSPropertyIDSet& aOther) const {
67 0 : return mozilla::PodEqual(mProperties, aOther.mProperties);
68 : }
69 :
70 : // Return a new nsCSSPropertyIDSet which is the inverse of this set.
71 0 : nsCSSPropertyIDSet Inverse() const {
72 0 : nsCSSPropertyIDSet result;
73 0 : for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) {
74 0 : result.mProperties[i] = ~mProperties[i];
75 : }
76 0 : return result;
77 : }
78 :
79 : private:
80 : typedef unsigned long property_set_type;
81 : public:
82 : // number of bits in |property_set_type|.
83 : static const size_t kBitsInChunk = sizeof(property_set_type)*CHAR_BIT;
84 : // number of |property_set_type|s in the set
85 : static const size_t kChunkCount =
86 : (eCSSProperty_COUNT_no_shorthands + kBitsInChunk - 1) / kBitsInChunk;
87 :
88 : /*
89 : * For fast enumeration of all the bits that are set, callers can
90 : * check each chunk against zero (since in normal cases few bits are
91 : * likely to be set).
92 : */
93 37416 : bool HasPropertyInChunk(size_t aChunk) const {
94 37416 : return mProperties[aChunk] != 0;
95 : }
96 609798 : bool HasPropertyAt(size_t aChunk, size_t aBit) const {
97 609798 : return (mProperties[aChunk] & (property_set_type(1) << aBit)) != 0;
98 : }
99 12934 : static nsCSSPropertyID CSSPropertyAt(size_t aChunk, size_t aBit) {
100 12934 : return nsCSSPropertyID(aChunk * kBitsInChunk + aBit);
101 : }
102 :
103 : private:
104 : property_set_type mProperties[kChunkCount];
105 : };
106 :
107 : #endif /* !defined(nsCSSPropertyIDSet_h__) */
|