carl  24.04
Computer ARithmetic Library
BitVector.h
Go to the documentation of this file.
1 /**
2  * @file BitVector.h
3  * @author: Sebastian Junges
4  *
5  *
6  */
7 #pragma once
8 
9 #include <cassert>
10 #include <cstdlib>
11 #include <iostream>
12 #include <vector>
13 
14 namespace carl
15 {
16 
17  constexpr unsigned sizeOfUnsigned = sizeof(unsigned);
18 
19  class BitVector {
20  public:
21  BitVector() = default;
22 
23  explicit BitVector(unsigned pos) {
24  setBit(pos);
25  }
26 
27  void clear()
28  {
29  mBits = {};
30  }
31 
32  size_t size() const {
33  return mBits.size() * sizeOfUnsigned * 8;
34  }
35 
36  void reserve(size_t capacity) {
37  mBits.resize(capacity);
38  }
39 
40  bool empty() const
41  {
42  for (const auto& b: mBits) {
43  if (b != 0) return false;
44  }
45  return true;
46  }
47 
48  size_t findFirstSetBit() const
49  {
50  size_t pos = 0;
51  for (const auto& b: mBits) {
52  if(b != 0) {
53  unsigned elem = b;
54  while( (elem & unsigned(1)) == 0 )
55  {
56  elem >>= 1;
57  ++pos;
58  }
59  return pos;
60  }
61  pos += sizeOfUnsigned * 8;
62  }
63  return size();
64  }
65 
66  void setBit(unsigned pos, bool val = true) {
67  static_assert(sizeof(unsigned) == 4, "Currently bitvectors are only supported on these platforms.");
68  unsigned vecElem = pos >> 5;
69  unsigned mask = 1;
70  mask <<= (pos & unsigned(31));
71  if(vecElem >= mBits.size()) {
72  mBits.resize(std::size_t(vecElem) + 1, 0);
73  }
74  if(!val) {
75  mask = ~mask;
76  mBits[vecElem] &= mask;
77  } else {
78  mBits[vecElem] |= mask;
79  }
80  assert(getBit(pos) == val);
81  }
82 
83  bool getBit(unsigned pos) const {
84  static_assert(sizeof(unsigned) == 4, "Currently bitvectors are only supported on these platforms.");
85  unsigned vecElem = pos >> 5;
86  if(vecElem < mBits.size()) {
87  unsigned bitNr = pos & unsigned(31);
88  return ((mBits[vecElem] >> bitNr) & unsigned(1)) != 0;
89  }
90  else
91  {
92  return false;
93  }
94  }
95 
96  bool subsetOf(const BitVector& superset);
97 
98  friend bool operator== (const BitVector& lhs, const BitVector& rhs);
99 
101  {
102  return *this |= rhs;
103  }
104 
105  friend BitVector operator| (const BitVector& lhs, const BitVector& rhs);
106 
107 
109  auto lhsIt = mBits.begin();
110  auto rhsIt = rhs.mBits.begin();
111 
112  auto lhsEnd = mBits.end();
113  auto rhsEnd = rhs.mBits.end();
114 
115  while(true) {
116  if(lhsIt == lhsEnd) {
117  mBits.insert(lhsIt,rhsIt,rhsEnd);
118  break;
119  }
120 
121  if(rhsIt == rhsEnd) {
122  break;
123  }
124 
125  *lhsIt |= *rhsIt;
126  ++rhsIt;
127  ++lhsIt;
128  }
129 
130  return *this;
131  }
132 
133 
135  public:
136  forward_iterator(const std::vector<unsigned>::const_iterator it, const std::vector<unsigned>::const_iterator vectorEnd) :
137  posInVec(0), vecIter(it), vecEnd(vectorEnd), curVecElem(vecIter == vecEnd ? 0 : *vecIter)
138  {
139  }
140  protected:
141  unsigned posInVec;
142  std::vector<unsigned>::const_iterator vecIter;
143  const std::vector<unsigned>::const_iterator vecEnd;
144  unsigned curVecElem;
145 
146  public:
147  bool get() {
148  return bool(curVecElem & unsigned(1));
149  }
150 
151  void next() {
152  if(++posInVec == 32) {
153  posInVec = 0;
154  curVecElem = (++vecIter) == vecEnd ? 0 : *vecIter ;
155  } else {
156  curVecElem >>= 1;
157  }
158  }
159 
160  friend bool operator==(const forward_iterator& fi1, const forward_iterator& fi2);
161 
163  if(i == 0) {
164  next();
165  }
166  return *this;
167  }
168 
169  bool isEnd() {
170  return vecIter == vecEnd;
171  }
172  };
174 
176  return forward_iterator(mBits.begin(), mBits.end());
177  }
178 
180  return forward_iterator(mBits.end(), mBits.end());
181  }
182 
183  void print(std::ostream& os = std::cout) const {
184  //std::cout << "Size of vector entries: " << sizeOfUnsigned << " .. " << std::endl;
185  for(const_iterator it = begin(); !it.isEnd(); it++) {
186  os << it.get();
187  }
188  }
189 
190  protected:
191  std::vector<unsigned> mBits;
192  };
193 
194  inline std::ostream& operator<<(std::ostream& os, const BitVector& bv)
195  {
196  bv.print(os);
197  return os;
198  }
199 
200 }
carl is the main namespace for the library.
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
constexpr unsigned sizeOfUnsigned
Definition: BitVector.h:17
bool empty() const
Definition: BitVector.h:40
forward_iterator begin() const
Definition: BitVector.h:175
bool subsetOf(const BitVector &superset)
Definition: BitVector.cpp:47
size_t findFirstSetBit() const
Definition: BitVector.h:48
bool getBit(unsigned pos) const
Definition: BitVector.h:83
void print(std::ostream &os=std::cout) const
Definition: BitVector.h:183
size_t size() const
Definition: BitVector.h:32
BitVector & calculateUnion(const BitVector &rhs)
Definition: BitVector.h:100
BitVector()=default
friend BitVector operator|(const BitVector &lhs, const BitVector &rhs)
Definition: BitVector.cpp:6
BitVector(unsigned pos)
Definition: BitVector.h:23
forward_iterator end() const
Definition: BitVector.h:179
void clear()
Definition: BitVector.h:27
void setBit(unsigned pos, bool val=true)
Definition: BitVector.h:66
friend bool operator==(const BitVector &lhs, const BitVector &rhs)
Definition: BitVector.cpp:37
void reserve(size_t capacity)
Definition: BitVector.h:36
BitVector & operator|=(const BitVector &rhs)
Definition: BitVector.h:108
std::vector< unsigned > mBits
Definition: BitVector.h:191
std::vector< unsigned >::const_iterator vecIter
Definition: BitVector.h:142
friend bool operator==(const forward_iterator &fi1, const forward_iterator &fi2)
Definition: BitVector.cpp:42
forward_iterator(const std::vector< unsigned >::const_iterator it, const std::vector< unsigned >::const_iterator vectorEnd)
Definition: BitVector.h:136
forward_iterator operator++(int i)
Definition: BitVector.h:162
const std::vector< unsigned >::const_iterator vecEnd
Definition: BitVector.h:143