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 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
#ifndef _typed_bitset_h_
#define _typed_bitset_h_
#include <stdint.h>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <utils/inc/bitset_detail.h>
namespace cmt { namespace bitset {
// compile-time calculation of the number of bits_ an integer requires
template<int cur>
struct num_bits { enum { value = 1 + num_bits<(cur >> 1)>::value }; };
template<> // exit condition
struct num_bits<0> { enum { value = 0 }; };
// compile-time calculation of the bitmask relating to a given bit position
template< int pos >
struct bit_mask { enum { value = 1 << pos }; };
// provides a strongly typed bits of up to 16 bits_
template< typename B0, typename B1 = detail::no_bit, typename B2 = detail::no_bit,
typename B3 = detail::no_bit, typename B4 = detail::no_bit, typename B5 = detail::no_bit,
typename B6 = detail::no_bit, typename B7 = detail::no_bit, typename B8 = detail::no_bit,
typename B9 = detail::no_bit, typename B10 = detail::no_bit, typename B11 = detail::no_bit,
typename B12 = detail::no_bit, typename B13 = detail::no_bit, typename B14 = detail::no_bit,
typename B15 = detail::no_bit >
class bits
{
public:
typedef uint16_t bits_sz_t;
private:
bits_sz_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;
bits()
: bits_()
{}
explicit bits(bool b0) : bits_()
{ set<0>(b0); }
bits(bool b0, bool b1) : bits_()
{ set<0>(b0); set<1>(b1); }
bits(bool b0, bool b1, bool b2) : bits_()
{ set<0>(b0); set<1>(b1); set<2>(b2); }
bits(bool b0, bool b1, bool b2, bool b3) : bits_()
{ set<0>(b0); set<1>(b1); set<2>(b2); set<3>(b3); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4) : bits_()
{ set<0>(b0); set<1>(b1); set<2>(b2); set<3>(b3); set<4>(b4); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5) : bits_()
{ set<0>(b0); set<1>(b1); set<2>(b2); set<3>(b3); set<4>(b4); set<5>(b5); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6) : bits_()
{ set<0>(b0); set<1>(b1); set<2>(b2); set<3>(b3); set<4>(b4); set<5>(b5); set<6>(b6); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7) : bits_()
{ set<0>(b0); set<1>(b1); set<2>(b2); set<3>(b3); set<4>(b4); set<5>(b5); set<6>(b6); set<7>(b7); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8) : bits_()
{ 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); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8, bool b9) : bits_()
{ 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); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8, bool b9, bool b10) : bits_()
{ 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); }
bits(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7, bool b8, bool b9, bool b10, bool b11) : bits_()
{ 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); }
bits(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) : bits_()
{ 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); }
bits(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) : bits_()
{ 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); }
bits(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) : bits_()
{ 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); }
bits(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) : bits_()
{ 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::no_bit >::value, bits& >::type set()
{
bits_ |= (1 << detail::find_bit<Bit, bit_names, 0>::position);
return *this;
}
template< size_t N >
bits& set()
{
return set< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >();
}
template< typename Bit >
bits& set(bool val)
{
return val ? set<Bit>() : reset<Bit>();
}
template< size_t N >
bits& set(bool val)
{
return val ? set<N>() : reset<N>();
}
// turn on all bits
bits& set()
{
bits_ = (1 << size()) - 1;
return *this;
}
bits& set_mask(const bits_sz_t mask)
{
bits_ = mask;
return *this;
}
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::no_bit >::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>();
}
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::no_bit >::value, bits& >::type reset()
{
bits_ &= ~(1 << detail::find_bit<Bit, bit_names, 0>::position);
return *this;
}
// turn off bit at position N
template< size_t N >
bits& reset()
{
return reset< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >();
}
// turn off all bits_
bits& reset()
{
bits_ = 0;
return *this;
}
template< typename Bit >
typename boost::disable_if_c< boost::is_same< Bit, detail::no_bit >::value, bits& >::type flip()
{
bits_ ^= (1 << detail::find_bit<Bit, bit_names, 0>::position); return *this;
}
template< size_t N >
bits& flip()
{
return flip< typename boost::mpl::at< bit_names, boost::mpl::integral_c< size_t, N > >::type >();
}
bits& flip()
{
bits_ = (~bits_) & ((1 << size()) - 1);
return *this;
}
// true if any bits are set
bool any() const
{
return bits_;
}
// true if no bits_ are set
bool none() const
{
return !any();
}
size_type count() const
{
// Perhaps not the most efficient implementation. Similar to GCC's though.
static const size_type bits_SetPerNibble[] = { 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 += bits_SetPerNibble[ (bits_ >> (8 * i)) & 0x0F ];
}
return count;
}
unsigned long to_ulong() const
{
return bits_;
}
size_type size() const
{
return detail::type_counter< bit_names, 0 >::count;
}
};
} // namespace bitset
} // namespace cmt
#endif
|