-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitset.c
More file actions
109 lines (85 loc) · 2.04 KB
/
bitset.c
File metadata and controls
109 lines (85 loc) · 2.04 KB
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
/*
* Colibry Compact Binary Set
*
* Copyright (c) 2007-2023 Alexei A. Smekalkine
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <data/bitset.h>
void bitset_clean (struct bitset *o)
{
memset (o->set, 0, o->count * sizeof (o->set[0]));
o->count = 0;
}
int bitset_is_member (const struct bitset *o, size_t x)
{
const size_t size = sizeof (o->set[0]) * CHAR_BIT;
const size_t pos = x / size;
const size_t bit = x % size;
if (pos >= o->count)
return 0;
return (o->set[pos] & (1UL << bit)) != 0;
}
static int bitset_prepare (struct bitset *o, size_t count)
{
const size_t old_size = o->count * sizeof (o->set[0]);
const size_t new_size = count * sizeof (o->set[0]);
unsigned long *p;
if (count <= o->count)
return 1;
if ((p = realloc (o->set, new_size)) == NULL)
return 0;
memset (p + o->count, 0, new_size - old_size);
o->count = count;
o->set = p;
return 1;
}
static void bitset_shrink (struct bitset *o)
{
for (; o->count > 0 && o->set[o->count - 1] == 0; --o->count) {}
}
/* o = o U {x} */
int bitset_add (struct bitset *o, size_t x)
{
const size_t size = sizeof (o->set[0]) * CHAR_BIT;
const size_t pos = x / size;
const size_t bit = x % size;
if (!bitset_prepare (o, pos + 1))
return 0;
o->set[pos] |= (1UL << bit);
return 1;
}
/* o = o \ {x} */
void bitset_del (struct bitset *o, size_t x)
{
const size_t size = sizeof (o->set[0]) * CHAR_BIT;
const size_t pos = x / size;
const size_t bit = x % size;
if (pos < o->count) {
o->set[pos] &= ~(1UL << bit);
bitset_shrink (o);
}
}
/* o = o U s */
int bitset_join (struct bitset *o, const struct bitset *s)
{
size_t i;
if (o->count < s->count && !bitset_prepare (o, s->count))
return 0;
for (i = 0; i < s->count; ++i)
o->set[i] |= s->set[i];
return 1;
}
/* o = o \ s */
int bitset_diff (struct bitset *o, const struct bitset *s)
{
const size_t min = o->count < s->count ? o->count : s->count;
size_t i;
for (i = 0; i < min; ++i)
o->set[i] &= ~s->set[i];
bitset_shrink (o);
return 1;
}