LLVM 22.0.0git
Bitset.h
Go to the documentation of this file.
1//=== llvm/ADT/Bitset.h - constexpr std::bitset -----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Defines a std::bitset like container that can be used in constexprs.
10// That constructor and many of the methods are constexpr. std::bitset doesn't
11// get constexpr methods until C++23. This class also provides a constexpr
12// constructor that accepts an initializer_list of bits to set.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_ADT_BITSET_H
17#define LLVM_ADT_BITSET_H
18
19#include <llvm/ADT/STLExtras.h>
20#include <array>
21#include <climits>
22#include <cstdint>
23
24namespace llvm {
25
26/// This is a constexpr reimplementation of a subset of std::bitset. It would be
27/// nice to use std::bitset directly, but it doesn't support constant
28/// initialization.
29template <unsigned NumBits>
30class Bitset {
31 using BitWord = uintptr_t;
32
33 static constexpr unsigned BitwordBits = sizeof(BitWord) * CHAR_BIT;
34
35 static_assert(BitwordBits == 64 || BitwordBits == 32,
36 "Unsupported word size");
37
38 static constexpr unsigned NumWords =
39 (NumBits + BitwordBits - 1) / BitwordBits;
40
41 using StorageType = std::array<BitWord, NumWords>;
42 StorageType Bits{};
43
44protected:
45 constexpr Bitset(const std::array<uint64_t, (NumBits + 63) / 64> &B) {
46 if constexpr (sizeof(BitWord) == sizeof(uint64_t)) {
47 for (size_t I = 0; I != B.size(); ++I)
48 Bits[I] = B[I];
49 } else {
50 unsigned BitsToAssign = NumBits;
51 for (size_t I = 0; I != B.size() && BitsToAssign; ++I) {
52 uint64_t Elt = B[I];
53 // On a 32-bit system the storage type will be 32-bit, so we may only
54 // need half of a uint64_t.
55 for (size_t offset = 0; offset != 2 && BitsToAssign; ++offset) {
56 Bits[2 * I + offset] = static_cast<uint32_t>(Elt >> (32 * offset));
57 BitsToAssign = BitsToAssign >= 32 ? BitsToAssign - 32 : 0;
58 }
59 }
60 }
61 }
62
63public:
64 constexpr Bitset() = default;
65 constexpr Bitset(std::initializer_list<unsigned> Init) {
66 for (auto I : Init)
67 set(I);
68 }
69
71 llvm::fill(Bits, -BitWord(0));
72 return *this;
73 }
74
75 constexpr Bitset &set(unsigned I) {
76 Bits[I / BitwordBits] |= BitWord(1) << (I % BitwordBits);
77 return *this;
78 }
79
80 constexpr Bitset &reset(unsigned I) {
81 Bits[I / BitwordBits] &= ~(BitWord(1) << (I % BitwordBits));
82 return *this;
83 }
84
85 constexpr Bitset &flip(unsigned I) {
86 Bits[I / BitwordBits] ^= BitWord(1) << (I % BitwordBits);
87 return *this;
88 }
89
90 constexpr bool operator[](unsigned I) const {
91 BitWord Mask = BitWord(1) << (I % BitwordBits);
92 return (Bits[I / BitwordBits] & Mask) != 0;
93 }
94
95 constexpr bool test(unsigned I) const { return (*this)[I]; }
96
97 constexpr size_t size() const { return NumBits; }
98
99 bool any() const {
100 return llvm::any_of(Bits, [](BitWord I) { return I != 0; });
101 }
102 bool none() const { return !any(); }
103 size_t count() const {
104 size_t Count = 0;
105 for (auto B : Bits)
107 return Count;
108 }
109
110 constexpr Bitset &operator^=(const Bitset &RHS) {
111 for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
112 Bits[I] ^= RHS.Bits[I];
113 }
114 return *this;
115 }
116 constexpr Bitset operator^(const Bitset &RHS) const {
117 Bitset Result = *this;
118 Result ^= RHS;
119 return Result;
120 }
121
122 constexpr Bitset &operator&=(const Bitset &RHS) {
123 for (unsigned I = 0, E = Bits.size(); I != E; ++I)
124 Bits[I] &= RHS.Bits[I];
125 return *this;
126 }
127 constexpr Bitset operator&(const Bitset &RHS) const {
128 Bitset Result = *this;
129 Result &= RHS;
130 return Result;
131 }
132
133 constexpr Bitset &operator|=(const Bitset &RHS) {
134 for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
135 Bits[I] |= RHS.Bits[I];
136 }
137 return *this;
138 }
139 constexpr Bitset operator|(const Bitset &RHS) const {
140 Bitset Result = *this;
141 Result |= RHS;
142 return Result;
143 }
144
145 constexpr Bitset operator~() const {
146 Bitset Result = *this;
147 for (auto &B : Result.Bits)
148 B = ~B;
149 return Result;
150 }
151
152 bool operator==(const Bitset &RHS) const {
153 return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits));
154 }
155
156 bool operator!=(const Bitset &RHS) const { return !(*this == RHS); }
157
158 bool operator < (const Bitset &Other) const {
159 for (unsigned I = 0, E = size(); I != E; ++I) {
160 bool LHS = test(I), RHS = Other.test(I);
161 if (LHS != RHS)
162 return LHS < RHS;
163 }
164 return false;
165 }
166};
167
168} // end namespace llvm
169
170#endif
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define I(x, y, z)
Definition MD5.cpp:58
modulo schedule test
This file contains some templates that are useful if you are working with the STL at all.
Value * RHS
Value * LHS
constexpr Bitset operator^(const Bitset &RHS) const
Definition Bitset.h:116
constexpr Bitset & set(unsigned I)
Definition Bitset.h:75
constexpr Bitset & flip(unsigned I)
Definition Bitset.h:85
bool operator<(const Bitset &Other) const
Definition Bitset.h:158
bool operator!=(const Bitset &RHS) const
Definition Bitset.h:156
constexpr Bitset(const std::array< uint64_t,(NumBits+63)/64 > &B)
Definition Bitset.h:45
constexpr Bitset()=default
constexpr Bitset & operator^=(const Bitset &RHS)
Definition Bitset.h:110
constexpr Bitset operator&(const Bitset &RHS) const
Definition Bitset.h:127
constexpr bool operator[](unsigned I) const
Definition Bitset.h:90
constexpr size_t size() const
Definition Bitset.h:97
size_t count() const
Definition Bitset.h:103
Bitset & set()
Definition Bitset.h:70
bool any() const
Definition Bitset.h:99
constexpr Bitset & operator|=(const Bitset &RHS)
Definition Bitset.h:133
bool operator==(const Bitset &RHS) const
Definition Bitset.h:152
constexpr Bitset(std::initializer_list< unsigned > Init)
Definition Bitset.h:65
constexpr Bitset & operator&=(const Bitset &RHS)
Definition Bitset.h:122
constexpr bool test(unsigned I) const
Definition Bitset.h:95
constexpr Bitset operator|(const Bitset &RHS) const
Definition Bitset.h:139
constexpr Bitset & reset(unsigned I)
Definition Bitset.h:80
bool none() const
Definition Bitset.h:102
constexpr Bitset operator~() const
Definition Bitset.h:145
This is an optimization pass for GlobalISel generic memory operations.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1745
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1732
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
@ Other
Any other memory.
Definition ModRef.h:68
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:154