00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef LIBECC_BITS_H
00029 #define LIBECC_BITS_H
00030
00031 #ifndef LIBECC_DEBUG_H
00032 #error "You need to include the appropriate debug.h in the source file, before including this header file."
00033 #endif
00034
00035 #include <libecc/config.h>
00036 #include <iosfwd>
00037 #include <cstddef>
00038 #include <cstring>
00039 #include <string>
00040 #include <inttypes.h>
00041
00042 namespace libecc {
00043
00044
00045 template<unsigned int n, bool inverted>
00046 class bitset_invertible;
00047
00056 typedef unsigned int bitset_digit_t;
00057
00067 template<unsigned int n>
00068 struct bitset_base {
00069 public:
00073 static unsigned int const number_of_bits = n;
00074
00076 static unsigned int const digit_bits = sizeof(bitset_digit_t) * 8;
00077
00079 static unsigned int const digits = (n - 1) / digit_bits + 1;
00080
00081
00082 static unsigned int const number_of_valid_bits = digit_bits - (digits * digit_bits - n);
00083
00085 static bitset_digit_t const valid_bits =
00086 ((static_cast<bitset_digit_t>(1) << (number_of_valid_bits - 1)) << 1) - 1;
00087
00089 static bool const has_excess_bits = ((digits * digit_bits) != n);
00090
00091 protected:
00098 bitset_digit_t vector[digits];
00099
00100 template<unsigned int n1, bool i1, unsigned int n2, bool i2>
00101 friend bool operator==(bitset_invertible<n1, i1> const&, bitset_invertible<n2, i2> const&);
00102 };
00103
00104 #ifndef HIDE_FROM_DOXYGEN
00105 namespace Operator {
00106
00107
00108
00109
00110 struct bitsetAssign {
00111 static bool const sets_excess_bits = true;
00112 static bool const with_zero_sets_zero = true;
00113 static bool const with_ones_sets_ones = true;
00114 static bool const with_ones_inverts = false;
00115 static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out = in; }
00116 };
00117
00118
00119 struct bitsetANDAssign {
00120 static bool const sets_excess_bits = false;
00121 static bool const with_zero_sets_zero = true;
00122 static bool const with_ones_sets_ones = false;
00123 static bool const with_ones_inverts = false;
00124 static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out &= in; }
00125 };
00126
00127
00128 struct bitsetORAssign {
00129 static bool const sets_excess_bits = true;
00130 static bool const with_zero_sets_zero = false;
00131 static bool const with_ones_sets_ones = true;
00132 static bool const with_ones_inverts = false;
00133 static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out |= in; }
00134 };
00135
00136
00137 struct bitsetXORAssign {
00138 static bool const sets_excess_bits = true;
00139 static bool const with_zero_sets_zero = false;
00140 static bool const with_ones_sets_ones = false;
00141 static bool const with_ones_inverts = true;
00142 static inline void exec(bitset_digit_t& out, bitset_digit_t in) { out ^= in; }
00143 };
00144
00145
00146 struct bitsetAND {
00147 static inline bitset_digit_t exec(bitset_digit_t digit1, bitset_digit_t digit2) { return digit1 & digit2; }
00148 };
00149
00150
00151 struct bitsetOR {
00152 static inline bitset_digit_t exec(bitset_digit_t digit1, bitset_digit_t digit2) { return digit1 | digit2; }
00153 };
00154
00155
00156 struct bitsetXOR {
00157 static inline bitset_digit_t exec(bitset_digit_t digit1, bitset_digit_t digit2) { return digit1 ^ digit2; }
00158 };
00159
00160 template<unsigned int n, bool inverted1, bool inverted2, typename OP>
00161 struct expression
00162 {
00163 bitset_invertible<n, inverted1> const& first;
00164 bitset_invertible<n, inverted2> const& second;
00165 OP op;
00166 expression(bitset_invertible<n, inverted1> const& arg1, bitset_invertible<n, inverted2> const& arg2) : first(arg1), second(arg2) { }
00167 };
00168
00169 }
00170 #endif // HIDE_FROM_DOXYGEN
00171
00189 template<unsigned int n, bool inverted>
00190 class bitset_invertible : public bitset_base<n> {
00191 public:
00192
00193 bitset_invertible(void);
00194 template<typename Expression>
00195 explicit bitset_invertible<n, inverted>(Expression const&);
00196
00197 protected:
00198 template<typename OP, unsigned int x, bool invertedx>
00199 void assign(bitset_invertible<x, invertedx> const&, OP);
00200 template<typename OP1, unsigned int x, bool inverted1, bool inverted2, typename OP2>
00201 void assign(Operator::expression<x, inverted1, inverted2, OP2> const&, OP1);
00202
00203 private:
00204 template<unsigned int m, bool i>
00205 friend class bitset_invertible;
00206 bitset_digit_t digit(unsigned int d) const { return inverted ? ~(vector[d]) : vector[d]; }
00207 };
00208
00209
00210 template<unsigned int n, bool inverted>
00211 inline
00212 bitset_invertible<n, inverted>::bitset_invertible(void)
00213 {
00214 if (has_excess_bits)
00215 vector[digits - 1] = 0;
00216 }
00217
00218
00219 template<unsigned int n, bool inverted>
00220 template<typename Expression>
00221 inline
00222 bitset_invertible<n, inverted>::bitset_invertible(Expression const& expr)
00223 {
00224 this->assign(expr, Operator::bitsetAssign());
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 template<unsigned int n, bool inverted>
00243 template<typename ASSIGNMENT_OPERATOR, unsigned int x, bool inverted_argument>
00244 inline void
00245 bitset_invertible<n, inverted>::assign(bitset_invertible<x, inverted_argument> const& bits, ASSIGNMENT_OPERATOR)
00246 {
00247
00248 if (digits > bitset_base<x>::digits)
00249 {
00250 if (!inverted_argument)
00251 {
00252
00253 if (ASSIGNMENT_OPERATOR::with_zero_sets_zero)
00254 {
00255 unsigned int count = digits - bitset_base<x>::digits;
00256 do { vector[count + bitset_base<x>::digits - 1] = 0; } while (--count);
00257 }
00258 }
00259 else
00260 {
00261
00262 if (ASSIGNMENT_OPERATOR::with_ones_sets_ones)
00263 {
00264 vector[digits - 1] = valid_bits;
00265 unsigned int count = digits - bitset_base<x>::digits;
00266 while(--count) { vector[count + bitset_base<x>::digits - 1] = ~static_cast<bitset_digit_t>(0); }
00267 }
00268
00269 if (ASSIGNMENT_OPERATOR::with_ones_inverts)
00270 {
00271 vector[digits - 1] ^= valid_bits;
00272 unsigned int count = digits - bitset_base<x>::digits;
00273 while(--count) { vector[count + bitset_base<x>::digits - 1] ^= ~static_cast<bitset_digit_t>(0); }
00274 }
00275 }
00276 }
00277
00278
00279 unsigned int d;
00280 if (digits < bitset_base<x>::digits)
00281 d = digits - 1;
00282 else
00283 d = bitset_base<x>::digits - 1;
00284 ASSIGNMENT_OPERATOR::exec(vector[d], bits.digit(d));
00285 while(d) { --d; ASSIGNMENT_OPERATOR::exec(vector[d], bits.digit(d)); }
00286
00287
00288 if (((!inverted_argument && x > n) ||
00289 (inverted_argument && digits <= bitset_base<x>::digits)) &&
00290 has_excess_bits && ASSIGNMENT_OPERATOR::sets_excess_bits)
00291 vector[digits - 1] &= valid_bits;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 template<unsigned int n, bool inverted>
00351 template<typename ASSIGNMENT_OPERATOR, unsigned int x, bool inverted1, bool inverted2, typename OPERATOR>
00352 inline void
00353 bitset_invertible<n, inverted>::assign(Operator::expression<x, inverted1, inverted2, OPERATOR> const& expr, ASSIGNMENT_OPERATOR)
00354 {
00355 static bool const argument_has_leading_ones = OPERATOR::exec(inverted1, inverted2);
00356
00357
00358 if (digits > bitset_base<x>::digits)
00359 {
00360 if (!argument_has_leading_ones)
00361 {
00362
00363 if (ASSIGNMENT_OPERATOR::with_zero_sets_zero)
00364 {
00365 unsigned int count = digits - bitset_base<x>::digits;
00366 do { vector[count + bitset_base<x>::digits - 1] = 0; } while (--count);
00367 }
00368 }
00369 else
00370 {
00371
00372 if (ASSIGNMENT_OPERATOR::with_ones_sets_ones)
00373 {
00374 vector[digits - 1] = valid_bits;
00375 unsigned int count = digits - bitset_base<x>::digits;
00376 while(--count) { vector[count + bitset_base<x>::digits - 1] = ~static_cast<bitset_digit_t>(0); }
00377 }
00378 if (ASSIGNMENT_OPERATOR::with_ones_inverts)
00379 {
00380 vector[digits - 1] ^= valid_bits;
00381 unsigned int count = digits - bitset_base<x>::digits;
00382 while(--count) { vector[count + bitset_base<x>::digits - 1] ^= ~static_cast<bitset_digit_t>(0); }
00383 }
00384 }
00385 }
00386
00387
00388 unsigned int d;
00389 if (digits < bitset_base<x>::digits)
00390 d = digits - 1;
00391 else
00392 d = bitset_base<x>::digits - 1;
00393 ASSIGNMENT_OPERATOR::exec(vector[d], OPERATOR::exec(expr.first.digit(d), expr.second.digit(d)));
00394 while(d) { --d; ASSIGNMENT_OPERATOR::exec(vector[d], OPERATOR::exec(expr.first.digit(d), expr.second.digit(d))); }
00395
00396
00397 if (((!argument_has_leading_ones && x > n) ||
00398 (argument_has_leading_ones && digits <= bitset_base<x>::digits)) &&
00399 has_excess_bits && ASSIGNMENT_OPERATOR::sets_excess_bits)
00400 vector[digits - 1] &= valid_bits;
00401 }
00402
00429 template<unsigned int n, bool inverted>
00430 inline bitset_invertible<n, !inverted> const&
00431 operator~(bitset_invertible<n, inverted> const& bits)
00432 {
00433 return *reinterpret_cast<bitset_invertible<n, !inverted> const*>(&bits);
00434 }
00435
00442 template<unsigned int n>
00443 class bitset : public bitset_invertible<n, false> {
00444 public:
00445
00446 bitset(void);
00447 bitset(std::string const&);
00448
00449
00455 bitset(bitset_digit_t const (&v)[bitset_base<n>::digits])
00456 {
00457 #if ECC_DEBUG
00458 LIBCWD_ASSERT( (v[digits - 1] & ~valid_bits) == 0 );
00459 #endif
00460 memcpy(vector, v, sizeof(vector));
00461 }
00462
00463
00464 template<unsigned int m, bool inverted>
00465 bitset(bitset_invertible<m, inverted> const&);
00466 template<unsigned int m, bool i1, bool i2, typename OP>
00467 bitset(Operator::expression<m, i1, i2, OP> const& expr);
00468
00469
00470 template<typename Expression>
00471 bitset& operator=(Expression const&);
00472
00473
00474 template<typename Expression>
00475 bitset& operator&=(Expression const&);
00476 template<typename Expression>
00477 bitset& operator|=(Expression const&);
00478 template<typename Expression>
00479 bitset& operator^=(Expression const&);
00480
00481 public:
00482
00483 template<unsigned int shift, class DIRECTION, class OPERATION>
00484 void shift_op(bitset& result) const;
00485
00486
00487 template<unsigned int shift, class DIRECTION>
00488 void rotate(bitset& result) const;
00489
00490
00491 bool test(size_t n) const;
00492 bool odd(void) const;
00493 void set(size_t n);
00494 void clear(size_t n);
00495 void flip(size_t n);
00496
00497
00498 template<unsigned int pos>
00499 bool test(void) const;
00500 template<unsigned int pos>
00501 void set(void);
00502 template<unsigned int pos>
00503 void clear(void);
00504 template<unsigned int pos>
00505 void flip(void);
00506 template<unsigned int pos>
00507 void digitset(unsigned int d, bool value);
00508
00509
00510 bitset& reset(void);
00511 void setall(void);
00512 bool any(void) const;
00513
00514
00515 bitset_digit_t digit(unsigned int d) const { return vector[d]; }
00516 bitset_digit_t& digit(unsigned int d) { return vector[d]; }
00517 bitset_digit_t const* digits_ptr(void) const { return vector; }
00518 uint32_t digit32(unsigned int d32) const
00519 {
00520 if (sizeof(bitset_digit_t) == 4)
00521 return vector[d32];
00522 else
00523 {
00524 unsigned int d = d32 / (sizeof(bitset_digit_t) / 4);
00525 unsigned int r = d32 % (sizeof(bitset_digit_t) / 4);
00526 return (vector[d] >> (r * 32)) & 0xffffffff;
00527 }
00528 }
00529 };
00530
00534 template<unsigned int n>
00535 inline
00536 bitset<n>::bitset(void)
00537 {
00538 }
00539
00543 template<unsigned int n>
00544 void
00545 bitset<n>::setall(void)
00546 {
00547 vector[digits - 1] = valid_bits;
00548 if (digits > 1)
00549 {
00550 int d = digits - 2;
00551 do { vector[d] = ~static_cast<bitset_digit_t>(0); } while(--d >= 0);
00552 }
00553 }
00554
00579 template<unsigned int n>
00580 template<typename Expression>
00581 inline bitset<n>& bitset<n>::operator=(Expression const& expr)
00582 {
00583 this->assign(expr, Operator::bitsetAssign());
00584 return *this;
00585 }
00586
00603 template<unsigned int n>
00604 template<unsigned int m, bool inverted>
00605 inline bitset<n>::bitset(bitset_invertible<m, inverted> const& bits) : bitset_invertible<n, false>(bits)
00606 {
00607 }
00608
00614 template<unsigned int n>
00615 template<unsigned int m, bool i1, bool i2, typename OP>
00616 inline bitset<n>::bitset(Operator::expression<m, i1, i2, OP> const& expr) : bitset_invertible<n, false>(expr)
00617 {
00618 }
00619
00631 template<unsigned int n1, bool inverted1, unsigned int n2, bool inverted2>
00632 bool operator==(bitset_invertible<n1, inverted1> const& bits1, bitset_invertible<n2, inverted2> const& bits2)
00633 {
00634 unsigned int d;
00635 if (bitset_invertible<n1, inverted1>::digits > bitset_invertible<n2, inverted2>::digits)
00636 {
00637 d = bitset_base<n1>::digits - 1;
00638 do
00639 {
00640 if (bits1.vector[d] != (inverted1 == inverted2 ? 0 : ~static_cast<bitset_digit_t>(0)))
00641 return false;
00642 }
00643 while (--d != bitset_base<n2>::digits - 1);
00644 }
00645 if (bitset_base<n2>::digits > bitset_base<n1>::digits)
00646 {
00647 d = bitset_base<n2>::digits - 1;
00648 do
00649 {
00650 if (bits2.vector[d] != (inverted1 == inverted2 ? 0 : ~static_cast<bitset_digit_t>(0)))
00651 return false;
00652 }
00653 while (--d != bitset_base<n1>::digits - 1);
00654 }
00655 if (bitset_base<n1>::digits > 1 && bitset_base<n2>::digits > 1)
00656 {
00657 if (bitset_base<n1>::digits == bitset_base<n2>::digits)
00658 d = bitset_base<n1>::digits - 1;
00659 do
00660 {
00661 if (inverted1 == inverted2)
00662 {
00663 if (bits1.vector[d] != bits2.vector[d])
00664 return false;
00665 }
00666 else
00667 {
00668 if (bits1.vector[d] != ~(bits2.vector[d]))
00669 return false;
00670 }
00671 }
00672 while(--d != 0);
00673 }
00674 if (inverted1 != inverted2)
00675 return (bits1.vector[0] == ~(bits2.vector[0]));
00676 return (bits1.vector[0] == bits2.vector[0]);
00677 }
00678
00684 template<typename Expression1, typename Expression2>
00685 inline bool
00686 operator!=(Expression1 const& expr1, Expression2 const& expr2)
00687 {
00688 return !(expr1 == expr2);
00689 }
00690
00695 template<unsigned int n>
00696 template<typename Expression>
00697 inline bitset<n>&
00698 bitset<n>::operator&=(Expression const& expr)
00699 {
00700 this->assign(expr, Operator::bitsetANDAssign());
00701 return *this;
00702 }
00703
00708 template<unsigned int n>
00709 template<typename Expression>
00710 inline bitset<n>&
00711 bitset<n>::operator|=(Expression const& expr)
00712 {
00713 this->assign(expr, Operator::bitsetORAssign());
00714 return *this;
00715 }
00716
00721 template<unsigned int n>
00722 template<typename Expression>
00723 inline bitset<n>&
00724 bitset<n>::operator^=(Expression const& expr)
00725 {
00726 this->assign(expr, Operator::bitsetXORAssign());
00727 return *this;
00728 }
00729
00734 template<unsigned int m, bool inverted1, bool inverted2>
00735 Operator::expression<m, inverted1, inverted2, Operator::bitsetAND>
00736 operator&(bitset_invertible<m, inverted1> const& arg1, bitset_invertible<m, inverted2> const& arg2)
00737 {
00738 return Operator::expression<m, inverted1, inverted2, Operator::bitsetAND>(arg1, arg2);
00739 }
00740
00745 template<unsigned int m, bool inverted1, bool inverted2>
00746 Operator::expression<m, inverted1, inverted2, Operator::bitsetOR>
00747 operator|(bitset_invertible<m, inverted1> const& arg1, bitset_invertible<m, inverted2> const& arg2)
00748 {
00749 return Operator::expression<m, inverted1, inverted2, Operator::bitsetOR>(arg1, arg2);
00750 }
00751
00756 template<unsigned int m, bool inverted1, bool inverted2>
00757 Operator::expression<m, inverted1, inverted2, Operator::bitsetXOR>
00758 operator^(bitset_invertible<m, inverted1> const& arg1, bitset_invertible<m, inverted2> const& arg2)
00759 {
00760 return Operator::expression<m, inverted1, inverted2, Operator::bitsetXOR>(arg1, arg2);
00761 }
00762
00773 template<unsigned int n>
00774 template<unsigned int shift, class DIRECTION, class OPERATION>
00775 void
00776 bitset<n>::shift_op(bitset& result) const
00777 {
00778 static unsigned int const digit_shift = shift / digit_bits;
00779 static unsigned int const bit_shift = shift % digit_bits;
00780
00781 static unsigned int const zeroed_digits =
00782 DIRECTION::__left ? ((shift < n) ? digit_shift : digits)
00783 : ((digit_bits - number_of_valid_bits + shift) / digit_bits);
00784
00785 if (zeroed_digits < digits)
00786 {
00787 static unsigned int const complement_shift = (bit_shift == 0) ? 0 : digit_bits - bit_shift;
00788 static unsigned int const initial_to = DIRECTION::__right ? 0 : digits - 1;
00789 static unsigned int const initial_from = initial_to + DIRECTION::direction * digit_shift;
00790 static unsigned int const final_from = DIRECTION::__left ? 0 : digits - 1;
00791
00792 register bitset_digit_t digit = vector[initial_from];
00793 if (initial_from != final_from)
00794 {
00795 register bitset_digit_t next_digit;
00796 unsigned int to = initial_to;
00797 unsigned int from = initial_from + DIRECTION::direction;
00798 if (from != final_from)
00799 do
00800 {
00801 next_digit = vector[from];
00802 if (bit_shift != 0)
00803 {
00804 DIRECTION::shift(digit, bit_shift);
00805 digit |= DIRECTION::reverse_shift_copy(next_digit, complement_shift);
00806 }
00807 OPERATION::op(result.vector[to], digit);
00808 digit = next_digit;
00809 to += DIRECTION::direction;
00810 from += DIRECTION::direction;
00811 }
00812 while (from != final_from);
00813 if (DIRECTION::__left || bit_shift < number_of_valid_bits || bit_shift != 0)
00814 next_digit = vector[final_from];
00815 if (bit_shift != 0)
00816 {
00817 DIRECTION::shift(digit, bit_shift);
00818 digit |= DIRECTION::reverse_shift_copy(next_digit, complement_shift);
00819 }
00820 if (DIRECTION::__left || bit_shift < number_of_valid_bits)
00821 {
00822 OPERATION::op(result.vector[final_from - DIRECTION::direction * (digit_shift + 1)], digit);
00823 digit = DIRECTION::shift_copy(next_digit, bit_shift);
00824 }
00825 }
00826 else
00827 DIRECTION::shift(digit, bit_shift);
00828 static bool const have_mixed_digit = shift != 0 && (DIRECTION::__left ? shift : (n - shift)) % digit_bits != 0;
00829 static unsigned int const last_digit = (DIRECTION::__left ? shift : (n - 1 - shift)) / digit_bits;
00830 if (have_mixed_digit)
00831 OPERATION::mixed_op(result.vector[last_digit], digit);
00832 else
00833 OPERATION::op(result.vector[last_digit], digit);
00834 if (DIRECTION::__left && has_excess_bits)
00835 result.vector[digits - 1] &= valid_bits;
00836 }
00837 if (OPERATION::__clear && zeroed_digits > 0)
00838 {
00839 static unsigned int const final_to = DIRECTION::__left ? 0 : digits - 1;
00840 static unsigned int const initial_to = final_to - DIRECTION::direction * (zeroed_digits - 1);
00841 unsigned int to = initial_to;
00842 if (to != final_to)
00843 do
00844 {
00845 result.vector[to] = 0;
00846 to += DIRECTION::direction;
00847 }
00848 while(to != final_to);
00849 result.vector[to] = 0;
00850 }
00851 }
00852
00869 template<unsigned int n>
00870 bitset<n>::bitset(std::string const& input)
00871 {
00872 reset();
00873 unsigned int d = 0;
00874 unsigned int u = 0;
00875
00876 for (std::string::const_reverse_iterator iter = input.rbegin(); iter != input.rend(); ++iter)
00877 {
00878 bitset_digit_t c = toupper(*iter);
00879 if (c == ' ')
00880 continue;
00881 if (c < '0')
00882 break;
00883 if (c <= '9')
00884 c -= '0';
00885 else
00886 {
00887 if (c > 'F')
00888 break;
00889 if (c >= 'A')
00890 c -= ('A' - 10);
00891 else
00892 break;
00893 }
00894 vector[d] |= c << u;
00895 if ((u += 4) == digit_bits)
00896 {
00897 u = 0;
00898 if (++d == digits)
00899 break;
00900 }
00901 }
00902 if (has_excess_bits)
00903 vector[digits - 1] &= valid_bits;
00904 }
00905
00909 template<unsigned int n>
00910 std::istream&
00911 operator>>(std::istream& is, bitset<n>& bitsetx)
00912 {
00913 std::string tmp;
00914 is >> tmp;
00915 bitsetx.bitset(tmp);
00916 return is;
00917 }
00918
00922 template<unsigned int n>
00923 std::ostream&
00924 operator<<(std::ostream& os, bitset<n> const& bits)
00925 {
00926 #if 0
00927
00928 for (int d = bitset<n>::digits - 1; d >= 0; --d)
00929 for (bitset_digit_t mask = (~static_cast<bitset_digit_t>(0) >> 1) + 1; mask != 0; mask >>= 1)
00930 if (d != bitset<n>::digits - 1 || (mask & bitset<n>::valid_bits))
00931 if (bits.digit(d) & mask)
00932 os << '1';
00933 else
00934 os << '0';
00935 #else
00936
00937 os.fill('0');
00938 os << std::hex;
00939 for (int d = bitset<n>::digits - 1; d >= 0; --d)
00940 {
00941 os.width((d == bitset<n>::digits - 1 && bitset<n>::has_excess_bits) ?
00942 (((n % bitset<n>::digit_bits) - 1) / 4 + 1) :
00943 (bitset<n>::digit_bits / 4));
00944 os << bits.digit(d);
00945 if (d > 0)
00946 os << ' ';
00947 }
00948 #endif
00949 return os;
00950 }
00951
00955 template<unsigned int n>
00956 bitset<n>&
00957 bitset<n>::reset(void)
00958 {
00959 bitset_digit_t* const least_significant_digit = &vector[0];
00960 if (digits > 1)
00961 {
00962 bitset_digit_t* digit_pointer = &vector[digits];
00963 int count = digits - 1;
00964 do { *--digit_pointer = 0; } while(--count);
00965 }
00966 *least_significant_digit = 0;
00967 return *this;
00968 }
00969
00973 template<unsigned int n>
00974 bool
00975 bitset<n>::test(size_t pos) const
00976 {
00977 unsigned int d = pos / digit_bits;
00978 bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
00979 return (vector[d] & mask);
00980 }
00981
00985 template<unsigned int n>
00986 template<unsigned int pos>
00987 bool
00988 bitset<n>::test(void) const
00989 {
00990 static unsigned int const d = pos / digit_bits;
00991 static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
00992 return (vector[d] & mask);
00993 }
00994
00998 template<unsigned int n>
00999 void
01000 bitset<n>::set(size_t pos)
01001 {
01002 unsigned int d = pos / digit_bits;
01003 bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01004 vector[d] |= mask;
01005 }
01006
01010 template<unsigned int n>
01011 template<unsigned int pos>
01012 void
01013 bitset<n>::set(void)
01014 {
01015 static unsigned int const d = pos / digit_bits;
01016 static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01017 vector[d] |= mask;
01018 }
01019
01023 template<unsigned int n>
01024 template<unsigned int pos>
01025 void
01026 bitset<n>::digitset(unsigned int d, bool value)
01027 {
01028 bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01029 if (value)
01030 vector[d] |= mask;
01031 else
01032 vector[d] &= ~mask;
01033 }
01034
01038 template<unsigned int n>
01039 void
01040 bitset<n>::clear(size_t pos)
01041 {
01042 unsigned int d = pos / digit_bits;
01043 bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01044 vector[d] &= ~mask;
01045 }
01046
01050 template<unsigned int n>
01051 template<unsigned int pos>
01052 void
01053 bitset<n>::clear(void)
01054 {
01055 static unsigned int const d = pos / digit_bits;
01056 static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01057 vector[d] &= ~mask;
01058 }
01059
01063 template<unsigned int n>
01064 void
01065 bitset<n>::flip(size_t pos)
01066 {
01067 unsigned int d = pos / digit_bits;
01068 bitset_digit_t mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01069 vector[d] ^= mask;
01070 }
01071
01075 template<unsigned int n>
01076 template<unsigned int pos>
01077 void
01078 bitset<n>::flip(void)
01079 {
01080 static unsigned int const d = pos / digit_bits;
01081 static bitset_digit_t const mask = static_cast<bitset_digit_t>(1) << (pos % digit_bits);
01082 vector[d] ^= mask;
01083 }
01084
01088 template<unsigned int n>
01089 bool
01090 bitset<n>::any(void) const
01091 {
01092 unsigned int to = digits - 1;
01093 if (digits > 1)
01094 do
01095 {
01096 if (vector[to] != 0)
01097 return true;
01098 --to;
01099 }
01100 while(to != 0);
01101 return (vector[0] != 0);
01102 }
01103
01104 static bool const oddnumberofbits[] = {
01105 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01106 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01107 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01108 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01109 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01110 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01111 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01112 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01113 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01114 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01115 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01116 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01117 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false,
01118 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01119 true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true,
01120 false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false };
01121
01125 template<unsigned int n>
01126 bool
01127 bitset<n>::odd(void) const
01128 {
01129 unsigned int from = digits - 1;
01130 bitset_digit_t sum = vector[0];
01131 if (digits > 1)
01132 do
01133 {
01134 sum ^= vector[from];
01135 --from;
01136 }
01137 while(from != 0);
01138 bitset_digit_t ssum = sum;
01139 if (sizeof(bitset_digit_t) >= 2)
01140 {
01141 ssum >>= (digit_bits / 2);
01142 sum ^= ssum;
01143 }
01144 if (sizeof(bitset_digit_t) >= 4)
01145 {
01146 ssum = sum;
01147 ssum >>= (digit_bits / 4);
01148 sum ^= ssum;
01149 }
01150 if (sizeof(bitset_digit_t) >= 8)
01151 {
01152 ssum = sum;
01153 ssum >>= (digit_bits / 8);
01154 sum ^= ssum;
01155 }
01156 if (sizeof(bitset_digit_t) == 16)
01157 {
01158 ssum = sum;
01159 ssum >>= (digit_bits / 16);
01160 sum ^= ssum;
01161 }
01162 return oddnumberofbits[sum & 0xff];
01163 }
01164
01168 struct left {
01169 public:
01170 typedef struct right inverse;
01171 static int const direction = -1;
01172 static bool const __left = true;
01173 static bool const __right = false;
01174 static inline void shift(bitset_digit_t& digit, unsigned int shift) { digit <<= shift; }
01175 static inline bitset_digit_t shift_copy(bitset_digit_t digit, unsigned int shift) { return digit << shift; }
01176 static inline bitset_digit_t reverse_shift_copy(bitset_digit_t digit, unsigned int shift) { return digit >> shift; }
01177 };
01178
01182 struct right {
01183 public:
01184 typedef struct left inverse;
01185 static int const direction = 1;
01186 static bool const __left = false;
01187 static bool const __right = true;
01188 static inline void shift(bitset_digit_t& digit, unsigned int shift) { digit >>= shift; }
01189 static inline bitset_digit_t shift_copy(bitset_digit_t digit, unsigned int shift) { return digit >> shift; }
01190 static inline bitset_digit_t reverse_shift_copy(bitset_digit_t digit, unsigned int shift) { return digit << shift; }
01191 };
01192
01196 struct assign {
01197 public:
01198 static bool const __clear = true;
01199 static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
01200 static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
01201 };
01202
01206 struct exor {
01207 public:
01208 static bool const __clear = false;
01209 static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 ^= digit2; }
01210 static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 ^= digit2; }
01211 };
01212
01213 #ifndef HIDE_FROM_DOXYGEN
01214 struct rotate_phase1 {
01215 public:
01216 static bool const __clear = false;
01217 static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
01218 static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
01219 };
01220
01221 struct rotate_phase2 {
01222 public:
01223 static bool const __clear = false;
01224 static inline void op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 = digit2; }
01225 static inline void mixed_op(bitset_digit_t& digit1, bitset_digit_t digit2) { digit1 |= digit2; }
01226 };
01227 #endif
01228
01237 template<unsigned int n>
01238 template<unsigned int shift, class DIRECTION>
01239 void
01240 bitset<n>::rotate(bitset<n>& result) const
01241 {
01242 shift_op<shift % n, DIRECTION, rotate_phase1>(result);
01243 shift_op<n - (shift % n), typename DIRECTION::inverse, rotate_phase2>(result);
01244 }
01245
01246 }
01247
01248 #endif // LIBECC_BITS_H