1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
template< typename B0, typename B1 = detail::none, typename B2 = detail::none,
typename B3 = detail::none, typename B4 = detail::none, typename B5 = detail::none,
typename B6 = detail::none, typename B7 = detail::none, typename B8 = detail::none,
typename B9 = detail::none, typename B10 = detail::none, typename B11 = detail::none,
typename B12 = detail::none, typename B13 = detail::none, typename B14 = detail::none,
typename B15 = detail::none >
class bitfield
{
uint32_t bits;
typedef boost::mpl::vector< B0, B1, B2, B3, B4, B5, B6, B7, B8, B9,
B10, B11, B12, B13, B14, B15 > bit_names;
public:
typedef size_t size_type;
bitfield() : bits() {}
explicit bitfield( bool b0 )
{ set<0>( b0 ); }
bitfield( bool b0, bool b1 )
{ set<0>( b0 ); set<1>( b1 ); }
bitfield( bool b0, bool b1, bool b2 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); }
bitfield( bool b0, bool b1, bool b2, bool b3 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); }
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); }
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 ); }
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9, bool b10 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 ); set<10>( b10 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9, bool b10, bool b11 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 ); set<10>( b10 ); set<11>( b11 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9, bool b10, bool b11, bool b12 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 ); set<10>( b10 ); set<11>( b11 );
set<12>( b12 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9, bool b10, bool b11, bool b12, bool b13 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 ); set<10>( b10 ); set<11>( b11 );
set<12>( b12 ); set<13>( b13 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9, bool b10, bool b11, bool b12, bool b13, bool b14 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 ); set<10>( b10 ); set<11>( b11 );
set<12>( b12 ); set<13>( b13 ); set<14>( b14 );
}
bitfield( bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8,
bool b9, bool b10, bool b11, bool b12, bool b13, bool b14, bool b15 )
{ set<0>( b0 ); set<1>( b1 ); set<2>( b2 ); set<3>( b3 ); set<4>( b4 ); set<5>( b5 );
set<6>( b6 ); set<7>( b7 ); set<8>( b8 ); set<9>( b9 ); set<10>( b10 ); set<11>( b11 );
set<12>( b12 ); set<13>( b13 ); set<14>( b14 ); set<15>( b15 );
}
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::none >::value, bitfield& >::type
set()
{ bits |= ( 1 << detail::find_bit<Bit, bit_names, 0>::position ); return *this; }
template< size_t N > bitfield& set()
{ return set< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >(); }
template< typename Bit > bitfield& set( bool val )
{ return val ? set<Bit>() : reset<Bit>(); }
template< size_t N > bitfield& set( bool val )
{ return val ? set<N>() : reset<N>(); }
bitfield& set()
{ bits = ( 1 << size() ) - 1; return *this; }
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::none >::value, bitfield& >::type
reset()
{ bits &= ~( 1 << detail::find_bit<Bit, bit_names, 0>::position ); return *this; }
template< size_t N > bitfield& reset()
{ return reset< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >(); }
bitfield& reset() { bits = 0; return *this; }
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::none >::value, bitfield& >::type
flip()
{ bits ^= ( 1 << detail::find_bit<Bit, bit_names, 0>::position ); return *this; }
template< size_t N > bitfield& flip()
{ return flip< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >(); }
bitfield& flip()
{ bits = ( ~bits ) & ( ( 1 << size() ) - 1 ); return *this; }
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::none >::value, bool >::type
get() const
{ return bits & ( 1 << detail::find_bit<Bit, bit_names, 0>::position ); }
template< size_t N > bool get() const
{ return get< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >(); }
template< typename Bit > bool test() const
{ return get<Bit>(); }
template< size_t N > bool test() const
{ return get<N>(); }
bool any() const
{ return bits; }
bool none() const
{ return !any(); }
// Perhaps not the most efficient implementation. Similar to GCC's though.
size_type count() const
{
static const size_type bitsSetPerNibble[] =
{ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
size_type count = 0;
for( size_t i = 0; i < 4; ++i )
count += bitsSetPerNibble[ ( bits >> ( 8 * i ) ) & 0x0F ];
return count;
}
unsigned long to_ulong() const { return bits; }
bool operator==( const bitfield& rhs ) const
{ return bits == rhs.bits; }
bool operator!=( const bitfield& rhs ) const
{ return !( *this == rhs ); }
bitfield& operator&=( const bitfield& rhs )
{ bits &= rhs.bits; return *this; }
bitfield& operator^=( const bitfield& rhs )
{ bits ^= rhs.bits; return *this; }
bitfield& operator|=( const bitfield& rhs )
{ bits |= rhs.bits; return *this; }
bitfield& operator>>=( size_t num )
{ bits >>= num; return *this; }
bitfield& operator<<=( size_t num )
{ bits = ( bits << num ) & ( ( 1 << size() ) - 1 ); return *this; }
size_type size() const
{ return detail::type_counter< bit_names, 0 >::count; }
};
|