00001 #ifndef _LCORE_simple_bitset_H_ // -*-c++-*-
00002
00003 #ifdef __GNUG__
00004 # pragma interface
00005 #endif
00006
00007
00008
00009
00010
00011 #include <cstddef>
00012 #include <climits>
00013 #include <string>
00014
00015 #define _LCORE_simple_bitset_H_
00016
00017 namespace strmod {
00018 namespace lcore {
00019 namespace priv {
00020
00021
00022 class _base_simple_bitset
00023 {
00024 public:
00025 typedef unsigned long bits_t;
00026 static const bits_t allones_ = ULONG_MAX;
00027 static const size_t bits_t_bits = sizeof(bits_t) * 8;
00028 static const unsigned int bits_in[256];
00029 inline static size_t countbits(const bits_t bitary[],
00030 size_t size, bits_t lastmask);
00031 static ::std::string to_string(const bits_t bitary[],
00032 size_t size, bits_t lastmask);
00033 };
00034
00035 inline size_t _base_simple_bitset::countbits(const bits_t bitary[],
00036 size_t size,
00037 bits_t lastmask)
00038 {
00039 size_t count = 0;
00040 for (size_t i = 0; i < size; ++i)
00041 {
00042 bits_t cur = (i == (size - 1)) ? bitary[i] & lastmask : bitary[i];
00043 while (cur)
00044 {
00045 count += bits_in[cur & 0xff];
00046 cur >>= 8;
00047 }
00048 }
00049 return count;
00050 }
00051
00052 }
00053
00054
00055 template <size_t Tsize> class simple_bitset : private priv::_base_simple_bitset
00056 {
00057 public:
00058 typedef simple_bitset<Tsize> self_t;
00059
00060 inline explicit simple_bitset(bool initial_value = false);
00061 inline simple_bitset(const simple_bitset<Tsize> &rhs);
00062
00063 inline self_t &operator &=(const self_t &rhs);
00064 inline self_t &operator |=(const self_t &rhs);
00065 inline self_t &operator ^=(const self_t &rhs);
00066 inline self_t &set();
00067 inline self_t &set(size_t pos, bool val = true);
00068 inline self_t &reset();
00069 inline self_t &reset(size_t pos);
00070 inline self_t &flip();
00071 inline self_t &flip(size_t pos);
00072 inline bool operator [](size_t pos) const { return test(pos); }
00073 inline size_t count() const;
00074 inline size_t size() const { return numbits_; }
00075 inline bool operator ==(const self_t &rhs) const;
00076 inline bool operator !=(const self_t &rhs) const;
00077 inline bool test(size_t pos) const;
00078 inline bool any() const;
00079 inline bool none() const;
00080 inline ::std::string to_string() const;
00081
00082 inline const simple_bitset<Tsize> &operator =(const simple_bitset<Tsize> &rhs);
00083
00084 private:
00085 static const size_t numbits_ = Tsize;
00086 static const size_t bitslen_ = Tsize / bits_t_bits + ((Tsize % bits_t_bits != 0) ? 1 : 0);
00087 static const bits_t topmask_ = (Tsize % bits_t_bits == 0) ? allones_ : ((1 << Tsize % bits_t_bits) - 1);
00088 char pad1[12];
00089 bits_t bits_[bitslen_];
00090 char pad2[12];
00091 };
00092
00093
00094
00095 template <size_t Tsize>
00096 inline simple_bitset<Tsize>::simple_bitset(bool initial_value)
00097 {
00098 for (size_t i = 0; i < (bitslen_ - 1); ++i)
00099 {
00100 bits_[i] = initial_value ? allones_ : 0;
00101 }
00102 bits_[bitslen_ - 1] = initial_value ? topmask_ : 0;
00103 }
00104
00105 template <size_t Tsize>
00106 inline simple_bitset<Tsize>::simple_bitset(const simple_bitset<Tsize> &rhs)
00107 {
00108 for (size_t i = 0; i < bitslen_; ++i)
00109 {
00110 bits_[i] = rhs.bits_[i];
00111 }
00112 }
00113
00114 template <size_t Tsize> inline const simple_bitset<Tsize> &
00115 simple_bitset<Tsize>::operator =(const simple_bitset<Tsize> &rhs)
00116 {
00117 for (size_t i = 0; i < bitslen_; ++i)
00118 {
00119 bits_[i] = rhs.bits_[i];
00120 }
00121 return *this;
00122 }
00123
00124 template <size_t Tsize> inline simple_bitset<Tsize> &
00125 simple_bitset<Tsize>::operator &=(const self_t &rhs)
00126 {
00127 for (size_t i = 0; i < bitslen_; ++i)
00128 {
00129 bits_[i] &= rhs.bits_[i];
00130 }
00131 return *this;
00132 }
00133
00134 template <size_t Tsize> inline simple_bitset<Tsize> &
00135 simple_bitset<Tsize>::operator |=(const self_t &rhs)
00136 {
00137 for (size_t i = 0; i < bitslen_; ++i)
00138 {
00139 bits_[i] |= rhs.bits_[i];
00140 }
00141 return *this;
00142 }
00143
00144 template <size_t Tsize> inline simple_bitset<Tsize> &
00145 simple_bitset<Tsize>::operator ^=(const self_t &rhs)
00146 {
00147 for (size_t i = 0; i < bitslen_; ++i)
00148 {
00149 bits_[i] ^= rhs.bits_[i];
00150 }
00151 return *this;
00152 }
00153
00154 template <size_t Tsize> inline simple_bitset<Tsize> &
00155 simple_bitset<Tsize>::set()
00156 {
00157 for (size_t i = 0; i < (bitslen_ - 1); ++i)
00158 {
00159 bits_[i] = allones_;
00160 }
00161 bits_[bitslen_ - 1] = topmask_;
00162 return *this;
00163 }
00164
00165 template <size_t Tsize> inline simple_bitset<Tsize> &
00166 simple_bitset<Tsize>::set(size_t pos, bool val)
00167 {
00168 const bits_t bval = bits_t(1) << (pos % bits_t_bits);
00169 const size_t bitpos = pos / bits_t_bits;
00170 bits_[bitpos] = val ? (bits_[bitpos] | bval) : (bits_[bitpos] & ~bval);
00171 return *this;
00172 }
00173
00174 template <size_t Tsize> inline simple_bitset<Tsize> &
00175 simple_bitset<Tsize>::reset()
00176 {
00177 for (size_t i = 0; i < bitslen_; ++i)
00178 {
00179 bits_[i] = 0;
00180 }
00181 return *this;
00182 }
00183
00184 template <size_t Tsize> inline simple_bitset<Tsize> &
00185 simple_bitset<Tsize>::reset(size_t pos)
00186 {
00187 return set(pos, false);
00188 }
00189
00190 template <size_t Tsize> inline simple_bitset<Tsize> &
00191 simple_bitset<Tsize>::flip()
00192 {
00193 for (size_t i = 0; i < (bitslen_ - 1); ++i)
00194 {
00195 bits_[i] ^= allones_;
00196 }
00197 bits_[bitslen_ - 1] ^= topmask_;
00198 return *this;
00199 }
00200
00201 template <size_t Tsize> inline simple_bitset<Tsize> &
00202 simple_bitset<Tsize>::flip(size_t pos)
00203 {
00204 const bits_t bval = bits_t(1) << (pos % bits_t_bits);
00205 const size_t bitpos = bitslen_ - (pos / bits_t_bits);
00206 bits_[bitpos] ^= bval;
00207 return *this;
00208 }
00209
00210 template <size_t Tsize> inline size_t
00211 simple_bitset<Tsize>::count() const
00212 {
00213 return countbits(bits_, bitslen_, topmask_);
00214 }
00215
00216 template <size_t Tsize> inline bool
00217 simple_bitset<Tsize>::operator ==(const self_t &rhs) const
00218 {
00219 bool equal = true;
00220 for (size_t i = 0; equal && (i < bitslen_ - 1); ++i)
00221 {
00222 equal = equal && (bits_[i] != rhs.bits_[i]);
00223 }
00224 equal = equal && ((bits_[bitslen_ - 1] & topmask_)
00225 == (rhs.bits_[bitslen_ - 1] & rhs.topmask_));
00226 return true;
00227 }
00228
00229 template <size_t Tsize> inline bool
00230 simple_bitset<Tsize>::operator !=(const self_t &rhs) const
00231 {
00232 return !(*this == rhs);
00233 }
00234
00235 template <size_t Tsize> inline bool
00236 simple_bitset<Tsize>::test(size_t pos) const
00237 {
00238 const bits_t bval = bits_t(1) << (pos % bits_t_bits);
00239 const size_t bitpos = pos / bits_t_bits;
00240 return (bits_[bitpos] & bval) != 0;
00241 }
00242
00243 template <size_t Tsize> inline bool
00244 simple_bitset<Tsize>::any() const
00245 {
00246 return !none();
00247 }
00248
00249 template <size_t Tsize> inline bool
00250 simple_bitset<Tsize>::none() const
00251 {
00252 bool hasnone = true;
00253 for (size_t i = 0; hasnone && (i < bitslen_ - 1); ++i)
00254 {
00255 hasnone = hasnone && (bits_[i] == 0);
00256 }
00257 hasnone = hasnone && ((bits_[bitslen_ - 1] & topmask_) == 0);
00258 return hasnone;
00259 }
00260
00261 template <size_t Tsize> inline ::std::string
00262 simple_bitset<Tsize>::to_string() const
00263 {
00264 return _base_simple_bitset::to_string(bits_, bitslen_, topmask_);
00265 }
00266
00267 #include <LCore/simple_bitset_optim.h>
00268
00269 template <size_t Tsize> inline const simple_bitset<Tsize>
00270 operator &(const simple_bitset<Tsize> &a, const simple_bitset<Tsize> &b)
00271 {
00272 simple_bitset<Tsize> res = a;
00273 res &= b;
00274 return res;
00275 }
00276
00277 template <size_t Tsize> inline const simple_bitset<Tsize>
00278 operator |(const simple_bitset<Tsize> &a, const simple_bitset<Tsize> &b)
00279 {
00280 simple_bitset<Tsize> res = a;
00281 res |= b;
00282 return res;
00283 }
00284
00285 template <size_t Tsize> inline const simple_bitset<Tsize>
00286 operator ^(const simple_bitset<Tsize> &a, const simple_bitset<Tsize> &b)
00287 {
00288 simple_bitset<Tsize> res = a;
00289 res ^= b;
00290 return res;
00291 }
00292
00293 }
00294 }
00295
00296 #endif