1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
/* Functions to support fixed-length bitmaps.
Copyright (C) 2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_BBITMAP_H
#define GCC_BBITMAP_H
/* Implementation of bounded (fixed length) bitmaps.
This provides a drop-in replacement for bitmaps that have outgrown the
storage capacity of a single integer.
Sets are stored as a fixed length array of uint64_t elements. The length of
this array is given as a template parameter. */
/* Use recusive templated functions to define constexpr operations. */
template<int M>
struct bbitmap_operators
{
/* Return a result that maps binary operator OP to elements [0, M) of
X and Y, and takes the remaining elements from REST. */
template<typename Result, typename Operator, typename Arg, typename ...Rest>
static constexpr Result binary(Operator op, const Arg &x, const Arg &y,
Rest ...rest)
{
return bbitmap_operators<M - 1>::template binary<Result, Operator, Arg>
(op, x, y, op (x.val[M - 1], y.val[M - 1]), rest...);
}
/* Return a result that contains the bitwise inverse of elements [0, M) of X,
and takes the remaining elements from REST. */
template<typename Result, typename Arg, typename ...Rest>
static constexpr Result bit_not(const Arg &x, Rest ...rest)
{
return bbitmap_operators<M - 1>::template bit_not<Result, Arg>
(x, ~(x.val[M - 1]), rest...);
}
/* Return true if any element [0, M) of X is nonzero. */
template<typename Arg>
static constexpr bool non_zero(const Arg &x)
{
return (bool) x.val[M - 1]
|| bbitmap_operators<M - 1>::template non_zero<Arg> (x);
}
/* Return true if elements [0, M) of X are all equal to the corresponding
elements of Y. */
template<typename Arg>
static constexpr bool equal(const Arg &x, const Arg &y)
{
return x.val[M - 1] == y.val[M - 1]
&& bbitmap_operators<M - 1>::template equal<Arg> (x, y);
}
/* If bit index INDEX selects a bit in the first M elements, return a
Result with that bit set and the other bits of the leading M elements
clear. Clear the leading M elements otherwise. Take the remaining
elements of the Result from REST. */
template<typename Result, typename ...Rest>
static constexpr Result from_index(int index, Rest ...rest)
{
return bbitmap_operators<M - 1>::template from_index<Result>
(index,
uint64_t ((index - (M - 1) * 64) == (index & 63)) << (index & 63),
rest...);
}
};
/* These functions form the base for the recursive functions above. They
return either bitmap containing the elements passed in REST, or a default
bool result. */
template<>
struct bbitmap_operators<0>
{
template<typename Result, typename Operator, typename Arg, typename ...Rest>
static constexpr Result binary(Operator, const Arg, const Arg,
Rest ...rest)
{
return Result { rest... };
}
template<typename Result, typename Arg, typename ...Rest>
static constexpr Result bit_not(const Arg, Rest ...rest)
{
return Result { rest... };
}
template<typename Arg>
static constexpr bool non_zero(const Arg)
{
return false;
}
template<typename Arg>
static constexpr bool equal(const Arg, const Arg)
{
return true;
}
template<typename Result, typename ...Rest>
static constexpr Result from_index(int, Rest ...rest)
{
return Result { rest... };
}
};
template<typename T>
constexpr T bbitmap_element_or(T x, T y) { return x | y;}
template<typename T>
constexpr T bbitmap_element_and(T x, T y) { return x & y;}
template<typename T>
constexpr T bbitmap_element_xor(T x, T y) { return x ^ y;}
template <int N>
class GTY((user)) bbitmap
{
public:
uint64_t val[N];
template<typename... Rest>
constexpr bbitmap(Rest ...rest) : val{(uint64_t) rest...} {}
constexpr bbitmap<N> operator|(const bbitmap<N> other) const
{
return bbitmap_operators<N>::template binary<bbitmap<N>>
(bbitmap_element_or<uint64_t>, *this, other);
}
bbitmap<N> operator|=(const bbitmap<N> other)
{
for (int i = 0; i < N; i++)
val[i] |= other.val[i];
return this;
}
constexpr bbitmap<N> operator&(const bbitmap<N> other) const
{
return bbitmap_operators<N>::template binary<bbitmap<N>>
(bbitmap_element_and<uint64_t>, *this, other);
}
bbitmap<N> operator&=(const bbitmap<N> other)
{
for (int i = 0; i < N; i++)
val[i] &= other.val[i];
return this;
}
constexpr bbitmap<N> operator^(const bbitmap<N> other) const
{
return bbitmap_operators<N>::template binary<bbitmap<N>>
(bbitmap_element_xor<uint64_t>, *this, other);
}
bbitmap<N> operator^=(const bbitmap<N> other)
{
for (int i = 0; i < N; i++)
val[i] ^= other.val[i];
return this;
}
constexpr bbitmap<N> operator~() const
{
return bbitmap_operators<N>::template bit_not<bbitmap<N>>(*this);
}
constexpr bool operator!() const
{
return !(bbitmap_operators<N>::template non_zero<bbitmap<N>>(*this));
}
constexpr explicit operator bool() const
{
return bbitmap_operators<N>::template non_zero<bbitmap<N>>(*this);
}
constexpr bool operator==(const bbitmap<N> other) const
{
return bbitmap_operators<N>::template equal<bbitmap<N>>(*this, other);
}
constexpr bool operator!=(const bbitmap<N> other) const
{
return !(bbitmap_operators<N>::template equal<bbitmap<N>>(*this, other));
}
/* Return a bitmap with bit INDEX set and all other bits clear. */
static constexpr bbitmap<N> from_index (int index)
{
return bbitmap_operators<N>::template from_index<bbitmap<N>> (index);
}
};
template<int N>
void
gt_ggc_mx (bbitmap<N> *)
{
}
template<int N>
void
gt_pch_nx (bbitmap<N> *)
{
}
template<int N>
void
gt_pch_nx (bbitmap<N> *, gt_pointer_operator, void *)
{
}
#endif
|