StochHMM  v0.34
Flexible Hidden Markov Model C++ Library and Application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dynamic_bitset.cpp
Go to the documentation of this file.
1 //
2 // dynamic_bitset.cpp
3 // dynamic_bitset
4 //
5 // Created by Paul Lott on 3/1/13.
6 // Copyright (c) 2013 Korf Lab, Genome Center, UC Davis, Davis, CA. All rights reserved.
7 //
8 
9 #include "dynamic_bitset.h"
10 
11 namespace StochHMM {
12 
13  dynamic_bitset::dynamic_bitset(size_t sz): current_size(sz){
14  num_ints = ((sz-1)/32)+1;
15  buffer = (num_ints*32) - sz;
16  array.resize(num_ints);
17  //array = new (std::nothrow) uint32_t[num_ints]{0};
18  return;
19  }
20 
22  num_ints = rhs.num_ints;
23  buffer = rhs.buffer;
25  array = rhs.array;
26  return;
27  }
28 
29  dynamic_bitset::dynamic_bitset(const std::string& str){
30  size_t str_size = str.size();
31  num_ints = ((str_size-1)/32)+1;
32  buffer = (num_ints*32) - str_size;
33  current_size=str_size;
34  array.resize(num_ints);
35 
36  for(size_t i = 0; i < str_size; ++i){
37  if (str[(str_size-1) - i ] == '1'){
38  set(i);
39  continue;
40  }
41  else if (str[(str_size-1) - i ] == '0'){
42  continue;
43  }
44  else{
45  std::cerr << "Invalid argument: " << str[(str_size-1) - i ] << " Only 0's and 1's \
46  allowed in string to initialize dynamic_bitset" << std::endl;
47  exit(2);
48  }
49  }
50  return;
51  }
52 
53  dynamic_bitset::dynamic_bitset(const std::vector<bool>& vec){
54  size_t vec_size = vec.size();
55  num_ints = ((vec_size-1)/32)+1;
56  buffer = (num_ints*32) - vec_size;
57  current_size = vec_size;
58  array.resize(num_ints);
59  for (size_t i = 0; i < vec_size; ++i){
60  if (vec[i]){
61  set(i);
62  }
63  }
64  return;
65  }
66 
67  //dynamic_bitset::dynamic_bitset(unsigned char ch){
68  // num_ints = 1;
69  // buffer = 24;
70  // current_size = 8;
71  // array.resize(num_ints);
72  // array[0] = (ch << 24);
73  // return;
74  //}
75 
76  //dynamic_bitset::dynamic_bitset(uint16_t val){
77  // num_ints = 1;
78  // buffer = 16;
79  // current_size = 16;
80  // array.resize(num_ints);
81  // array[0] = (val << 16);
82  // return;
83  //}
84  //
85  //dynamic_bitset::dynamic_bitset(uint32_t val){
86  // num_ints = 1;
87  // buffer = 0;
88  // current_size = 32;
89  // array.resize(num_ints);
90  // array[0] = val;
91  // return;
92  //}
93  //
94  //dynamic_bitset::dynamic_bitset(uint64_t val){
95  // num_ints = 2;
96  // buffer = 0;
97  // current_size = 64;
98  // array.resize(num_ints);
99  // array[0] = (uint32_t) ((val & 0xFFFFFFFF00000000) >> 32);
100  // array[1] = (uint32_t) (val & 0xFFFFFFFF);
101  // return;
102  //}
103 
104 
105  //Need to implement getting smaller
106  //! Resize the bitset.
107  //! If size is smaller than bitset, those values will get deleted
108  //! If size is larger than bitset, it will get extended.
109  void dynamic_bitset::resize(size_t sz){
110  size_t new_num_ints = ((sz-1)/32)+1;
111 
112  if (num_ints == new_num_ints){
113  current_size = sz;
114  }
115  else{
116  array.resize(new_num_ints);
117  current_size = sz;
118  num_ints = new_num_ints;
119  }
120 
121  //Set new buffer size
122  buffer = (num_ints*32)-sz;
123 
124  //Clear bit in buffer
125  //Clear those bits that are outside of the current scope
126  uint32_t mask = (1 << 32 - buffer) - 1;
127  array[num_ints-1] &= mask;
128  return;
129  }
130 
131 
132  //!Reserves the set amount of memory
133  //!Doesn't change any of the bitset size. Only reserve a set amount of memory.
134  void dynamic_bitset::reserve(size_t sz){
135  if (sz <= current_size + buffer){
136  return;
137  }
138  else{
139  size_t new_num_ints = ((sz-1)/32)+1;
140  array.reserve(new_num_ints);
141  }
142 
143  return;
144  }
145 
146  //!Clears the complete bitset
147  //!Size is reduced to zero
149  buffer=0;
150  current_size=0;
151  num_ints=0;
152  array.clear();
153  return;
154  }
155 
156 
157  //!Bitwise - AND operator
158  //!\returns a dynamic_bitset that is *this AND rhs
160  dynamic_bitset output(*this);
161  output&=rhs;
162  return output;
163  }
164 
165  //!Bitwise - OR operator
166  //!\returns a dynamic_bitset that is *this OR rhs
168  dynamic_bitset output(*this);
169  output|=rhs;
170  return output;
171  }
172 
173  //!Bitwise - XOR operator
174  //!\returns a dynamic_bitset that is *this XOR rhs
176  dynamic_bitset output(*this);
177  output^=rhs;
178  return output;
179  }
180 
181  //!Bitwise ~ Complement
182  //!\returns dynamic_bitset that is complement of *this
184  dynamic_bitset output(*this);
185  for(size_t i = 0; i < num_ints; ++i){
186  output.array[i] = ~output.array[i];
187  }
188 
189  //Clear those bits that are outside of the current scope
190  uint32_t mask = (1 << 32-output.buffer) - 1;
191  output.array[num_ints-1] &= mask;
192 
193  return output;
194  }
195 
196  //!Overloaded assignment operator makes *this a copy of rhs
197  //!\param rhs dynamic_bitset to copy
198  //!\return *this;
200  num_ints = rhs.num_ints;
201  buffer = rhs.buffer;
203  array = rhs.array;
204  return *this;
205  }
206 
207  //! Bitwise AND all the bits with all the bits in the rhs
209 
210  if (rhs.current_size != this->current_size){
211  std::cerr << __FUNCTION__ << " called on dynamic_bitsets of different sizes." <<std::endl;
212  exit(2);
213  }
214 
215  for(size_t i = 0; i < num_ints; ++i){
216  array[i] &= rhs.array[i];
217  }
218 
219  //Clear those bits that are outside of the current scope
220  uint32_t mask = (1 << 32-buffer) - 1;
221  array[num_ints-1] &= mask;
222 
223  return *this;
224  }
225 
226  //! Bitwise OR all the bits with all the bits in the rhs
228 
229  if (rhs.current_size != this->current_size){
230  std::cerr << __FUNCTION__ << " called on dynamic_bitsets of different sizes." <<std::endl;
231  exit(2);
232  }
233 
234 
235  for(size_t i = 0; i < num_ints; ++i){
236  array[i] |= rhs.array[i];
237  }
238 
239 
240  //Clear those bits that are outside of the current scope
241  uint32_t mask = (1 << 32-buffer) - 1;
242  array[num_ints-1] &= mask;
243 
244  return *this;
245  }
246 
247  //! Bitwise XOR all the bits with all the bits in the rhs
249 
250  if (rhs.current_size != this->current_size){
251  std::cerr << __FUNCTION__ << " called on dynamic_bitsets of different sizes." <<std::endl;
252  exit(2);
253  }
254 
255  for(size_t i = 0; i < num_ints; ++i){
256  array[i] ^= rhs.array[i];
257  }
258 
259 
260  //Clear those bits that are outside of the current scope
261  uint32_t mask = (1 << 32-buffer) - 1;
262  array[num_ints-1] &= mask;
263 
264  return *this;
265  }
266 
267 
268  //!Overloaded ostream for using dynamic_bitsets in ostream
269  //!Usage: std::cout << bs << ....;
270  std::ostream& operator<< (std::ostream& output , const dynamic_bitset& bs){
271  output << bs.stringify();
272 
273  return output;
274  }
275 
276  //!Checks to see if bitset is equal to *this
277  //! \param Bitset to compare with *this
278  //! \returns false if the bitsets are not equal to each other
279  //! \returns true if the bitsets are equal
281  for(size_t i = 0; i < num_ints ;++i){
282  if (array[i]!=rhs.array[i]){
283  return false;
284  }
285  }
286  return true;
287  }
288 
289  //!Checks to see if bitset is not equal to *this
290  //! \param Bitset to compare with *this
291  //! \returns true if the bitsets are not equal to each other
292  //! \returns false if the bitsets are equal
294  for(size_t i = 0; i < num_ints ;++i){
295  if (array[i]!=rhs.array[i]){
296  return true;
297  }
298  }
299  return false;
300  }
301 
302  //!Shift the bitset to the left n positions
303  //!Size of the bitset will not change. If values are shifted off bitset then
304  //!they will be lost.
305  //!\param n Number of positions to shift the bits
307  //If shifting more than 32 then need to insert integer before
308  size_t start(0);
309  if (n>=32){
310  size_t ints_to_add = n/32;
311  n %=32;
312  array.insert(array.begin(), ints_to_add, 0);
313  array.resize(num_ints);
314  if (n==0){
315  return *this;
316  }
317  }
318 
319  if (n!=0){
320  uint32_t shifted(lso(array[start],n));
321  for(size_t i = start+1; i < num_ints ; ++i){
322  shifted = lsoso(array[i], shifted, n);
323  }
324 
325  //Clear those bits that are outside of the current scope (bits in buffer region)
326  uint32_t mask = (1 << 32-buffer) - 1;
327  array[num_ints-1] &= mask;
328  }
329 
330  return *this;
331  }
332 
334  dynamic_bitset output(*this);
335  output<<=n;
336  return output;
337  }
338 
339 
340  //!Shift the bitset to the right n positions
341  //!Size of the bitset will not change. If values are shifted off bitset then
342  //!they will be lost.
343  //!\param n Number of positions to shift the bits
345  //If shifting more than 32 then need to insert integer before
346  size_t start(num_ints-1);
347  if (n>=32){
348  size_t ints_to_delete = n/32;
349  n %= 32;
350  array.erase(array.begin(), array.begin()+ints_to_delete);
351  start -= ints_to_delete;
352  if (n == 0){
353  array.resize(num_ints);
354  return *this;
355  }
356  }
357 
358  if (n != 0){
359  //Shift first integers and get value to shift to next
360  uint32_t shifted(rso(array[start],n));
361 
362  //For all the integers before shift the value
363  for(size_t i = start-1; i != SIZE_MAX ; --i){
364  shifted = rsoso(array[i], shifted, n);
365  }
366 
367  //Resesize the array
368  array.resize(num_ints);
369  }
370 
371  return *this;
372  }
373 
375  dynamic_bitset output(*this);
376  output>>=n;
377  return output;
378  }
379 
380  //!Insert n bits (set to zero) at the position. Bitsets at this position and
381  //!greater will be shifted to the left. This will increase the size of the bitset
382  // \param pos Position to insert the bits
383  // \param n Number of bits to insert
384  void dynamic_bitset::insert(size_t pos, size_t n){
385  if (pos > current_size){
386  std::cerr << "dynamic_bitset::"<<__FUNCTION__ << " Error: Position for insert is beyond the range current size\n";
387  exit(2);
388  }
389 
390  size_t new_buffer = 32-(current_size + n)%32;
391  size_t remainder = 32 - (pos%32);
392  size_t new_num_ints = ((current_size-1)+n)/32+1;
393 
394  size_t first_affected = pos/32;
395  //size_t last_affected = num_ints;
396 
397  size_t next_affected = (pos+n)/32;
398 
399  int64_t next_shift_size = ((pos+n)%32) - (pos%32);
400 
401  int64_t intervening_ints = int64_t (n-remainder) / 32;
402  size_t relative_pos = pos%32;
403 
404 
405  if (new_num_ints!= num_ints){
406 
407  if (intervening_ints != 0 && intervening_ints >= 0){
408  array.insert(array.begin()+first_affected+1,intervening_ints,0);
409  num_ints+= intervening_ints;
410  }
411 
412  //Add additional on end if necessary
413  if (new_num_ints != num_ints){
414  array.resize(new_num_ints);
415  num_ints= new_num_ints;
416  }
417  }
418 
419  uint32_t temp_mask = maskLeft(array[first_affected], relative_pos);
420  array[first_affected] = maskRight(array[first_affected], relative_pos-1);
421 
422  //If shift is by factor of 32 then we just need to reassign values
423  if (next_shift_size == 0){
424  size_t ints_shifted = n/32;
425  for (size_t i = num_ints-1; i > first_affected + intervening_ints + 1; --i){
426  array[i] = array[i-(ints_shifted-intervening_ints)];
427  }
428  array[first_affected+ints_shifted] = temp_mask;
429  }
430  else if (next_shift_size < 0){ //Right shift after intervening sequence
431 
432  //Shift temp sequence right by necessary amount
433  uint8_t left_shift = 32 - abs( (uint8_t) next_shift_size);
434  temp_mask >>= abs( (uint8_t) next_shift_size);
435 
436  for(size_t i = next_affected; i < num_ints ; ++i){
437  uint32_t tmp = array[i];
438  array[i] <<= left_shift;
439  array[i] |= temp_mask;
440  temp_mask = tmp >> (32-left_shift);
441 
442  //temp_mask = lsoso(array[i], temp_mask, left_shift);
443  }
444 
445  }
446  else{//left_shift after intervening sequence
447 
448  //Move the values to new cells before shifting old values
449  if (n>32){
450  size_t ints_shifted = n/32;
451  for (size_t i = num_ints-1; i > first_affected + intervening_ints + 1; --i){
452  array[i] = array[i-(ints_shifted-intervening_ints)];
453  array[i-(ints_shifted-intervening_ints)]=0;
454  }
455  }
456 
457  //Shift temp value
458  uint32_t shifted = lso(temp_mask,next_shift_size);
459  array[next_affected] |= temp_mask;
460 
461  //Shift the rest of the values
462  for(size_t i = next_affected+1; i < num_ints ; ++i){
463  uint32_t tmp = array[i];
464  array[i] <<= next_shift_size;
465  array[i] |= shifted;
466  shifted = tmp >> (32-next_shift_size);
467  }
468  }
469  buffer = new_buffer;
470  current_size +=n;
471  return;
472  }
473 
474 
475  //!Erase the bit at the position from the set.
476  //!Causes the bits to shift right by one
477 
478  void dynamic_bitset::erase(size_t pos){
479 
480  //if the remove position is beyond the end the don't do anything.
481  if (pos>=current_size){
482  return;
483  }
484 
485  //If size is equal to one then just assign zero and return
486  if (current_size == 1){
487  current_size =0;
488  buffer = 32;
489  array[0] = 0;
490  return;
491  }
492 
493  size_t new_buffer = 32-(current_size-1)%32;
494  size_t new_num_ints = ((current_size-2))/32+1;
495  size_t first_affected = pos/32;
496  size_t relative_pos = pos%32;
497 
498  //Get the value shifted off the last int
499  uint32_t shifted(0);
500 
501  //If not last
502  if (first_affected != num_ints-1){
503  shifted = rso(array[num_ints-1], 1);
504  //Shift the rest of the integers up to first affected
505  for (size_t i = num_ints-2; i != first_affected && i != SIZE_MAX; --i){
506  uint32_t temp(array[i]);
507  array[i] = (array[i]>>1) | shifted;
508  shifted = temp << 31;
509  }
510  }
511 
512 
513  //Get the left most part of the first affected
514  uint32_t temp_mask = maskLeft(array[first_affected], relative_pos+1);
515  //std::cout << intToBinString(temp_mask) << std::endl;
516 
517  //Get the right most part of the first affected and return it
518  if ((relative_pos - 1) == SIZE_MAX){
519  array[first_affected] = 0;
520  }
521  else{
522  array[first_affected] = maskRight(array[first_affected], relative_pos-1);
523  }
524 
525 
526  //Shift the left part
527  temp_mask >>=1;
528  //std::cout << intToBinString(temp_mask) << std::endl;
529  //Add the shifted bit from the previous
530  temp_mask |= shifted;
531  //std::cout << intToBinString(temp_mask) << std::endl;
532  //Add pack to the first affected
533  array[first_affected] |= temp_mask;
534 
535  //Resize the int if necessary
536  if (new_num_ints != num_ints){
537  array.resize(new_num_ints);
538  }
539 
540  //Set new values of buffer and size;
541  buffer = new_buffer;
542  current_size--;
543 
544  return;
545  }
546 
547 
548 
549  //!Return the intersection bitset with rhs bitset
550  //! Same as bitwise AND
551  //! \param dynamic_bitset&
552  //! \return dynamic_bitset that is intersection of both
554  return *this & rhs;
555  }
556 
557  //!Returns the union bitset
558  //! Same as bitwise OR
560  return *this | rhs;
561  }
562 
563  //!Return only the bits that are uniqe to bitset
565  return *this & ~rhs ;
566  }
567 
568 
569 
570 
571  //!Get state of bit at position
572  //!No initial range check
573  //!\returns true if set 1
574  //!\returns false if not set 0
575  bool dynamic_bitset::operator[](size_t pos)const{
576  size_t intIter = pos/32;
577  size_t bitIter = pos - (intIter*32);
578  return array[intIter] & (1 << bitIter);
579  }
580 
582  size_t intIter = pos/32;
583  size_t bitIter = pos - (intIter*32);
584  return bit_ref(array[intIter],bitIter);
585  }
586 
587  //!Returns state of bit at position
588  //!Performs range check first
589  bool dynamic_bitset::at(size_t pos) const{
590  if (pos>=current_size){
591  std::cerr << "Error: Out of Range.\nFunction: " << __FUNCTION__ << std::endl;
592  exit(2);
593  }
594 
595  size_t intIter = pos/32;
596  size_t bitIter = pos - (intIter*32);
597  return array[intIter] & (1 << bitIter);
598  }
599 
600  //!Returns whether bit is set at the position
601  //!Performs range check first
602  //! \param pos Position within bitset
603  //! \return true if bit is set
604  //! \return false if bit is unset
605  bool dynamic_bitset::test(size_t pos){
606  if (pos>=current_size){
607  std::cerr << "Error: Out of Range.\nFunction: " << __FUNCTION__ << std::endl;
608  exit(2);
609  }
610 
611  return at(pos);
612  }
613 
614  //!Sets the bit at position with value
615  //!Checks size before assignment
616  //!\param position within bitset
617  void dynamic_bitset::set(size_t pos){
618 
619  if (pos>=current_size){
620  std::cerr << "Error: Out of Range.\nFunction: " << __FUNCTION__ << std::endl;
621  exit(2);
622  }
623 
624  size_t intIter = pos/32;
625  size_t bitIter = pos - (intIter*32);
626  array[intIter] |= (1 << bitIter);
627  return;
628  }
629 
630  //!Sets the bit at position with value
631  //!Checks size before assignment
632  //!\param position within bitset
633  //!\param val Value to set bit
634  void dynamic_bitset::set(size_t pos, bool val){
635  if (pos>=current_size){
636  std::cerr << "Error: Out of Range.\nFunction: " << __FUNCTION__ << std::endl;
637  exit(2);
638  }
639 
640  if (val){
641  set(pos);
642  }
643  else{
644  unset(pos);
645  }
646  }
647 
648  //!Unsets the bit at position
649  //!Checks size before assignment
650  void dynamic_bitset::unset(size_t pos){
651 
652  if (pos>=current_size){
653  std::cerr << "Error: Out of Range.\nFunction: " << __FUNCTION__ << std::endl;
654  exit(2);
655  }
656 
657  size_t intIter = pos/32;
658  size_t bitIter = pos - (intIter*32);
659  array[intIter] &= ~(1 << bitIter);
660  return;
661  }
662 
663  //!Flips the whole bitset
664  //!Complete bitset gets assigned the complement bitset
666  *this = ~*this;
667  return;
668  }
669 
670  //!Flip the bit at position
671  //! If bit is set 1, then it gets unset 0
672  void dynamic_bitset::flip(size_t pos){
673  if (test(pos)){
674  unset(pos);
675  }
676  else{
677  set(pos);
678  }
679 
680  return;
681  }
682 
683  //!Resets all the bits to zero
685  array.assign(num_ints, 0);
686  }
687 
688  //!Clears the bit as position
689  void dynamic_bitset::reset(size_t pos){
690  unset(pos);
691  return;
692  }
693 
694  //!Checks to see if any bits are set
695  //!\returns true if any bits are set
696  //!\returns false no bits are set
698  for(size_t i = 0; i < num_ints; i++){
699  if (array[i]!=0){
700  return true;
701  }
702  }
703  return false;
704  }
705 
706  //!Checks to see if no bits are set
707  //!\returns false if any bits are set
708  //!\returns true if no bits are set
710  for(size_t i = 0; i < num_ints; i++){
711  if (array[i]!=0){
712  return false;
713  }
714  }
715  return true;
716  }
717 
718  //!Pushes a bit onto the bitset
719  //!Increases the bitset size by 1
720  //!\param bool Value to set in bitset
722  if (buffer==0){
723  //Reserve more memory. Push uint32(0) onto array
724  if (current_size != 0){
726  array.push_back(0);
727  buffer = 32;
728  num_ints++;
729  }
730  else{
731  reserve(32);
732  array.push_back(0);
733  buffer = 32;
734  num_ints++;
735  }
736  }
737 
738  //Increases the size and decrease buffer;
739  current_size++;
740  buffer--;
741 
742  //Set value of position
743  if (val){
744  set(current_size-1);
745  }
746  else{
747  unset(current_size-1);
748  }
749 
750  return;
751  }
752 
753 
754  //!Find first set bit within bitset and return the position
755  //!Searches from beginning to end. (Left to Right)
756  //!\return size_t position of first bit set
757  //!\ref http://bits.stephan-brumme.com/lowestBitSet.html
759  for(size_t i = 0; i < num_ints ; ++i){
760  if (array[i] == 0){
761  continue;
762  }
763  else{
764  uint32_t val = array[i];
765 
766  static const size_t MultiplyDeBruijnBitPosition[32] =
767  {
768  // precomputed lookup table
769  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
770  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
771  };
772 
773  // leave only lowest bit
774  val &= -int(val);
775  // DeBruijn constant
776  val *= 0x077CB531;
777  // get upper 5 bits
778  val >>= 27;
779  // convert to actual position
780 
781  return i*32 + MultiplyDeBruijnBitPosition[val];
782  }
783  }
784  return SIZE_MAX;
785  }
786 
787  //!Find the first bit within the bitset starting at position pos
788  //!Searches from beginning to end. (Left to Right)
789  //!\param pos Position to start the search
790  //!\return Returns the position within the bitset with first set bit
791  //\ref http://bits.stephan-brumme.com/lowestBitSet.html
792  size_t dynamic_bitset::find_first(size_t pos) const {
793 
794  static const size_t MultiplyDeBruijnBitPosition[32] =
795  {
796  // precomputed lookup table
797  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
798  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
799  };
800 
801  if (pos > current_size){
802  return SIZE_MAX;
803  }
804 
805  //Deal with partial integer upto next integer boundary
806  //Find Current interger
807  size_t iter = pos/32;
808 
809  //Position within the integer to start
810  size_t int_pos = pos%32;
811 
812  int32_t val = array[iter];
813 
814  //Mask bits before the position
815  val = val & ~((1 << int_pos) - 1);
816 
817  if (val !=0){
818  // leave only lowest bit
819  val &= -int(val);
820  // DeBruijn constant
821  val *= 0x077CB531;
822  // get upper 5 bits
823  val >>= 27;
824  // convert to actual position
825 
826  return iter * 32 + MultiplyDeBruijnBitPosition[val];
827  }
828 
829  //Deal with everything from integer boundary onward
830  //http://bits.stephan-brumme.com/lowestBitSet.html
831  for(size_t i = iter+1; i < num_ints ; ++i){
832  if (array[i] == 0){
833  continue;
834  }
835  else{
836  uint32_t val = array[i];
837 
838  // leave only lowest bit
839  val &= -int(val);
840  // DeBruijn constant
841  val *= 0x077CB531;
842  // get upper 5 bits
843  val >>= 27;
844  // convert to actual position
845 
846  return i * 32 + MultiplyDeBruijnBitPosition[val];
847  }
848  }
849  return SIZE_MAX;
850  }
851 
852 
853  //!Searches in reverse to find first set bit within bitset and return the position
854  //!Searches from end to beginning. (Right to Left)
855  //!\return size_t position of first bit set
857  for(size_t i = num_ints-1; i != SIZE_MAX ; --i){
858  if (array[i] == 0){
859  continue;
860  }
861  else{
862  //Adapted from http://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i
863  //Using binary search algorithm to search
864  uint32_t val = array[i];
865  const uint32_t mask[] = {
866  0x00000FFFF,
867  0x0000000FF,
868  0x00000000F,
869  0x000000003,
870  0x000000001
871  };
872  uint32_t hi = 32;
873  uint32_t lo = 0;
874 
875  if (val == 0)
876  return 0;
877 
878  for (uint32_t j = 0; j < 5; j++) {
879  int mi = lo + (hi - lo) / 2;
880 
881  if ((val >> mi) != 0)
882  lo = mi;
883  else if ((val & (mask[j] << lo)) != 0)
884  hi = mi;
885  }
886  return lo + 32 * i;
887  }
888  }
889  return SIZE_MAX;
890  }
891 
892 
893  size_t dynamic_bitset::find_last(size_t pos)const{
894  if (pos > current_size){
895  return SIZE_MAX;
896  }
897 
898  //Deal with partial integer upto next integer boundary
899  //Find Current interger
900  size_t iter = pos/32;
901 
902  //Position within the integer to start
903  size_t int_pos = pos%32;
904 
905  int32_t val = array[iter];
906  //std::cout << intToBinString(val) << std::endl;
907 
908  //Mask bits before the position
909  val = val & ((1 << int_pos+1) - 1);
910 
911  //std::cout << intToBinString(val) << std::endl;
912 
913  //If value isn't zero then we'll need to find which position is set within it
914  if (val !=0) {
915  //Adapted from http://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i
916  //Using binary search algorithm to search
917  const uint32_t mask[] = {
918  0x00000FFFF,
919  0x0000000FF,
920  0x00000000F,
921  0x000000003,
922  0x000000001
923  };
924  uint32_t hi = 32;
925  uint32_t lo = 0;
926 
927  if (val == 0)
928  return 0;
929 
930  for (uint32_t j = 0; j < 5; j++) {
931  int mi = lo + (hi - lo) / 2;
932 
933  if ((val >> mi) != 0)
934  lo = mi;
935  else if ((val & (mask[j] << lo)) != 0)
936  hi = mi;
937  }
938  return lo + 32 * iter;
939  }
940 
941  for(size_t i = iter-1; i != SIZE_MAX ; --i){
942  if (array[i] == 0){
943  continue;
944  }
945  else{
946  //Adapted from http://stackoverflow.com/questions/671815/what-is-the-fastest-most-efficient-way-to-find-the-highest-set-bit-msb-in-an-i
947  //Using binary search algorithm to search
948  uint32_t val = array[i];
949  const uint32_t mask[] = {
950  0x00000FFFF,
951  0x0000000FF,
952  0x00000000F,
953  0x000000003,
954  0x000000001
955  };
956  uint32_t hi = 32;
957  uint32_t lo = 0;
958 
959  if (val == 0)
960  return 0;
961 
962  for (uint32_t j = 0; j < 5; j++) {
963  int mi = lo + (hi - lo) / 2;
964 
965  if ((val >> mi) != 0)
966  lo = mi;
967  else if ((val & (mask[j] << lo)) != 0)
968  hi = mi;
969  }
970  return lo + 32 * i;
971  }
972  }
973 
974  return SIZE_MAX;
975  }
976 
977 
978  //!Returns whether there are an odd number of bits set
979  //!\return true if number of 1's is odd
980  //!\return false if number of 1' is even
982  bool val(false);
983  for(size_t i = 0; i < num_ints; ++i){
984  uint32_t temp = array[i];
985  temp ^= temp >> 1;
986  temp ^= temp >> 2;
987  temp &= 0x011111111;
988  temp *= 0x011111111;
989  val ^= ((temp >> 28) & 1) != 0;
990  }
991  return val;
992  }
993 
994  //!Returns the number of 1's in the bitset
995  //!\ref bits.sephan-brumme countBits population
996  //!\return size_t number of bits set in bitset
997  size_t dynamic_bitset::count() const{
998  size_t population(0);
999  for (size_t i=0; i < num_ints; i++){
1000  uint32_t x = array[i];
1001  // count bits of each 2-bit chunk
1002  x = x - ((x >> 1) & 0x55555555);
1003  // count bits of each 4-bit chunk
1004  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
1005  // count bits of each 8-bit chunk
1006  x = x + (x >> 4);
1007  // mask out junk
1008  x &= 0xF0F0F0F;
1009  // add all four 8-bit chunks
1010  population+= (x * 0x01010101) >> 24;
1011  }
1012  return population;
1013  }
1014 
1015 
1016  //!Returns the number of 1's in the bitset to the right of the current position
1017  //!\ref bits.sephan-brumme countBits population
1018  //!\return size_t number of bits set in bitset
1019  size_t dynamic_bitset::count_before(size_t pos) const{
1020  size_t current_int = pos/32;
1021  size_t current_pos = pos%32;
1022 
1023  uint32_t x(array[current_int]);
1024 
1025  //Mask all the bits to right (including pos);
1026  uint32_t mask = (1 << current_pos) - 1;
1027  x &= mask;
1028 
1029  //Count bits
1030  x = x - ((x >> 1) & 0x55555555); // reuse input as temporary
1031  x = (x & 0x33333333) + ((x >> 2) & 0x33333333); // temp
1032  size_t population(((x + (x >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); // count
1033 
1034  //Count the bit of integers to left
1035  for (size_t i=0; i < current_int; i++){
1036  x = array[i];
1037  // count bits of each 2-bit chunk
1038  x = x - ((x >> 1) & 0x55555555);
1039  // count bits of each 4-bit chunk
1040  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
1041  // count bits of each 8-bit chunk
1042  x = x + (x >> 4);
1043  // mask out junk
1044  x &= 0xF0F0F0F;
1045  // add all four 8-bit chunks
1046  population+= (x * 0x01010101) >> 24;
1047  }
1048  return population;
1049  }
1050 
1051 
1052  //!Returns string representation of bitset
1053  //!\return std::string representation of bitset
1054  std::string dynamic_bitset::stringify() const{
1055  std::string output("");
1056  for (size_t i=current_size-1;i != SIZE_MAX; --i){
1057 
1058 
1059  bool test = at(i);
1060  if (test){
1061  output+="1";
1062  }
1063  else{
1064  output+="0";
1065  }
1066 
1067  // if (i!= 0 && i%32 == 0){
1068  // output+=",";
1069  // }
1070 
1071  }
1072  return output;
1073  }
1074 
1075  //!Returns string representation of bitset includes buffered bits
1076  //\return std::string representation of bits including buffered bits
1077  std::string dynamic_bitset::stringify_all() const{
1078  std::string output("");
1079  for (size_t i=num_ints-1 ; i != SIZE_MAX; --i){
1080  output+= intToBinString(array[i]);
1081  // if (i!=0){
1082  // output+=",";
1083  // }
1084  }
1085 
1086  return output;
1087  }
1088 
1089 
1091  //if true then set the bit at position
1092  if (value){
1093  val |= (1<<pos);
1094  }
1095  //else clear the bit at the position
1096  else{
1097  val &= ~(1<< pos);
1098  }
1099  return *this;
1100  }
1101 
1103  //if set in rhs then set in this position
1104  if ((rhs.val >> pos) & 1){
1105  val |= (1 << pos);
1106  }
1107  //else clear the bit at this position
1108  else{
1109  val &= ~(1 << pos);
1110  }
1111  return *this;
1112  }
1113 
1115  //if true then set bit
1116  if (value){
1117  val |= (1 << pos);
1118  }
1119  //Otherwise leave it alone
1120  return *this;
1121  }
1122 
1124  //if value is false and val is true then clear val bit
1125  if (!value && ((this->val >> pos) & 1)){
1126  val &= ~(1 << pos);
1127  }
1128  //otherwise leave unchanged
1129  return *this;
1130  }
1131 
1133  //Flip the bit
1134  val^= (1 << pos);
1135  return *this;
1136  }
1137 
1139  //Flip the bit
1140  val^= (1 << pos);
1141  return *this;
1142  }
1143 
1145  //Clear the bit
1146  val &= ~(1 << pos);
1147  return *this;
1148  }
1149 
1151  return !((this->val >> pos) & 1);
1152  }
1153 
1154 
1155 
1156 }
1157