]> git.saurik.com Git - bison.git/blame - lib/bitset.h
doc: merge HACKING and README-hacking.
[bison.git] / lib / bitset.h
CommitLineData
7086e707 1/* Generic bitsets.
7d7d6663 2 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
7086e707
AD
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
f16b0819
PE
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
7086e707
AD
17
18#ifndef _BITSET_H
04af9e52 19#define _BITSET_H
7086e707 20
ef017502
AD
21/* This file is the public interface to the bitset abstract data type.
22 Only use the functions and macros defined in this file. */
7086e707 23
ef017502 24#include "bbitset.h"
7086e707
AD
25#include "obstack.h"
26#include <stdio.h>
7086e707 27
fb9c0b33
PE
28#if USE_UNLOCKED_IO
29# include "unlocked-io.h"
30#endif
31
ef017502 32/* Attributes used to select a bitset implementation. */
7086e707
AD
33enum bitset_attr {BITSET_FIXED = 1, /* Bitset size fixed. */
34 BITSET_VARIABLE = 2, /* Bitset size variable. */
35 BITSET_DENSE = 4, /* Bitset dense. */
36 BITSET_SPARSE = 8, /* Bitset sparse. */
37 BITSET_FRUGAL = 16, /* Prefer most compact. */
6aa452a6 38 BITSET_GREEDY = 32}; /* Prefer fastest at memory expense. */
7086e707
AD
39
40typedef unsigned int bitset_attrs;
41
47c8386f
PE
42/* The contents of the union should be considered to be private.
43 While I would like to make this union opaque, it needs to be
44 visible for the inline bit set/test functions, and for delegation
45 to the proper implementation. */
46union bitset_union
7086e707 47{
47c8386f
PE
48 /* This must be the first member of every other structure that is a
49 member of this union. */
144c1e76 50 struct bbitset_struct b; /* Base bitset data. */
47c8386f
PE
51
52 struct abitset_struct
53 {
54 struct bbitset_struct b;
47c8386f
PE
55 bitset_word words[1]; /* The array of bits. */
56 } a;
57
58 struct ebitset_struct
59 {
60 struct bbitset_struct b;
61 bitset_windex size; /* Number of elements. */
62 struct ebitset_elt_struct **elts; /* Expanding array of ptrs to elts. */
63 } e;
64
65 struct lbitset_struct
66 {
67 struct bbitset_struct b;
68 struct lbitset_elt_struct *head; /* First element in linked list. */
69 struct lbitset_elt_struct *tail; /* Last element in linked list. */
70 } l;
71
72 struct bitset_stats_struct
73 {
74 struct bbitset_struct b;
75 bitset bset;
76 } s;
144c1e76
PE
77
78 struct vbitset_struct
79 {
80 struct bbitset_struct b;
81 bitset_windex size; /* Allocated size of array. */
82 } v;
83
7086e707
AD
84};
85
613f5e1a
AD
86
87/* The contents of this structure should be considered private.
88 It is used for iterating over set bits. */
89typedef struct
90{
91 bitset_bindex list[BITSET_LIST_SIZE];
92 bitset_bindex next;
808a5918
PE
93 bitset_bindex num;
94 bitset_bindex i;
613f5e1a
AD
95} bitset_iterator;
96
97
7086e707 98/* Return bytes required for bitset of desired type and size. */
7d7d6663 99extern size_t bitset_bytes (enum bitset_type, bitset_bindex);
7086e707
AD
100
101/* Initialise a bitset with desired type and size. */
7d7d6663 102extern bitset bitset_init (bitset, bitset_bindex, enum bitset_type);
7086e707 103
ef017502
AD
104/* Select an implementation type based on the desired bitset size
105 and attributes. */
7d7d6663 106extern enum bitset_type bitset_type_choose (bitset_bindex, bitset_attrs);
7086e707 107
ef017502 108/* Create a bitset of desired type and size. The bitset is zeroed. */
7d7d6663 109extern bitset bitset_alloc (bitset_bindex, enum bitset_type);
7086e707
AD
110
111/* Free bitset. */
7d7d6663 112extern void bitset_free (bitset);
7086e707 113
ef017502
AD
114/* Create a bitset of desired type and size using an obstack. The
115 bitset is zeroed. */
7d7d6663
PE
116extern bitset bitset_obstack_alloc (struct obstack *bobstack,
117 bitset_bindex, enum bitset_type);
7086e707
AD
118
119/* Free bitset allocated on obstack. */
7d7d6663 120extern void bitset_obstack_free (bitset);
7086e707 121
ef017502 122/* Create a bitset of desired size and attributes. The bitset is zeroed. */
7d7d6663 123extern bitset bitset_create (bitset_bindex, bitset_attrs);
7086e707 124
613f5e1a 125/* Return bitset type. */
7d7d6663 126extern enum bitset_type bitset_type_get (bitset);
613f5e1a 127
6aa452a6 128/* Return bitset type name. */
7d7d6663 129extern const char *bitset_type_name_get (bitset);
6aa452a6 130
7086e707
AD
131
132/* Set bit BITNO in bitset BSET. */
04af9e52
PE
133static inline void
134bitset_set (bitset bset, bitset_bindex bitno)
7086e707 135{
dbba6a3b
PE
136 bitset_windex windex = bitno / BITSET_WORD_BITS;
137 bitset_windex offset = windex - bset->b.cindex;
04af9e52 138
ef017502 139 if (offset < bset->b.csize)
e601ff27 140 bset->b.cdata[offset] |= ((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
7086e707 141 else
ef017502 142 BITSET_SET_ (bset, bitno);
7086e707
AD
143}
144
145
146/* Reset bit BITNO in bitset BSET. */
04af9e52
PE
147static inline void
148bitset_reset (bitset bset, bitset_bindex bitno)
7086e707 149{
dbba6a3b
PE
150 bitset_windex windex = bitno / BITSET_WORD_BITS;
151 bitset_windex offset = windex - bset->b.cindex;
04af9e52 152
ef017502 153 if (offset < bset->b.csize)
e601ff27 154 bset->b.cdata[offset] &= ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
7086e707 155 else
ef017502 156 BITSET_RESET_ (bset, bitno);
7086e707
AD
157}
158
159
160/* Test bit BITNO in bitset BSET. */
d0829076 161static inline bool
04af9e52 162bitset_test (bitset bset, bitset_bindex bitno)
7086e707 163{
dbba6a3b
PE
164 bitset_windex windex = bitno / BITSET_WORD_BITS;
165 bitset_windex offset = windex - bset->b.cindex;
04af9e52 166
ef017502
AD
167 if (offset < bset->b.csize)
168 return (bset->b.cdata[offset] >> (bitno % BITSET_WORD_BITS)) & 1;
7086e707 169 else
ef017502 170 return BITSET_TEST_ (bset, bitno);
7086e707 171}
7086e707 172
7086e707 173
345cea78 174/* Toggle bit BITNO in bitset BSET and return non-zero if now set. */
6aa452a6 175#define bitset_toggle(bset, bitno) BITSET_TOGGLE_ (bset, bitno)
345cea78 176
6aa452a6
AD
177/* Return size in bits of bitset SRC. */
178#define bitset_size(SRC) BITSET_SIZE_ (SRC)
179
144c1e76 180/* Change size of bitset. */
7d7d6663 181extern void bitset_resize (bitset, bitset_bindex);
144c1e76 182
6aa452a6
AD
183/* Return number of bits set in bitset SRC. */
184#define bitset_count(SRC) BITSET_COUNT_ (SRC)
185
186
187/* Return SRC == 0. */
188#define bitset_empty_p(SRC) BITSET_EMPTY_P_ (SRC)
7086e707
AD
189
190/* DST = ~0. */
6aa452a6 191#define bitset_ones(DST) BITSET_ONES_ (DST)
7086e707 192
6aa452a6
AD
193/* DST = 0. */
194#define bitset_zero(DST) BITSET_ZERO_ (DST)
7086e707 195
7086e707 196
6aa452a6
AD
197
198/* DST = SRC. */
199#define bitset_copy(DST, SRC) BITSET_COPY_ (DST, SRC)
7086e707 200
ef017502 201/* Return DST & SRC == 0. */
6aa452a6 202#define bitset_disjoint_p(DST, SRC) BITSET_DISJOINT_P_ (DST, SRC)
ef017502 203
6aa452a6
AD
204/* Return DST == SRC. */
205#define bitset_equal_p(DST, SRC) BITSET_EQUAL_P_ (DST, SRC)
7086e707
AD
206
207/* DST = ~SRC. */
6aa452a6
AD
208#define bitset_not(DST, SRC) BITSET_NOT_ (DST, SRC)
209
210/* Return DST == DST | SRC. */
211#define bitset_subset_p(DST, SRC) BITSET_SUBSET_P_ (DST, SRC)
7086e707 212
6aa452a6
AD
213
214
215/* DST = SRC1 & SRC2. */
216#define bitset_and(DST, SRC1, SRC2) BITSET_AND_ (DST, SRC1, SRC2)
7086e707
AD
217
218/* DST = SRC1 & SRC2. Return non-zero if DST != SRC1 & SRC2. */
6aa452a6 219#define bitset_and_cmp(DST, SRC1, SRC2) BITSET_AND_CMP_ (DST, SRC1, SRC2)
7086e707 220
6aa452a6
AD
221/* DST = SRC1 & ~SRC2. */
222#define bitset_andn(DST, SRC1, SRC2) BITSET_ANDN_ (DST, SRC1, SRC2)
7086e707
AD
223
224/* DST = SRC1 & ~SRC2. Return non-zero if DST != SRC1 & ~SRC2. */
6aa452a6 225#define bitset_andn_cmp(DST, SRC1, SRC2) BITSET_ANDN_CMP_ (DST, SRC1, SRC2)
7086e707 226
6aa452a6
AD
227/* DST = SRC1 | SRC2. */
228#define bitset_or(DST, SRC1, SRC2) BITSET_OR_ (DST, SRC1, SRC2)
229
230/* DST = SRC1 | SRC2. Return non-zero if DST != SRC1 | SRC2. */
231#define bitset_or_cmp(DST, SRC1, SRC2) BITSET_OR_CMP_ (DST, SRC1, SRC2)
232
233/* DST = SRC1 ^ SRC2. */
234#define bitset_xor(DST, SRC1, SRC2) BITSET_XOR_ (DST, SRC1, SRC2)
235
236/* DST = SRC1 ^ SRC2. Return non-zero if DST != SRC1 ^ SRC2. */
237#define bitset_xor_cmp(DST, SRC1, SRC2) BITSET_XOR_CMP_ (DST, SRC1, SRC2)
238
239
240
241/* DST = (SRC1 & SRC2) | SRC3. */
242#define bitset_and_or(DST, SRC1, SRC2, SRC3) \
243 BITSET_AND_OR_ (DST, SRC1, SRC2, SRC3)
7086e707
AD
244
245/* DST = (SRC1 & SRC2) | SRC3. Return non-zero if
246 DST != (SRC1 & SRC2) | SRC3. */
6aa452a6
AD
247#define bitset_and_or_cmp(DST, SRC1, SRC2, SRC3) \
248 BITSET_AND_OR_CMP_ (DST, SRC1, SRC2, SRC3)
249
250/* DST = (SRC1 & ~SRC2) | SRC3. */
251#define bitset_andn_or(DST, SRC1, SRC2, SRC3) \
252 BITSET_ANDN_OR_ (DST, SRC1, SRC2, SRC3)
7086e707
AD
253
254/* DST = (SRC1 & ~SRC2) | SRC3. Return non-zero if
255 DST != (SRC1 & ~SRC2) | SRC3. */
6aa452a6
AD
256#define bitset_andn_or_cmp(DST, SRC1, SRC2, SRC3) \
257 BITSET_ANDN_OR_CMP_ (DST, SRC1, SRC2, SRC3)
7086e707 258
6aa452a6
AD
259/* DST = (SRC1 | SRC2) & SRC3. */
260#define bitset_or_and(DST, SRC1, SRC2, SRC3)\
261 BITSET_OR_AND_ (DST, SRC1, SRC2, SRC3)
7086e707 262
6aa452a6
AD
263/* DST = (SRC1 | SRC2) & SRC3. Return non-zero if
264 DST != (SRC1 | SRC2) & SRC3. */
265#define bitset_or_and_cmp(DST, SRC1, SRC2, SRC3)\
266 BITSET_OR_AND_CMP_ (DST, SRC1, SRC2, SRC3)
345cea78 267
04af9e52 268/* Find list of up to NUM bits set in BSET starting from and including
7086e707
AD
269 *NEXT. Return with actual number of bits found and with *NEXT
270 indicating where search stopped. */
7086e707 271#define bitset_list(BSET, LIST, NUM, NEXT) \
04af9e52 272 BITSET_LIST_ (BSET, LIST, NUM, NEXT)
7086e707
AD
273
274/* Find reverse list of up to NUM bits set in BSET starting from and
275 including NEXT. Return with actual number of bits found and with
276 *NEXT indicating where search stopped. */
6aa452a6 277#define bitset_list_reverse(BSET, LIST, NUM, NEXT) \
04af9e52 278 BITSET_LIST_REVERSE_ (BSET, LIST, NUM, NEXT)
6aa452a6 279
144c1e76 280/* Return true if both bitsets are of the same type and size. */
fa8db4ba 281extern bool bitset_compatible_p (bitset bset1, bitset bset2);
7086e707 282
144c1e76 283/* Find next set bit from the given bit index. */
7d7d6663 284extern bitset_bindex bitset_next (bitset, bitset_bindex);
47c8386f 285
144c1e76 286/* Find previous set bit from the given bit index. */
7d7d6663 287extern bitset_bindex bitset_prev (bitset, bitset_bindex);
47c8386f 288
7086e707 289/* Find first set bit. */
7d7d6663 290extern bitset_bindex bitset_first (bitset);
7086e707
AD
291
292/* Find last set bit. */
7d7d6663 293extern bitset_bindex bitset_last (bitset);
7086e707 294
47c8386f 295/* Return nonzero if this is the only set bit. */
7d7d6663 296extern bool bitset_only_set_p (bitset, bitset_bindex);
47c8386f 297
7086e707 298/* Dump bitset. */
7d7d6663 299extern void bitset_dump (FILE *, bitset);
7086e707 300
144c1e76 301/* Loop over all elements of BSET, starting with MIN, setting INDEX
6aa452a6
AD
302 to the index of each set bit. For example, the following will print
303 the bits set in a bitset:
304
fa8db4ba 305 bitset_bindex i;
6aa452a6
AD
306 bitset_iterator iter;
307
fa8db4ba 308 BITSET_FOR_EACH (iter, src, i, 0)
6aa452a6 309 {
fa8db4ba 310 printf ("%lu ", (unsigned long int) i);
6aa452a6
AD
311 };
312*/
144c1e76 313#define BITSET_FOR_EACH(ITER, BSET, INDEX, MIN) \
613f5e1a 314 for (ITER.next = (MIN), ITER.num = BITSET_LIST_SIZE; \
04098407
PE
315 (ITER.num == BITSET_LIST_SIZE) \
316 && (ITER.num = bitset_list (BSET, ITER.list, \
04af9e52 317 BITSET_LIST_SIZE, &ITER.next));) \
2175bfbd 318 for (ITER.i = 0; \
144c1e76 319 ITER.i < ITER.num && ((INDEX) = ITER.list[ITER.i], 1); \
2175bfbd 320 ITER.i++)
7086e707
AD
321
322
323/* Loop over all elements of BSET, in reverse order starting with
fa8db4ba 324 MIN, setting INDEX to the index of each set bit. For example, the
6aa452a6
AD
325 following will print the bits set in a bitset in reverse order:
326
fa8db4ba 327 bitset_bindex i;
6aa452a6
AD
328 bitset_iterator iter;
329
fa8db4ba 330 BITSET_FOR_EACH_REVERSE (iter, src, i, 0)
6aa452a6 331 {
fa8db4ba 332 printf ("%lu ", (unsigned long int) i);
6aa452a6
AD
333 };
334*/
144c1e76 335#define BITSET_FOR_EACH_REVERSE(ITER, BSET, INDEX, MIN) \
613f5e1a 336 for (ITER.next = (MIN), ITER.num = BITSET_LIST_SIZE; \
04098407 337 (ITER.num == BITSET_LIST_SIZE) \
613f5e1a 338 && (ITER.num = bitset_list_reverse (BSET, ITER.list, \
144c1e76 339 BITSET_LIST_SIZE, &ITER.next));) \
2175bfbd 340 for (ITER.i = 0; \
144c1e76 341 ITER.i < ITER.num && ((INDEX) = ITER.list[ITER.i], 1); \
2175bfbd 342 ITER.i++)
7086e707
AD
343
344
ef017502 345/* Define set operations in terms of logical operations. */
7086e707 346
04af9e52
PE
347#define bitset_diff(DST, SRC1, SRC2) bitset_andn (DST, SRC1, SRC2)
348#define bitset_diff_cmp(DST, SRC1, SRC2) bitset_andn_cmp (DST, SRC1, SRC2)
7086e707 349
04af9e52
PE
350#define bitset_intersection(DST, SRC1, SRC2) bitset_and (DST, SRC1, SRC2)
351#define bitset_intersection_cmp(DST, SRC1, SRC2) bitset_and_cmp (DST, SRC1, SRC2)
7086e707 352
04af9e52
PE
353#define bitset_union(DST, SRC1, SRC2) bitset_or (DST, SRC1, SRC2)
354#define bitset_union_cmp(DST, SRC1, SRC2) bitset_or_cmp (DST, SRC1, SRC2)
7086e707 355
6aa452a6 356/* Symmetrical difference. */
04af9e52
PE
357#define bitset_symdiff(DST, SRC1, SRC2) bitset_xor (DST, SRC1, SRC2)
358#define bitset_symdiff_cmp(DST, SRC1, SRC2) bitset_xor_cmp (DST, SRC1, SRC2)
6aa452a6
AD
359
360/* Union of difference. */
7086e707 361#define bitset_diff_union(DST, SRC1, SRC2, SRC3) \
04af9e52 362 bitset_andn_or (DST, SRC1, SRC2, SRC3)
6aa452a6 363#define bitset_diff_union_cmp(DST, SRC1, SRC2, SRC3) \
04af9e52 364 bitset_andn_or_cmp (DST, SRC1, SRC2, SRC3)
6aa452a6 365
ef017502 366
7086e707 367/* Release any memory tied up with bitsets. */
7d7d6663 368extern void bitset_release_memory (void);
7086e707 369
613f5e1a 370/* Enable bitset stats gathering. */
7d7d6663 371extern void bitset_stats_enable (void);
613f5e1a
AD
372
373/* Disable bitset stats gathering. */
7d7d6663 374extern void bitset_stats_disable (void);
613f5e1a
AD
375
376/* Read bitset stats file of accummulated stats. */
48b16bbc 377void bitset_stats_read (const char *file_name);
613f5e1a
AD
378
379/* Write bitset stats file of accummulated stats. */
48b16bbc 380void bitset_stats_write (const char *file_name);
7086e707
AD
381
382/* Dump bitset stats. */
7d7d6663 383extern void bitset_stats_dump (FILE *);
7086e707
AD
384
385/* Function to debug bitset from debugger. */
7d7d6663 386extern void debug_bitset (bitset);
7086e707
AD
387
388/* Function to debug bitset stats from debugger. */
7d7d6663 389extern void debug_bitset_stats (void);
7086e707 390
7086e707 391#endif /* _BITSET_H */