2005-09-08 17:16:18 +02:00
# ifndef _BITVECTOR_H_
# define _BITVECTOR_H_
# include "vec.h"
//compressed storage of large bit vectors
2006-03-30 21:16:40 +02:00
//any reasonable compiler changes the dividions and modulos to shift/and instructions
typedef unsigned long bitvector_block ; //should be automatically portable and efficiently use wordlength of each machine (32 vs 64)
# define blockbits (8*sizeof(bitvector_block))
inline unsigned int bitvector_rounded ( unsigned int n )
{
return ( ( n + blockbits - 1 ) / blockbits ) * blockbits ;
}
class bitvector : public NRVec < bitvector_block >
2005-09-08 17:16:18 +02:00
{
private :
2006-03-30 21:16:40 +02:00
unsigned int modulo ;
2005-09-08 17:16:18 +02:00
public :
2006-03-30 21:16:40 +02:00
bitvector ( ) : NRVec < bitvector_block > ( ) { } ;
explicit bitvector ( const unsigned int n ) : NRVec < bitvector_block > ( ( n + blockbits - 1 ) / blockbits ) { modulo = n % blockbits ; } ;
bitvector ( const bitvector_block a , const unsigned int n ) : NRVec < bitvector_block > ( a , ( n + blockbits - 1 ) / blockbits ) { modulo = n % blockbits ; } ;
bitvector ( const bitvector & rhs ) : NRVec < bitvector_block > ( rhs ) { } ;
//override dereferencing to address single bits, is however possible
2005-09-08 17:16:18 +02:00
//only in the const context (otherwise we would have to define a type which, when assigned to, changes a single bit - possible but probably inefficient)
2006-03-30 21:16:40 +02:00
void resize ( const unsigned int n ) { NRVec < bitvector_block > : : resize ( ( n + blockbits - 1 ) / blockbits ) ; modulo = n % blockbits ; } ;
unsigned int size ( ) const { return ( nn * blockbits ) - blockbits + ( modulo ? modulo : blockbits ) ; } ;
//arguments must be unsigned to keep the resulting assembly code simple and efficient
const bool operator [ ] ( const unsigned int i ) const { return ( v [ i / blockbits ] > > ( i % blockbits ) ) & 1 ; } ;
void set ( const unsigned int i ) { v [ i / blockbits ] | = ( 1 < < ( i % blockbits ) ) ; } ;
void reset ( const unsigned int i ) { v [ i / blockbits ] & = ~ ( 1 < < ( i % blockbits ) ) ; } ;
const bool get ( const unsigned int i ) { return ( v [ i / blockbits ] > > ( i % blockbits ) ) & 1 ; } ;
const bool assign ( const unsigned int i , const bool r ) { if ( r ) set ( i ) ; else reset ( i ) ; return r ; } ;
void clear ( ) { memset ( v , 0 , nn * sizeof ( bitvector_block ) ) ; } ;
void fill ( ) { memset ( v , 0xff , nn * sizeof ( bitvector_block ) ) ; } ;
const bool operator ! = ( const bitvector & rhs ) const { } ;
const bool operator = = ( const bitvector & rhs ) const { return ! ( * this ! = rhs ) ; } ;
2005-09-08 17:16:18 +02:00
} ;
2006-03-30 21:16:40 +02:00
extern ostream & operator < < ( ostream & s , const bitvector & x ) ;
extern istream & operator > > ( istream & s , bitvector & x ) ;
2005-09-08 17:16:18 +02:00
# endif