Nemo  2.4.0b
Simulate forward-in-time genetic evolution in a spatially explicit, individual-based stochastic simulator
bitstring.h
Go to the documentation of this file.
1 
29 #ifndef BITSRING_H
30 #define BITSRING_H
31 
32 #include <bitset>
33 #include <assert.h> //for CHAR_BIT
34 #include <limits.h>
35 #include <string.h>
36 #include <iostream>
37 
38 #ifdef _GLIBCPP_BITSET_BITS_PER_WORD
39 #define BITS_PER_WORD _GLIBCPP_BITSET_BITS_PER_WORD
40 #else
41 #define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long))
42 #endif
43 
44 #ifndef _GLIBCPP_BITSET_WORDS
45 #define BITSET_WORDS(__n) \
46 ((__n) < 1 ? 1 : ((__n) + BITS_PER_WORD - 1)/BITS_PER_WORD)
47 #else
48 #define BITSET_WORDS(__n) _GLIBCPP_BITSET_WORDS(__n)
49 #endif
50 
51 
52 #define MASK ULLONG_MAX
53 
54 //define MASK = (BITS_PER_WORD == 64 ? 0xFFFFFFFFFFFFFFFF : 0xFFFFFFFF)
55 
57 class bitstring {
58 
59 public:
60 
61  typedef unsigned long _ul;
62 
63  class reference
64  {
65  friend class bitstring;
66 
68  size_t _bitpos;
69 
70  // left undefined
72 
73  public:
74  reference(bitstring& bs, size_t pos)
75  {
76  _word = bs.getword_atPos( pos );
77  _bitpos = pos % BITS_PER_WORD;
78  }
79 
81  { }
82 
83  // For b[i] = x;
85  {
86  if (x)
87  *_word |= ( 1UL << ( _bitpos % BITS_PER_WORD ) );
88  else
89  *_word &= ~( 1UL << ( _bitpos % BITS_PER_WORD ) );
90  return *this;
91  }
92 
93  // For b[i] = b[j];
95  {
96  if ((*(j._word) & ( 1UL << ( j._bitpos % BITS_PER_WORD ) ) ))
97  *_word |= ( 1UL << ( _bitpos % BITS_PER_WORD ) );
98  else
99  *_word &= ~( 1UL << ( _bitpos % BITS_PER_WORD ) );
100  return *this;
101  }
102 
103  // Flips the bit
104  bool operator~() const
105  { return (*(_word) & ( 1UL << ( _bitpos % BITS_PER_WORD ) ) ) == 0; }
106 
107  // For __x = b[i];
108  operator bool() const
109  { return (*(_word) & ( 1UL << ( _bitpos % BITS_PER_WORD ) ) ) != 0; }
110 
111  // For b[i].flip();
113  {
114  *_word ^= ( 1UL << ( _bitpos % BITS_PER_WORD ) );
115  return *this;
116  }
117  };
118 
119  friend class reference;
120 
121  bitstring () : _size(0), _words(0), _data(0) {}
122 
123  bitstring (size_t length)
124  : _size(length), _words( BITSET_WORDS(length) ), _data(0)
125  {
126  _data = new _ul [_words];
127  memset(_data, 0, _words * sizeof(_ul));
128  }
129 
130  bitstring (const bitstring& b)
131  : _size(b._size), _words(b._words), _data(0)
132  {
133  _data = new _ul [_words];
134  memcpy(_data, b._data, _words * sizeof(_ul));
135  }
136 
137  ~bitstring () {if(_data != NULL) delete [] _data;}
138 
139 
140  void reset(size_t length)
141  {
142  _size = length;
143 
144  _words = BITSET_WORDS(length);
145 
146  if(_data) delete [] _data;
147 
148  _data = new _ul [_words];
149  memset(_data, 0UL, _words * sizeof(_ul));
150  }
151 
153  void reset ( )
154  { for(unsigned int i = 0; i < _words; i++) _data[i] = 0UL; }
155 
156  _ul* getword_atPos (size_t pos) const
157  { return &_data[ pos / BITS_PER_WORD ]; }
158 
159  _ul* getword_atIdx (size_t index) const
160  { return &_data[ index ]; }
161 
162  size_t size ( ) const {return _size;}
163 
164  size_t nb_words ( ) const {return _words;}
165 
166  bool at (size_t word, unsigned long bitmask) const
167  {
168  return bool( _data[ word ] & bitmask );
169  }
170 
171  reference operator[] (size_t pos)
172  { return reference(*this, pos); }
173 
174  bool operator[] (size_t n) const
175  { return bool( _data[ n / BITS_PER_WORD ] & ( 1UL << ( n % BITS_PER_WORD ) ) ); }
176 
178  {
179  _size = b._size;
180  if (_words != b._words) {
181  _words = b._words;
182  if(_data != NULL) delete [] _data;
183  _data = new _ul [_words];
184  }
185  memcpy(_data, b._data, _words * sizeof(_ul));
186  return *this;
187  }
188 
190  {
191  for (size_t i = 0; i < _words; i++)
192  _data[i] &= x._data[i];
193  return *this;
194  }
195 
197  {
198  for (size_t i = 0; i < _words; i++)
199  _data[i] |= x._data[i];
200  return *this;
201  }
202 
204  {
205  for (size_t i = 0; i < _words; i++)
206  _data[i] ^= x._data[i];
207  return *this;
208  }
209 
211  {
212  for (size_t i = 0; i < _words; i++)
213  _data[i] = ~(_data[i]);
214  return *this;
215  }
216 
218  {
219  bitstring result(*this);
220  result &= x;
221  return result;
222  }
223 
225  {
226  bitstring result(*this);
227  result |= x;
228  return result;
229  }
230 
232  {
233  bitstring result(*this);
234  result ^= x;
235  return result;
236  }
237 
240 #ifdef __POPCNT__
241  unsigned int local_popcountl (_ul wd) const
242  {
243  return (unsigned int) __builtin_popcountl(wd);
244  }
245 #else
246  unsigned int local_popcountl (_ul wd) const
247  {
248  unsigned char* c = (unsigned char*)&wd;
249  unsigned short cnt = 0;
250 
251  for(unsigned int i = 0; i < sizeof(_ul); i++)
252  cnt += _bit_count[ (unsigned int)c[i] ];
253 
254  return (unsigned int) cnt;
255  }
256 #endif
257 
259  unsigned int count ( )
260  {
261  unsigned int cnt = 0;
262 
263  for(size_t i = 0; i < _words; i++)
264  cnt += local_popcountl(_data[i]);
265 
266  return cnt;
267  }
268 
270  unsigned int count (size_t from, size_t to)
271  {
272  assert(from < to && to <= _size);
273 
274  unsigned int cnt = 0;
275  size_t start_w = from / BITS_PER_WORD;
276  size_t end_w = to / BITS_PER_WORD;
277  size_t start_l = from % BITS_PER_WORD;
278  size_t end_l = to % BITS_PER_WORD;
279 
280  if (start_w == end_w) {
281  _ul mask = (MASK << start_l) & (MASK >> (BITS_PER_WORD - end_l));
282  return local_popcountl( _ul(_data[start_w] & mask) );
283  }
284 
285  // first partial word
286  cnt += local_popcountl(_data[start_w] & (MASK << start_l));
287 
288  // full words in between
289  for (size_t i = start_w + 1; i < end_w; ++i)
290  cnt += local_popcountl(_data[i]);
291 
292  // last partial word
293  if (end_l > 0)
294  cnt += local_popcountl(_data[end_w] & (MASK >> (BITS_PER_WORD - end_l)));
295 
296  return cnt;
297  }
298 
300  unsigned int count_and (const bitstring& mask) const
301  {
302  unsigned int cnt = 0;
303  for (size_t i = 0; i < _words; ++i)
304  cnt += local_popcountl(_data[i] & mask._data[i]);
305  return cnt;
306  }
307 
309  unsigned int count_xor (const bitstring& other) const
310  {
311  unsigned int cnt = 0;
312  for (size_t i = 0; i < _words; ++i)
313  cnt += local_popcountl(_data[i] ^ other._data[i]);
314  return cnt;
315  }
316 
318  unsigned int count_xor_and (const bitstring& other, const bitstring& mask) const
319  {
320  unsigned int cnt = 0;
321  for (size_t i = 0; i < _words; ++i)
322  cnt += local_popcountl((_data[i] ^ other._data[i]) & mask._data[i]);
323  return cnt;
324  }
325 
327  unsigned int count_and_and (const bitstring& other, const bitstring& mask) const
328  {
329  unsigned int cnt = 0;
330  for (size_t i = 0; i < _words; ++i)
331  cnt += local_popcountl((_data[i] & other._data[i]) & mask._data[i]);
332  return cnt;
333  }
334 
336  void set (size_t n) {_data[n / BITS_PER_WORD] |= (1UL << (n % BITS_PER_WORD));}
337 
339  void set (size_t n, bool x) {
340  if (x)
341  _data[n / BITS_PER_WORD] |= ( 1UL << ( n % BITS_PER_WORD ) );
342  else
343  _data[n / BITS_PER_WORD] &= ~( 1UL << ( n % BITS_PER_WORD ) );
344  }
345 
347  void flip (size_t n) {_data[n / BITS_PER_WORD] ^= (1UL << (n % BITS_PER_WORD));}
348 
350  void set_data (_ul* srce, size_t nbwrd)
351  {
352  // if(nbwrd != _words) {
353  // std::cerr<<"bitstring::set_data: different sizes in memcpy!!\n";
354  // exit(1);
355  // }
356  assert(nbwrd == _words);
357  memcpy(_data, srce, nbwrd * sizeof(_ul));
358  }
359 
361  void copy (const bitstring& b)
362  { memcpy(_data, b._data, _words * sizeof(_ul)); }
363 
365  void copy (const bitstring& b, size_t word_pos)
366  { _data[ word_pos ] = b._data[ word_pos ]; }
367 
369  void copy (const bitstring& b, size_t from, size_t to)
370  {
371  assert(to <= _size);
372 
373  if(to != from) { // only if we do have something to copy
374 
375  size_t start_w, end_w, start_l, end_l;
376  _ul mask, tmpl;
377 
378  start_w = from / BITS_PER_WORD;
379  end_w = to / BITS_PER_WORD;
380 
381  start_l = from % BITS_PER_WORD;
382  end_l = to % BITS_PER_WORD;
383 
384  if(start_w != end_w) {
385  //copy wihtin first word:
386  mask = (MASK << start_l);
387 
388  _data[ start_w ] &= ~mask;
389  tmpl = b._data[ start_w ] & mask;
390 
391  _data[ start_w ] |= tmpl;
392 
393  //copy words in-between:
394  size_t k = start_w + 1;
395 
396  memcpy(&_data[k], &b._data[k], (end_w - k)*sizeof(_ul));
397 
398  //copy within last word:
399  mask = (MASK >> (BITS_PER_WORD - end_l) );
400 
401  _data[ end_w ] &= ~mask;;
402  tmpl = b._data[ end_w ] & mask;
403 
404  _data[ end_w ] |= tmpl;
405 
406  } else {
407  //bits to copy are within a word:
408  mask = (MASK << start_l) & (MASK >> (BITS_PER_WORD - end_l) );
409 
410  _data[ start_w ] &= ~mask;
411  tmpl = b._data[ start_w ] & mask;
412 
413  _data[ start_w ] |= tmpl;
414 
415  }
416  }
417  }
418 
419  std::string to_string() const
420  {
421  const char one = '1';
422  std::string result;
423 
424  result.assign(_size, '0');
425 
426  for(size_t i = 0; i < _size; ++i) {
427  if(_data[ i / BITS_PER_WORD ] & ( 1UL << ( i % BITS_PER_WORD ) ))
428  result[i] = one;
429  }
430 
431  return result;
432  }
433 
434  std::string to_string(size_t from, size_t to) const
435  {
436  assert(from < to && to < _size+1);
437 
438  const char one = '1';
439 
440  size_t len = to - from;
441 
442  std::string result;
443 
444  result.assign(len, '0');
445 
446  for(size_t i = from, s = 0; i < to && s < len; ++i, ++s) {
447  if(_data[ i / BITS_PER_WORD ] & ( 1UL << ( i % BITS_PER_WORD ) ))
448  result[s] = one;
449  }
450  return result;
451  }
452 
453  void print (size_t from, size_t to) const
454  {
455  assert(from < to && to < _size+1);
456  for(unsigned int i = from; i < to; ++i)
457  std::cout<< (bool)(_data[ i / BITS_PER_WORD ] & ( 1UL << ( i % BITS_PER_WORD ) ));
458  std::cout<<std::endl;
459  }
460 
461  void print() const
462  {
463  for(unsigned int i = 0; i < _size; ++i)
464  std::cout<< (bool)(_data[ i / BITS_PER_WORD ] & ( 1UL << ( i % BITS_PER_WORD ) ));
465  std::cout<<std::endl;
466  }
467 
468 private:
470  size_t _size;
471 
473  size_t _words;
474 
477 
478 
479 #ifndef __POPCNT__
480  static unsigned char _bit_count[256];
481 #endif
482 
483 };
484 
485 #endif
486 
#define BITSET_WORDS(__n)
Definition: bitstring.h:45
#define MASK
Definition: bitstring.h:52
#define BITS_PER_WORD
Definition: bitstring.h:41
Definition: bitstring.h:64
reference(bitstring &bs, size_t pos)
Definition: bitstring.h:74
reference & operator=(bool x)
Definition: bitstring.h:84
_ul * _word
Definition: bitstring.h:67
reference & flip()
Definition: bitstring.h:112
size_t _bitpos
Definition: bitstring.h:68
~reference()
Definition: bitstring.h:80
bool operator~() const
Definition: bitstring.h:104
reference & operator=(const reference &j)
Definition: bitstring.h:94
Non-template and faster implementation of std::bitset.
Definition: bitstring.h:57
static unsigned char _bit_count[256]
Definition: bitstring.h:480
bitstring(const bitstring &b)
Definition: bitstring.h:130
bitstring operator|(const bitstring &x)
Definition: bitstring.h:224
unsigned int count()
Count number of set bits.
Definition: bitstring.h:259
bool at(size_t word, unsigned long bitmask) const
Definition: bitstring.h:166
unsigned int count(size_t from, size_t to)
Count set bits in the range [from, to).
Definition: bitstring.h:270
unsigned int count_and_and(const bitstring &other, const bitstring &mask) const
Fused AND + mask popcount: count set bits in ((this AND other) AND mask).
Definition: bitstring.h:327
_ul * getword_atPos(size_t pos) const
Definition: bitstring.h:156
unsigned long _ul
Definition: bitstring.h:61
bitstring()
Definition: bitstring.h:121
size_t size() const
Definition: bitstring.h:162
_ul * getword_atIdx(size_t index) const
Definition: bitstring.h:159
size_t _words
Number of _ul-long Words necessary to hold the _size bits.
Definition: bitstring.h:473
unsigned int count_xor(const bitstring &other) const
Fused XOR popcount: count set bits in (this XOR other).
Definition: bitstring.h:309
void print(size_t from, size_t to) const
Definition: bitstring.h:453
bitstring operator&(const bitstring &x)
Definition: bitstring.h:217
unsigned int count_and(const bitstring &mask) const
Masked popcount: count set bits in (this AND mask).
Definition: bitstring.h:300
bitstring & operator|=(const bitstring &x)
Definition: bitstring.h:196
std::string to_string() const
Definition: bitstring.h:419
reference operator[](size_t pos)
Definition: bitstring.h:171
void set(size_t n, bool x)
Set a bit to 0 or 1.
Definition: bitstring.h:339
void reset()
Set all bits to 0.
Definition: bitstring.h:153
bitstring & operator=(const bitstring &b)
Definition: bitstring.h:177
bitstring & operator^=(const bitstring &x)
Definition: bitstring.h:203
friend class reference
Definition: bitstring.h:119
void set(size_t n)
Set a bit to 1.
Definition: bitstring.h:336
bitstring operator~(void)
Definition: bitstring.h:210
unsigned int local_popcountl(_ul wd) const
Counts number of one's in a word using hardware POPCNT when available, falling back to a byte-table l...
Definition: bitstring.h:246
size_t _size
Number of bits in the sequence.
Definition: bitstring.h:470
_ul * _data
The sequence.
Definition: bitstring.h:476
~bitstring()
Definition: bitstring.h:137
void set_data(_ul *srce, size_t nbwrd)
Copy bits from an array of unsigned long words.
Definition: bitstring.h:350
std::string to_string(size_t from, size_t to) const
Definition: bitstring.h:434
void flip(size_t n)
Flip the bit at n.
Definition: bitstring.h:347
void print() const
Definition: bitstring.h:461
bitstring operator^(const bitstring &x)
Definition: bitstring.h:231
void copy(const bitstring &b, size_t word_pos)
Copy one word.
Definition: bitstring.h:365
bitstring & operator&=(const bitstring &x)
Definition: bitstring.h:189
bitstring(size_t length)
Definition: bitstring.h:123
unsigned int count_xor_and(const bitstring &other, const bitstring &mask) const
Fused XOR + mask popcount: count set bits in ((this XOR other) AND mask).
Definition: bitstring.h:318
void copy(const bitstring &b)
Unchecked copy, assumes we have sames sizes.
Definition: bitstring.h:361
void copy(const bitstring &b, size_t from, size_t to)
Copy a delimited sequence block.
Definition: bitstring.h:369
size_t nb_words() const
Definition: bitstring.h:164
void reset(size_t length)
Definition: bitstring.h:140

Generated for Nemo v2.4.0b by  doxygen 1.9.1 -- Nemo is hosted on  Download Nemo

Locations of visitors to this page
Catalogued on GSR