00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef SHTTL_XBITSET_H
00033 #define SHTTL_XBITSET_H
00034
00035 #include <stdexcept>
00036 #include <string>
00037 #include <iostream>
00038
00039 #include "bit.h"
00040 #include "bitset.h"
00041
00042
00043 namespace shttl
00044 {
00045
00046 template<int N>
00047 class xbitset : public shttl_bitset<N>
00048 {
00049 public:
00050
00051
00052 typedef xbitset<N> this_type;
00053 typedef shttl_bitset<N> base_type;
00054 typedef ssize_t size_type;
00055
00056
00057 using base_type::size;
00058 using base_type::to_ulong;
00059
00060
00061 xbitset(const u64 v = 0) : base_type(v)
00062 {
00063 }
00064
00065 template<class C, class R, class A>
00066 explicit xbitset(
00067 const std::basic_string<C, R, A>& s,
00068 typename std::basic_string<C, R, A>::size_type p = 0,
00069 typename std::basic_string<C, R, A>::size_type l = -1
00070 ) :
00071 base_type(s, p, l)
00072 {
00073 }
00074
00075 xbitset(const xbitset& rhs) : base_type(rhs)
00076 {
00077 }
00078
00079 xbitset& operator=(const xbitset& rhs)
00080 {
00081 base_type::operator=(rhs);
00082 return *this;
00083 }
00084
00085
00086
00087 class const_reference {
00088
00089 public:
00090
00091 operator bool() const { return _i.test(_p); }
00092 bool operator~() const { return !_i.test(_p); }
00093
00094 private:
00095
00096 const this_type& _i;
00097 const size_type _p;
00098
00099 const_reference(const this_type& i, const size_type p) :
00100 _i(i),
00101 _p(p)
00102 {
00103 }
00104
00105 };
00106
00107 class reference : public base_type::reference {
00108
00109 public:
00110
00111 reference& operator=(const const_reference& r)
00112 {
00113 _i.set(_p, r.operator bool());
00114 return *this;
00115 }
00116
00117 private:
00118
00119 using base_type::reference::_i;
00120 using base_type::reference::_p;
00121 };
00122
00123
00124
00125 const const_reference operator[](const size_type p) const
00126 {
00127 return const_reference(this, p);
00128 }
00129
00130 const const_reference at(const size_type p) const
00131 {
00132 if (p < 0 || size() <= p){
00133 throw std::out_of_range("xbitset::at");
00134 }
00135
00136 return operator[](p);
00137 }
00138
00139
00140
00141 bool all() const
00142 {
00143 for (int p = 0; p < N; ++p)
00144 if (!base_type::test(p))
00145 return false;
00146 return true;
00147 }
00148
00149 bool none() const
00150 {
00151 for (int p = 0; p < N; ++p)
00152 if (base_type::test(p))
00153 return false;
00154 return true;
00155 }
00156
00157 bool any() const
00158 {
00159 for (int p = 0; p < N; ++p)
00160 if (base_type::test(p))
00161 return true;
00162 return false;
00163 }
00164
00165 bool any( const bool v ) const { return v ? any() : !all(); }
00166 bool none( const bool v ) const { return v ? none() : all(); }
00167 bool all( const bool v ) const { return v ? all() : none(); }
00168
00169
00170
00171 public:
00172
00173 static const size_type npos = -1;
00174
00175 size_type
00176 find(const int v = 0, const size_type s = 0) const
00177 {
00178 #ifdef SHTTL_DEBUG
00179 if (s < 0 || size() <= s){
00180 throw std::out_of_range("xbitset::find");
00181 }
00182 #endif
00183
00184 if (v == 0 && s == 0 && size() <= 4)
00185 return _find_0_map[to_ulong()];
00186 else
00187 return _find(v, s);
00188 }
00189
00190 size_type
00191 find_and_flip(const int v = 0, const size_type s = 0)
00192 {
00193 #ifdef SHTTL_DEBUG
00194 if (s < 0 || size() <= s){
00195 throw std::out_of_range("xbitset::find_and_flip");
00196 }
00197 #endif
00198
00199 const size_type p = find(v, s);
00200 if (p != npos)
00201 base_type::flip(p);
00202 return p;
00203 }
00204
00205
00206
00207 void reset(void) {
00208 *this = 0;
00209 }
00210
00211 this_type& operator++()
00212 {
00213 u64 v = to_ulong();
00214 if (v < umax(size()))
00215 *this = v + 1;
00216 return *this;
00217 }
00218
00219 this_type& operator--()
00220 {
00221 u64 v = to_ulong();
00222 if (v > umin(size()))
00223 *this = v - 1;
00224 return *this;
00225 }
00226
00227 u64 operator++(int)
00228 {
00229 u64 v = to_ulong();
00230 if (v < umax(size()))
00231 *this = v + 1;
00232 return v;
00233 }
00234
00235 u64 operator--(int)
00236 {
00237 u64 v = to_ulong();
00238 if (v > umin(size()))
00239 *this = v - 1;
00240 return v;
00241 }
00242
00243 this_type& inc()
00244 {
00245 u64 v = to_ulong();
00246 if (v < umax(size()))
00247 *this = v + 1;
00248 else
00249 throw std::overflow_error("xbitset::inc");
00250 return *this;
00251 }
00252
00253 this_type& dec()
00254 {
00255 u64 v = to_ulong();
00256 if (v > umin(size()))
00257 *this = v - 1;
00258 else
00259 throw std::underflow_error("xbitset::dec");
00260 return *this;
00261 }
00262
00263
00264
00265 protected:
00266
00267 size_type _find(const int v, const size_type s) const ;
00268
00269 static const signed char _find_0_map[16];
00270
00271 };
00272
00273
00274
00275
00276
00277 template<int N>
00278 typename xbitset<N>::size_type
00279 xbitset<N>::_find(const int v, const typename xbitset<N>::size_type s) const
00280
00281 {
00282 const bool b = v != 0;
00283 for (size_type p = s; p < size(); ++p)
00284 if (base_type::test(p) == b)
00285 return p;
00286 return npos;
00287 }
00288
00289
00290
00291
00292 template<int N>
00293 const signed char xbitset<N>::_find_0_map[16] = {
00294 -1
00295 };
00296
00297 template<>
00298 const signed char xbitset<1>::_find_0_map[16] = {
00299 0,
00300 -1
00301 };
00302
00303 template<>
00304 const signed char xbitset<2>::_find_0_map[16] = {
00305 0,
00306 1,
00307 0,
00308 -1
00309 };
00310
00311 template<>
00312 const signed char xbitset<3>::_find_0_map[16] = {
00313 0,
00314 1,
00315 0,
00316 2,
00317 0,
00318 1,
00319 0,
00320 -1
00321 };
00322
00323 template<>
00324 const signed char xbitset<4>::_find_0_map[16] = {
00325 0,
00326 1,
00327 0,
00328 2,
00329 0,
00330 1,
00331 0,
00332 3,
00333 0,
00334 1,
00335 0,
00336 2,
00337 0,
00338 1,
00339 0,
00340 -1
00341 };
00342
00343 }
00344
00345 #endif // SHTTL_XBITSET_H