1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "mozilla/MathAlgorithms.h"
11 #include "mozilla/TemplateLib.h"
22 template <typename WordT
>
23 inline uint_fast8_t CountTrailingZeroes(WordT word
);
26 inline uint_fast8_t CountTrailingZeroes(uint32_t word
) {
27 return mozilla::CountTrailingZeroes32(word
);
31 inline uint_fast8_t CountTrailingZeroes(uint64_t word
) {
32 return mozilla::CountTrailingZeroes64(word
);
37 template <size_t nbits
>
40 // Use a 32 bit word to make it easier to access a BitArray from JIT code.
41 using WordT
= uint32_t;
43 static const size_t bitsPerElement
= sizeof(WordT
) * CHAR_BIT
;
44 static const size_t numSlots
=
45 nbits
/ bitsPerElement
+ (nbits
% bitsPerElement
== 0 ? 0 : 1);
48 static const size_t paddingBits
= (numSlots
* bitsPerElement
) - nbits
;
49 static_assert(paddingBits
< bitsPerElement
,
50 "More padding bits than expected.");
51 static const WordT paddingMask
= WordT(-1) >> paddingBits
;
56 constexpr BitArray() : map() {};
58 void clear(bool value
) {
59 memset(map
, value
? 0xFF : 0, sizeof(map
));
61 map
[numSlots
- 1] &= paddingMask
;
65 inline bool get(size_t offset
) const {
68 getIndexAndMask(offset
, &index
, &mask
);
69 MOZ_ASSERT(index
< nbits
);
70 return map
[index
] & mask
;
73 void set(size_t offset
) {
76 getIndexAndMask(offset
, &index
, &mask
);
80 void unset(size_t offset
) {
83 getIndexAndMask(offset
, &index
, &mask
);
87 bool isAllClear() const {
88 for (size_t i
= 0; i
< numSlots
; i
++) {
96 // For iterating over the set bits in the bit array, get a word at a time.
97 WordT
getWord(size_t elementIndex
) const {
98 MOZ_ASSERT(elementIndex
< nbits
);
99 return map
[elementIndex
];
102 // Update a word at a time.
103 void setWord(size_t elementIndex
, WordT value
) {
104 MOZ_ASSERT(elementIndex
< nbits
);
105 map
[elementIndex
] = value
;
108 static void getIndexAndMask(size_t offset
, size_t* indexp
, WordT
* maskp
) {
109 MOZ_ASSERT(offset
< nbits
);
110 static_assert(bitsPerElement
== 32, "unexpected bitsPerElement value");
111 *indexp
= offset
/ bitsPerElement
;
112 *maskp
= WordT(1) << (offset
% bitsPerElement
);
115 static size_t offsetOfMap() { return offsetof(BitArray
<nbits
>, map
); }
120 #endif /* ds_BitArray_h */