JASSv2
bitstring.h
Go to the documentation of this file.
1 /*
2  BITSTRING.H
3  -----------
4  Copyright (c) 2016 Andrew Trotman
5  Released under the 2-clause BSD license (See:https://en.wikipedia.org/wiki/BSD_licenses)
6 
7  Originally from the ATIRE codebase (where it was also written by Andrew Trotman)
8 */
15 #pragma once
16 
17 #include <stdint.h>
18 
19 #include <vector>
20 
21 namespace JASS
22  {
23  /*
24  CLASS BITSTRING
25  ---------------
26  */
36  class bitstring
37  {
38  /*
39  CONSTANTS
40  ---------
41  */
42  protected:
43  /*
44  BITSTRING::ACTION
45  -----------------
46  */
50  enum action
51  {
52  OR,
53  XOR,
54  AND,
56  };
57 
58  /*
59  TYPES
60  -----
61  */
62  protected:
67  typedef uint64_t bitstring_word; // this is the size of word used for Boolean operatons (and so storage is rounded up to units of this)
68 
69  /*
70  MEMBERS
71  -------
72  */
73  protected:
77  std::vector<uint8_t> bits;
78 
82  size_t bits_long;
83 
84  /*
85  METHODS
86  -------
87  */
88  protected:
89  /*
90  BITSTRING::OPERATION()
91  ----------------------
92  */
100  virtual void operation(action op, bitstring &a, bitstring &b, bitstring &c);
101 
102  public:
103  /*
104  BITSTRING::BITSTRING()
105  ----------------------
106  */
110  bitstring() : bits_long(0)
111  {
112  // nothing
113  }
114  /*
115  BITSTRING::~BITSTRING()
116  ----------------------
117  */
121  virtual ~bitstring()
122  {
123  // nothing
124  }
125 
126  /*
127  BITSTRING::POPCOUNT()
128  ---------------------
129  */
135  inline static size_t popcount(uint64_t value)
136  {
137  value = value - ((value >> 1) & 0x5555555555555555);
138  value = (value & 0x3333333333333333) + ((value >> 2) & 0x3333333333333333);
139  return (((value + (value >> 4)) & 0xF0F0F0F0F0F0F0F) * 0x101010101010101) >> 56;
140  }
141 
142  /*
143  BITSTRING::POPCOUNT()
144  ---------------------
145  */
149  inline static size_t popcount(uint32_t value)
150  {
151  value = value - ((value >> 1) & 0x55555555);
152  value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
153  return (((value + (value >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
154  }
155 
156  /*
157  BITSTRING::POPCOUNT()
158  ---------------------
159  */
163  inline static size_t popcount(uint16_t value)
164  {
165  value = value - ((value >> 1) & 0x5555);
166  value = (value & 0x3333) + ((value >> 2) & 0x3333);
167  /*
168  Is this a compiler bug? we can't do a single line return and must instead do a two line return on Xcode 8.3.3
169  */
170 // return (((value + (value >> 4)) & 0xF0F) * 0x101) >> 8;
171  value = (((value + (value >> 4)) & 0xF0F) * 0x101);
172  return value >> 8;
173  }
174 
175  /*
176  BITSTRING::POPCOUNT()
177  ---------------------
178  */
182  inline static size_t popcount(uint8_t value)
183  {
184  value = value - ((value >> 1) & 0x55u);
185  value = (value & 0x33u) + ((value >> 2) & 0x33u);
186  return (((value + (value >> 4)) & 0xFu) * 0x1);
187  }
188 
189  /*
190  BITSTRING::RESIZE()
191  -------------------
192  */
197  void resize(size_t length_in_bits);
198 
199  /*
200  BITSTRING::SIZE()
201  -----------------
202  */
207  size_t size(void) const
208  {
209  return bits_long;
210  }
211 
212  /*
213  BITSTRING::UNSAFE_SETBIT()
214  --------------------------
215  */
221  inline void unsafe_setbit(size_t position)
222  {
223  bits[position >> 3] |= 1 << (position & 7);
224  }
225 
226  /*
227  BITSTRING::UNSAFE_UNSETBIT()
228  ----------------------------
229  */
235  inline void unsafe_unsetbit(size_t position)
236  {
237  bits[position >> 3] &= ~(1 << (position & 7));
238  }
239 
240  /*
241  BITSTRING::UNSAFE_GETBIT()
242  --------------------------
243  Return the value of the bit at position (either 0 or 1)
244  */
251  bool unsafe_getbit(size_t position) const
252  {
253  return (bits[position >> 3] >> (position & 7)) & 0x01;
254  }
255 
256 
257  /*
258  BITSTRING::SETBIT()
259  -------------------
260  */
266  inline void setbit(size_t position)
267  {
268  if (position < bits_long)
269  unsafe_setbit(position);
270  }
271 
272  /*
273  BITSTRING::UNSETBIT()
274  ---------------------
275  */
281  inline void unsetbit(size_t position)
282  {
283  if (position < bits_long)
284  unsafe_unsetbit(position);
285  }
286 
287  /*
288  BITSTRING::GETBIT()
289  -------------------
290  Return the value of the bit at position (either 0 or 1)
291  */
298  bool getbit(size_t position) const
299  {
300  return position < bits_long ? unsafe_getbit(position) : 0;
301  }
302 
303  /*
304  BITSTRING::BIT_OR()
305  -------------------
306  */
314  inline void bit_or(bitstring &answer, bitstring &with)
315  {
316  operation(OR, answer, *this, with);
317  }
318 
319  /*
320  BITSTRING::BIT_XOR()
321  --------------------
322  */
330  inline void bit_xor(bitstring &answer, bitstring &with)
331  {
332  operation(XOR, answer, *this, with);
333  }
334 
335 
336  /*
337  BITSTRING::BIT_AND()
338  --------------------
339  */
347  inline void bit_and(bitstring &answer, bitstring &with)
348  {
349  operation(AND, answer, *this, with);
350  }
351 
352 
353  /*
354  BITSTRING::BIT_AND_NOT()
355  ------------------------
356  */
364  inline void bit_and_not(bitstring &answer, bitstring &with)
365  {
366  operation(AND_NOT, answer, *this, with);
367  }
368 
369  /*
370  BITSTRING::POPCOUNT()
371  ---------------------
372  */
373 
378  size_t popcount(void) const;
379 
380  /*
381  BITSTRING::INDEX()
382  ------------------
383  */
389  size_t index(size_t which);
390 
391  /*
392  BITSTRING::ZERO()
393  -----------------
394  */
398  void zero(void);
399 
400  /*
401  BITSTRING::ONE()
402  ----------------
403  */
407  void one(void);
408 
409  /*
410  BITSTRING::SERIALISE()
411  ----------------------
412  */
421  uint8_t *serialise(size_t &length)
422  {
423  length = bits.size();
424  return &bits[0];
425  }
426 
427  /*
428  BITSTRING::UNITTEST()
429  ---------------------
430  */
434  static void unittest(void);
435  };
436 }
static size_t popcount(uint64_t value)
Count the number of bits set in value. This uses the parallel algorithm from here: https://graphics...
Definition: bitstring.h:135
void unsafe_setbit(size_t position)
Set the bit at position to 1.
Definition: bitstring.h:221
XOR two bitstrings together.
Definition: bitstring.h:53
void unsafe_unsetbit(size_t position)
Set the bit at position to 0.
Definition: bitstring.h:235
void bit_or(bitstring &answer, bitstring &with)
answer = this | with
Definition: bitstring.h:314
void unsetbit(size_t position)
Set the bit at position to 0.
Definition: bitstring.h:281
static size_t popcount(uint16_t value)
Definition: bitstring.h:163
void setbit(size_t position)
Set the bit at position to 1.
Definition: bitstring.h:266
static size_t popcount(uint32_t value)
Definition: bitstring.h:149
AND two bitstrings together.
Definition: bitstring.h:54
OR two bitstrings together.
Definition: bitstring.h:52
void bit_and_not(bitstring &answer, bitstring &with)
answer = this & ~with
Definition: bitstring.h:364
bitstring()
Constructor.
Definition: bitstring.h:110
void zero(void)
Set the bitstring to all zeros.
Definition: bitstring.cpp:70
virtual ~bitstring()
Destructor.
Definition: bitstring.h:121
Long bitstrings.
Definition: bitstring.h:36
virtual void operation(action op, bitstring &a, bitstring &b, bitstring &c)
operation
Definition: bitstring.cpp:101
size_t size(void) const
Return the length (in bits) of the bitstring.
Definition: bitstring.h:207
size_t index(size_t which)
Returns the bit position of the which-th set bit.
Definition: bitstring.cpp:153
uint64_t bitstring_word
bitstring_word is used as the underlying type for Boolean operations and for popcount() ...
Definition: bitstring.h:67
action
The action enum is used to pass a Boolean operation to operation().
Definition: bitstring.h:50
void one(void)
Set the bitstring to all ones.
Definition: bitstring.cpp:80
static size_t popcount(uint8_t value)
Definition: bitstring.h:182
uint8_t * serialise(size_t &length)
Return a serialised version of this object as an array of uint8_t.
Definition: bitstring.h:421
size_t popcount(void) const
Return the number of set bits in the bitstring. This uses popcount(bitstring_word) to do the count...
Definition: bitstring.cpp:25
void resize(size_t length_in_bits)
Set the length of the bitstring to length_in_bits. The new valid range is 0.. length_in_bits - 1...
Definition: bitstring.cpp:42
static void unittest(void)
Unit test this class.
Definition: bitstring.cpp:183
std::vector< uint8_t > bits
The underlying storage for the long bitstring.
Definition: bitstring.h:77
bool unsafe_getbit(size_t position) const
Return the state (0 or 1) of the bit at the given position.
Definition: bitstring.h:251
void bit_and(bitstring &answer, bitstring &with)
answer = this & with
Definition: bitstring.h:347
a AND ~ b
Definition: bitstring.h:55
Definition: compress_integer_elias_delta_simd.c:23
size_t bits_long
The length of the bitstring in bits.
Definition: bitstring.h:82
bool getbit(size_t position) const
Return the state (0 or 1) of the bit at the given position.
Definition: bitstring.h:298
void bit_xor(bitstring &answer, bitstring &with)
answer = this ^ with
Definition: bitstring.h:330