nsCSSPropertyIDSet.h 3.4 KB

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