Coverage Report

Created: 2018-09-25 14:53

/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__) */