-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitset.cpp
More file actions
132 lines (120 loc) · 3.54 KB
/
bitset.cpp
File metadata and controls
132 lines (120 loc) · 3.54 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* mini-cp is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3
* as published by the Free Software Foundation.
*
* mini-cp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with mini-cp. If not, see http://www.gnu.org/licenses/lgpl-3.0.en.html
*
* Copyright (c) 2018. by Laurent Michel, Pierre Schaus, Pascal Van Hentenryck
*
* StaticBitSet Implementation: Tim Curry
*/
#include "bitset.hpp"
StaticBitSet::StaticBitSet(int sz)
: _sz(sz)
{
int nbWords = (sz >> 5) + ((sz & 0x1f) != 0);
for (int i = 0; i < nbWords; i++)
_words.emplace_back(int(0xffffffff));
if (sz & 0x1f)
_words[nbWords - 1] = (_words[nbWords - 1] & ~(0xffffffff >> (sz % 32)));
}
void StaticBitSet::clear()
{
int nbWords = (_sz >> 5) + ((_sz & 0x1f) != 0);
for (int i = 0; i < nbWords; i++)
_words[i] = 0x0;
}
bool StaticBitSet::contains(int pos) const
{
int word = pos >> 5; // find word for element to remove
int shift = pos % 32; // find pos (from left) within word
int mask = 0x80000000 >> shift;
return (_words[word] & mask) != 0;
}
void StaticBitSet::remove(int pos)
{
int word = pos >> 5; // find word for element to remove
int shift = pos % 32; // find pos (from left) within word
int mask = 0x80000000 >> shift;
mask = ~mask;
_words[word] = (_words[word] & mask);
return;
}
SparseBitSet::SparseBitSet(Trailer::Ptr eng, Storage::Ptr store, int sz)
: _sz(sz)
{
_nbWords = (_sz >> 5) + ((_sz & 0x1f) != 0);
_limit = trail<int>(eng,_nbWords-1);
for (int i = 0; i < _nbWords; i++) {
_words.emplace_back(trail<int>(eng, 0xffffffff));
_index.emplace_back(int(i));
_mask.emplace_back(int(0));
}
if (_sz & 0x1f)
_words[_nbWords - 1] = (_words[_nbWords - 1] & ~(0xffffffff >> (_sz % 32)));
}
void SparseBitSet::clearBit(int b)
{
const int bIdx = b >> 5;
const int bOfs = b % 32;
if (bIdx <= _limit) {
int mask = 0x80000000 >> bOfs;
mask = ~mask;
const int at = _index[bIdx];
_words[at] = _words[at] & mask;
if (_words[at] == 0) {
_index[bIdx] = _index[_limit];
_index[_limit] = at;
_limit = _limit - 1;
}
}
}
void SparseBitSet::clearMask() {
int offset;
for (int i = 0; i <= _limit; i++) {
offset = _index[i];
_mask[offset] = 0;
}
}
void SparseBitSet::reverseMask() {
int offset;
for (int i = 0; i <= _limit; i++) {
offset = _index[i];
_mask[offset] = ~(_mask[offset]);
}
}
void SparseBitSet::addToMask(StaticBitSet& m) {
int offset;
for (int i = 0; i <= _limit; i++) {
offset = _index[i];
_mask[offset] = (_mask[offset] | m[offset]);
}
}
void SparseBitSet::intersectWithMask() {
int offset, w;
for (int i = _limit; i >= 0; i--) {
offset = _index[i];
w = (_words[offset] & _mask[offset]);
_words[offset] = w;
if (w == 0) {
_index[i] = _index[_limit];
_index[_limit] = offset;
_limit = _limit - 1;
}
}
}
int SparseBitSet::intersectIndex(StaticBitSet& m) {
int offset;
for (int i = 0; i <= _limit; i++) {
offset = _index[i];
if ((_words[offset] & m[offset]) != 0)
return offset;
}
return -1;
}