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/. */
7 #ifndef mozilla_BitSet_h
8 #define mozilla_BitSet_h
10 #include "mozilla/Array.h"
11 #include "mozilla/PodOperations.h"
12 #include "mozilla/Span.h"
17 * An object like std::bitset but which provides access to the underlying
20 * The limited API is due to expedience only; feel free to flesh out any
21 * std::bitset-like members.
23 template <size_t N
, typename Word
= size_t>
25 static_assert(std::is_unsigned_v
<Word
>,
26 "The Word type must be an unsigned integral type");
29 static constexpr size_t kBitsPerWord
= 8 * sizeof(Word
);
30 static constexpr size_t kNumWords
= (N
+ kBitsPerWord
- 1) / kBitsPerWord
;
32 // The zeroth bit in the bitset is the least significant bit of mStorage[0].
33 Array
<Word
, kNumWords
> mStorage
;
38 Reference(BitSet
<N
, Word
>& aBitSet
, size_t aPos
)
39 : mBitSet(aBitSet
), mPos(aPos
) {}
41 Reference
& operator=(bool aValue
) {
42 auto bit
= Word(1) << (mPos
% kBitsPerWord
);
43 auto& word
= mBitSet
.mStorage
[mPos
/ kBitsPerWord
];
44 word
= (word
& ~bit
) | (aValue
? bit
: 0);
48 MOZ_IMPLICIT
operator bool() const { return mBitSet
.Test(mPos
); }
51 BitSet
<N
, Word
>& mBitSet
;
55 BitSet() { ResetAll(); }
57 BitSet(const BitSet
& aOther
) { *this = aOther
; }
59 BitSet
& operator=(const BitSet
& aOther
) {
60 PodCopy(mStorage
.begin(), aOther
.mStorage
.begin(), kNumWords
);
64 explicit BitSet(Span
<Word
, kNumWords
> aStorage
) {
65 PodCopy(mStorage
.begin(), aStorage
.Elements(), kNumWords
);
68 constexpr size_t Size() const { return N
; }
70 constexpr bool Test(size_t aPos
) const {
72 return mStorage
[aPos
/ kBitsPerWord
] & (Word(1) << (aPos
% kBitsPerWord
));
75 constexpr bool operator[](size_t aPos
) const { return Test(aPos
); }
77 Reference
operator[](size_t aPos
) {
82 BitSet
operator|(const BitSet
<N
, Word
>& aOther
) {
83 BitSet result
= *this;
88 BitSet
& operator|=(const BitSet
<N
, Word
>& aOther
) {
89 for (size_t i
= 0; i
< ArrayLength(mStorage
); i
++) {
90 mStorage
[i
] |= aOther
.mStorage
[i
];
95 // Set all bits to false.
96 void ResetAll() { PodArrayZero(mStorage
); }
98 // Set all bits to true.
100 memset(mStorage
.begin(), 0xff, kNumWords
* sizeof(Word
));
101 constexpr size_t paddingBits
= (kNumWords
* kBitsPerWord
) - N
;
102 constexpr Word paddingMask
= Word(-1) >> paddingBits
;
103 if constexpr (paddingBits
!= 0) {
104 mStorage
[kNumWords
- 1] &= paddingMask
;
108 Span
<Word
> Storage() { return mStorage
; }
110 Span
<const Word
> Storage() const { return mStorage
; }
113 } // namespace mozilla
115 #endif // mozilla_BitSet_h