1 #ifndef VIGRA_BIT_ARRAY_HXX
2 #define VIGRA_BIT_ARRAY_HXX
6 #include "metaprogramming.hxx"
11 class vigra_error_BitArray_accepts_only_unsigned_underlying_types_and_no_;
13 template <
unsigned SIZE,
class X>
15 :
public enable_if<(HasMetaLog2<X>::value && !IsSameType<X, bool>::value && SIZE > 0)> {};
22 template <
unsigned SIZE,
class WORD_TYPE =
unsigned,
class =
void>
25 vigra_error_BitArray_accepts_only_unsigned_underlying_types_and_no_
29 template <
unsigned SIZE,
class WORD_TYPE>
30 class BitArray<SIZE, WORD_TYPE, typename EnableBitArray<SIZE, WORD_TYPE>::type>
36 static const unsigned bit_size = SIZE;
37 static const unsigned word_len = MetaLog2<WORD_TYPE>::value;
38 static const unsigned array_len = (bit_size + word_len - 1) / word_len;
39 static const unsigned last_pos = array_len - 1;
40 template <
unsigned pos>
43 static const unsigned word_pos = pos / word_len;
44 static const unsigned bit_pos = pos % word_len;
45 static const WORD_TYPE bit_mask = WORD_TYPE(1) << bit_pos;
47 typedef bit_index<bit_size> size_index;
48 static const WORD_TYPE ones_mask = ~(WORD_TYPE(0));
49 static const unsigned border_pos = size_index::bit_pos;
50 static const WORD_TYPE last_mask = !border_pos ? 0
51 : size_index::bit_mask - 1;
52 static const bool does_fit = border_pos == 0;
53 unsigned word_pos(
unsigned pos)
const
55 return pos / word_len;
57 WORD_TYPE bit_mask(
unsigned pos)
const
59 return WORD_TYPE(1) << (pos % word_len);
62 WORD_TYPE set_bits[array_len];
71 for (
unsigned i = 0; i != array_len; ++i)
78 template <
unsigned pos>
81 typedef bit_index<pos> index;
82 set_bits[index::word_pos] |= index::bit_mask;
84 template <
unsigned pos>
87 typedef bit_index<pos> index;
88 set_bits[index::word_pos] &= ~index::bit_mask;
90 template <
unsigned pos>
93 typedef bit_index<pos> index;
94 set_bits[index::word_pos] ^= index::bit_mask;
96 template <
unsigned pos>
99 typedef bit_index<pos> index;
100 return (set_bits[index::word_pos] & index::bit_mask) != 0;
103 BitArray & set(
unsigned pos,
bool value =
true)
105 (set_bits[word_pos(pos)] &= ~bit_mask(pos))
106 |= value ? bit_mask(pos) : 0;
109 BitArray & reset(
unsigned pos)
111 set_bits[word_pos(pos)] &= ~bit_mask(pos);
114 BitArray & flip(
unsigned pos)
116 set_bits[word_pos(pos)] ^= bit_mask(pos);
119 bool test(
unsigned pos)
const
121 return set_bits[word_pos(pos)] & bit_mask(pos);
123 bool operator[](
unsigned pos)
const
130 for (
unsigned i = 0; i != last_pos + does_fit; ++i)
131 set_bits[i] = ones_mask;
133 set_bits[last_pos] = last_mask;
138 for (
unsigned i = 0; i != array_len; ++i)
144 for (
unsigned i = 0; i != last_pos + does_fit; ++i)
145 set_bits[i] ^= ones_mask;
147 set_bits[last_pos] ^= last_mask;
151 operator bool()
const
153 for (
unsigned i = 0; i != array_len; ++i)
154 if (set_bits[i] != 0)
158 bool operator!()
const
172 for (
unsigned i = 0; i != last_pos + does_fit; ++i)
173 if (set_bits[i] != ones_mask)
176 return set_bits[last_pos] == last_mask;
180 BitArray operator~()
const
189 bool mutual_compare(
const BitArray & t, F f,
bool if_equal =
false)
const
191 for (
int i = last_pos; i >= 0; i--)
193 WORD_TYPE x = set_bits[i];
194 WORD_TYPE y = t.set_bits[i];
202 typedef std::less<WORD_TYPE> less;
203 typedef std::greater<WORD_TYPE> greater;
208 return mutual_compare(t, less());
212 return mutual_compare(t, greater());
217 return mutual_compare(t, less(),
true);
221 return mutual_compare(t, greater(),
true);
226 for (
unsigned i = 0; i != array_len; ++i)
227 if (set_bits[i] != t.set_bits[i])
237 struct bit_and_assign
239 static void assign(WORD_TYPE & a, WORD_TYPE b) { a &= b; }
241 struct exclusive_or_assign
243 static void assign(WORD_TYPE & a, WORD_TYPE b) { a ^= b; }
247 static void assign(WORD_TYPE & a, WORD_TYPE b) { a |= b; }
250 BitArray & assign_operator(
const BitArray & x)
252 for (
unsigned i = 0; i != array_len; ++i)
253 A::assign(set_bits[i], x.set_bits[i]);
257 BitArray & operator&=(
const BitArray & x)
259 return assign_operator<bit_and_assign>(x);
261 BitArray & operator^=(
const BitArray & x)
263 return assign_operator<exclusive_or_assign>(x);
265 BitArray & operator|=(
const BitArray & x)
267 return assign_operator<bit_or_assign>(x);
272 BitArray & bit_operator(
const BitArray & y)
const
275 return x.assign_operator<A>(y);
278 BitArray operator&(
const BitArray & y)
const
280 return bit_operator<bit_and_assign>(y);
282 BitArray operator^(
const BitArray & y)
const
284 return bit_operator<exclusive_or_assign>(y);
286 BitArray operator|(
const BitArray & y)
const
288 return bit_operator<bit_or_assign>(y);
291 bool operator&&(
const BitArray & y)
const
295 bool operator||(
const BitArray & y)
const
300 friend std::ostream & operator<<(std::ostream & os,
const BitArray & z)
302 for (
int i = bit_size - 1; i >= 0; i--)
303 os << (z[i] ?
"1" :
"0");
309 template <
class WORD_TYPE>
310 class BitArray<0, WORD_TYPE>
318 #endif // VIGRA_BIT_ARRAY_HXX
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition: fixedpoint.hxx:521
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition: fixedpoint.hxx:512
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition: fixedpoint.hxx:539
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition: fixedpoint.hxx:530