#ifndef __C_BITS_H__ #define __C_BITS_H__ #include #include /* * Fixed-size bit flag type with set expression constructors * * 2006.9.29 by Young-Hyun Joo */ template< int N = 32 > class c_bits { public: //struct OR {}; // 'or' is the default operator. struct NOT {}; struct AND {}; struct XOR {}; struct MINUS {}; c_bits() {} c_bits( bool bFillValue ) { if ( bFillValue ) set(); else reset(); } c_bits( const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = s.m_flags[i]; } c_bits( const void* pBuf, int bufSize ) { read_from( pBuf, bufSize ); } explicit c_bits( int e ) { reset(); set(e); } c_bits( NOT, int e ) { set(); reset(e); } c_bits( int e1, int e2 ) { reset(); set(e1); set(e2); } c_bits( int e1, int e2, int e3 ) { reset(); set(e1); set(e2); set(e3); } c_bits( int e1, int e2, int e3, int e4 ) { reset(); set(e1); set(e2); set(e3); set(e4); } c_bits( int e1, int e2, int e3, int e4, int e5 ) { reset(); set(e1); set(e2); set(e3); set(e4); set(e5); } c_bits( int e1, int e2, int e3, int e4, int e5, int e6 ) { reset(); set(e1); set(e2); set(e3); set(e4); set(e5); set(e6); } c_bits( int e, const c_bits& s ) { *this = s; set(e); } c_bits( int e, AND, const c_bits& s ) { reset(); if ( s[e] ) set(e); } c_bits( int e, MINUS, const c_bits& s ) { reset(); if ( s[e] ) reset(e); } c_bits( int e, XOR, const c_bits& s ) { *this = s; flip(e); } c_bits( const c_bits& s, int e ) { *this = s; set(e); } c_bits( const c_bits& s, AND, int e ) { reset(); if ( s[e] ) set(e); } c_bits( const c_bits& s, MINUS, int e ) { *this = s; reset(e); } c_bits( const c_bits& s, XOR, int e ) { *this = s; flip(e); } c_bits( NOT, const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = ~s.m_flags[i]; _n(this); } c_bits( const c_bits& s1, const c_bits& s2 ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = s1.m_flags[i] | s2.m_flags[i]; } c_bits( const c_bits& s1, AND, const c_bits& s2 ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = s1.m_flags[i] & s2.m_flags[i]; } c_bits( const c_bits& s1, MINUS, const c_bits& s2 ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = s1.m_flags[i] & ~s2.m_flags[i]; } c_bits( const c_bits& s1, XOR, const c_bits& s2 ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = s1.m_flags[i] ^ s2.m_flags[i]; } static int size() { return N; } int count() const { return _count(); } bool operator ! () const { return none(); } bool any() const { for ( int i = 0; i < SIZE; i++ ) if ( m_flags[i] ) return true; return false; } bool none() const { for ( int i = 0; i < SIZE; i++ ) if ( m_flags[i] ) return false; return true; } bool operator [] ( int e ) const { assert(e>=0 && e& s ) const { for ( int i = 0; i < SIZE; i++ ) if ( m_flags[i] & s.m_flags[i] ) return true; return false; } bool test( int e ) const { assert(e>=0 && e& s ) const { for ( int i = 0; i < SIZE; i++ ) if ( m_flags[i] & s.m_flags[i] ) return true; return false; } c_bits& set( int e ) { assert(e>=0 && e& reset( int e ) { assert(e>=0 && e& flip( int e ) { assert(e>=0 && e& set( const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] |= s.m_flags[i]; return *this; } c_bits& reset( const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] &= ~s.m_flags[i]; return *this; } c_bits& flip( const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] ^= s.m_flags[i]; return *this; } c_bits& set() { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = ~0; _n(this); return *this; } c_bits& reset() { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = 0; return *this; } c_bits& flip() { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = ~m_flags[i]; _n(this); return *this; } c_bits& operator = ( int e ) { reset(); set(e); return *this; } c_bits& operator &= ( int e ) { if ( (*this)[e] ) *this = e; else reset(); return *this; } c_bits& operator |= ( int e ) { return set(e); } c_bits& operator ^= ( int e ) { return flip(e); } c_bits& operator = ( const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] = s.m_flags[i]; return *this; } c_bits& operator &= ( const c_bits& s ) { for ( int i = 0; i < SIZE; i++ ) m_flags[i] &= s.m_flags[i]; return *this; } c_bits& operator |= ( const c_bits& s ) { return set(s); } c_bits& operator ^= ( const c_bits& s ) { return flip(s); } bool operator == ( const c_bits& s ) const { for ( int i = 0; i < SIZE; i++ ) if ( m_flags[i] != s.m_flags[i] ) return false; return true; } bool operator != ( const c_bits& s ) const { for ( int i = 0; i < SIZE; i++ ) if ( m_flags[i] != s.m_flags[i] ) return true; return false; } c_bits operator & ( int e ) const { return c_bits( *this, AND(), e ); } c_bits operator | ( int e ) const { return c_bits( *this, e ); } c_bits operator ^ ( int e ) const { return c_bits( *this, XOR(), e ); } c_bits operator & ( const c_bits& s ) const { return c_bits( *this, AND(), s ); } c_bits operator | ( const c_bits& s ) const { return c_bits( *this, s ); } c_bits operator ^ ( const c_bits& s ) const { return c_bits( *this, XOR(), s ); } c_bits operator ~ () const { return c_bits( NOT(), *this ); } int read_from( const void* pBuf, int bufSize ) { int size = (bufSize >= 0 && bufSize < SIZE * sizeof(int) ) ? bufSize : SIZE * sizeof(int); s_memcpy( m_flags, sizeof( m_flags ), pBuf, size ); _n(this); return size; } int write_to( void* pBuf, int bufSize ) const { int size = (bufSize >= 0 && bufSize < SIZE * sizeof(int) ) ? bufSize : SIZE * sizeof(int); s_memcpy( pBuf, bufSize, m_flags, size ); return size; } unsigned to_uint() const { assert( N <= sizeof(unsigned) * 8 ); return m_flags[0]; } void from_uint( unsigned flags ) { assert( N <= sizeof(unsigned) * 8 ); m_flags[0] = flags; _n(this); } template< typename T > void for_each_on( T fn ) { struct FnPass { unsigned operator () ( unsigned n ) { return n; } }; _for_each( fn, FnPass() ); } template< typename T > void for_each_off( T fn ) { struct FnInv { unsigned operator () ( unsigned n ) { return ~n; } }; _for_each( fn, FnInv() ); } private: /// very dangerous! operator bool () const; enum { BITS = sizeof(unsigned)*8, SIZE = (N+BITS-1) / BITS, BSIZE = SIZE * BITS, LAST_MASK = (N % BITS) ? (1 << (N % BITS)) - 1 : ~0 }; int _count() const { static const char bitCount[ 16 ] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; int c = 0; for ( int i = 0; i < SIZE-1; i++ ) for ( unsigned f = m_flags[i]; f != 0; f /= 16 ) c += bitCount[ f % 16 ]; for ( unsigned f = m_flags[ SIZE-1 ] & LAST_MASK; f != 0; f /= 16 ) c += bitCount[ f % 16 ]; return c; } template< typename T, typename OP > void _for_each( T fn, OP op ) { for ( int i = 0, bit = 0; i < SIZE; i++, bit += BITS ) { unsigned f = op( m_flags[i] ); if ( i == SIZE-1 ) f &= LAST_MASK; if ( f == 0 ) continue; for ( int j = 0; f != 0; j+=4, f /= 16 ) { if ( f % 16 == 0 ) continue; if ( f&1 ) fn( bit+j ); if ( f&2 ) fn( bit+j+1 ); if ( f&4 ) fn( bit+j+2 ); if ( f&8 ) fn( bit+j+3 ); } } } template< int M > struct _n { _n( c_bits* p ) { p->m_flags[ SIZE-1 ] &= LAST_MASK; } }; template<> struct _n< 0 > { _n( c_bits* p ) {} }; unsigned m_flags[ SIZE ]; }; #endif