michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* bit vectors for sets of CSS properties */ michael@0: michael@0: #ifndef nsCSSPropertySet_h__ michael@0: #define nsCSSPropertySet_h__ michael@0: michael@0: #include "mozilla/ArrayUtils.h" michael@0: michael@0: #include "nsCSSProperty.h" michael@0: #include // for CHAR_BIT michael@0: michael@0: /** michael@0: * nsCSSPropertySet maintains a set of non-shorthand CSS properties. In michael@0: * other words, for each longhand CSS property we support, it has a bit michael@0: * for whether that property is in the set. michael@0: */ michael@0: class nsCSSPropertySet { michael@0: public: michael@0: nsCSSPropertySet() { Empty(); } michael@0: // auto-generated copy-constructor OK michael@0: michael@0: void AssertInSetRange(nsCSSProperty aProperty) const { michael@0: NS_ASSERTION(0 <= aProperty && michael@0: aProperty < eCSSProperty_COUNT_no_shorthands, michael@0: "out of bounds"); michael@0: } michael@0: michael@0: // Conversion of aProperty to |size_t| after AssertInSetRange michael@0: // lets the compiler generate significantly tighter code. michael@0: michael@0: void AddProperty(nsCSSProperty aProperty) { michael@0: AssertInSetRange(aProperty); michael@0: size_t p = aProperty; michael@0: mProperties[p / kBitsInChunk] |= michael@0: property_set_type(1) << (p % kBitsInChunk); michael@0: } michael@0: michael@0: void RemoveProperty(nsCSSProperty aProperty) { michael@0: AssertInSetRange(aProperty); michael@0: size_t p = aProperty; michael@0: mProperties[p / kBitsInChunk] &= michael@0: ~(property_set_type(1) << (p % kBitsInChunk)); michael@0: } michael@0: michael@0: bool HasProperty(nsCSSProperty aProperty) const { michael@0: AssertInSetRange(aProperty); michael@0: size_t p = aProperty; michael@0: return (mProperties[p / kBitsInChunk] & michael@0: (property_set_type(1) << (p % kBitsInChunk))) != 0; michael@0: } michael@0: michael@0: void Empty() { michael@0: memset(mProperties, 0, sizeof(mProperties)); michael@0: } michael@0: michael@0: void AssertIsEmpty(const char* aText) const { michael@0: for (size_t i = 0; i < mozilla::ArrayLength(mProperties); ++i) { michael@0: NS_ASSERTION(mProperties[i] == 0, aText); michael@0: } michael@0: } michael@0: michael@0: private: michael@0: typedef unsigned long property_set_type; michael@0: public: michael@0: // number of bits in |property_set_type|. michael@0: static const size_t kBitsInChunk = sizeof(property_set_type)*CHAR_BIT; michael@0: // number of |property_set_type|s in the set michael@0: static const size_t kChunkCount = michael@0: (eCSSProperty_COUNT_no_shorthands + kBitsInChunk - 1) / kBitsInChunk; michael@0: michael@0: /* michael@0: * For fast enumeration of all the bits that are set, callers can michael@0: * check each chunk against zero (since in normal cases few bits are michael@0: * likely to be set). michael@0: */ michael@0: bool HasPropertyInChunk(size_t aChunk) const { michael@0: return mProperties[aChunk] != 0; michael@0: } michael@0: bool HasPropertyAt(size_t aChunk, size_t aBit) const { michael@0: return (mProperties[aChunk] & (property_set_type(1) << aBit)) != 0; michael@0: } michael@0: static nsCSSProperty CSSPropertyAt(size_t aChunk, size_t aBit) { michael@0: return nsCSSProperty(aChunk * kBitsInChunk + aBit); michael@0: } michael@0: michael@0: private: michael@0: property_set_type mProperties[kChunkCount]; michael@0: }; michael@0: michael@0: #endif /* !defined(nsCSSPropertySet_h__) */