00001 #ifndef strbitset_h
00002 #define strbitset_h
00003
00016 #include <string>
00017 #include <map>
00018 #include <vector>
00019 #include <iostream>
00020 #include <fstream>
00021
00022 namespace pat {
00023
00024 class strbitset {
00025 public:
00026
00027
00028 class index_type {
00029 public:
00030 typedef unsigned int size_t;
00031
00032 friend class strbitset;
00033
00034 index_type() :bitset_(0), i_(0) {}
00035
00036 index_type( strbitset const * b, std::string const & s) :
00037 bitset_(b)
00038 {
00039 if ( bitset_ ) {
00040 i_ = bitset_->index(s);
00041 } else {
00042 i_ = 0;
00043 }
00044 }
00045
00046 std::string const & str() const { return bitset_->index(i_);}
00047
00048 bool operator< ( index_type const & r) const { return i_ < r.i_;}
00049 bool operator> ( index_type const & r) const { return i_ > r.i_;}
00050 bool operator<=( index_type const & r) const { return i_ <= r.i_;}
00051 bool operator>=( index_type const & r) const { return i_ >= r.i_;}
00052 bool operator==( index_type const & r) const { return i_ == r.i_;}
00053
00054 friend std::ostream & operator<<(std::ostream & out, const index_type & r);
00055
00056 protected:
00057 strbitset const * bitset_;
00058 size_t i_;
00059 };
00060
00061
00062 friend class index_type;
00063
00064
00065 typedef unsigned int size_t;
00066 typedef std::map<std::string, size_t> str_index_map;
00067 typedef std::vector<bool> bit_vector;
00068
00070 strbitset() {
00071 clear();
00072 }
00073
00075 void clear() {
00076 map_.clear();
00077 bits_.clear();
00078 }
00079
00081 operator bool() const {
00082 bool b = true;
00083 for ( bit_vector::const_iterator bitsBegin = bits_.begin(),
00084 bitsEnd = bits_.end(), ibit = bitsBegin;
00085 ibit != bitsEnd; ++ibit ) {
00086 if ( *ibit == false ) b = false;
00087 }
00088 return b;
00089 }
00090
00092 bool operator!() const {
00093 return ! ( operator bool() );
00094 }
00095
00099 void push_back( std::string s ) {
00100 if ( map_.find(s) == map_.end() ) {
00101 map_[s] = bits_.size();
00102 bits_.resize( bits_.size() + 1 );
00103 *(bits_.rbegin()) = false;
00104 } else {
00105 std::cout << "Duplicate entry " << s << ", not added to registry" << std::endl;
00106 }
00107 }
00108
00109
00111 void print(std::ostream & out) const {
00112 for( str_index_map::const_iterator mbegin = map_.begin(),
00113 mend = map_.end(),
00114 mit = mbegin;
00115 mit != mend; ++mit ) {
00116 char buff[100];
00117 sprintf(buff, "%10s = %6d", mit->first.c_str(), bits_.at(mit->second));
00118 out << buff << std::endl;
00119 }
00120 }
00121
00123 bit_vector::const_reference operator[] ( const std::string s) const {
00124 size_t index = this->index(s);
00125 return bits_.operator[](index);
00126 }
00127
00128 bit_vector::const_reference operator[] ( index_type const & i) const {
00129 return bits_.operator[](i.i_);
00130 }
00131
00133 bit_vector::reference operator[] ( const std::string s) {
00134 size_t index = this->index(s);
00135 return bits_.operator[](index);
00136 }
00137
00138 bit_vector::reference operator[] ( index_type const & i ) {
00139 return bits_.operator[](i.i_);
00140 }
00141
00142
00144 strbitset & set( bool val = true) {
00145 for ( bit_vector::iterator ibegin = bits_.begin(),
00146 iend = bits_.end(), i = ibegin;
00147 i != iend; ++i ) {
00148 *i = val;
00149 }
00150 return *this;
00151 }
00152
00154 strbitset & flip() {
00155 for ( bit_vector::iterator ibegin = bits_.begin(),
00156 iend = bits_.end(), i = ibegin;
00157 i != iend; ++i ) {
00158 *i = ! (*i);
00159 }
00160 return *this;
00161 }
00162
00164 strbitset & set( std::string s, bool val = true) {
00165 (*this)[s] = val;
00166 return *this;
00167 }
00168
00169 strbitset & set( index_type const & i, bool val = true) {
00170 (*this)[i] = val;
00171 return *this;
00172 }
00173
00174
00176 strbitset & flip( std::string s) {
00177 (*this)[s] = !( (*this)[s] );
00178 return *this;
00179 }
00180
00181 strbitset & flip( index_type const & i ) {
00182 (*this)[i] = !( (*this)[i] );
00183 return *this;
00184 }
00185
00187 strbitset operator~() {
00188 strbitset ret(*this);
00189 for ( bit_vector::iterator ibegin = ret.bits_.begin(),
00190 iend = ret.bits_.end(), i = ibegin;
00191 i != iend; ++i ) {
00192 *i = !(*i);
00193 }
00194 return ret;
00195 }
00196
00198 strbitset & operator&=( const strbitset & r) {
00199 if ( map_.size() != r.map_.size() ) {
00200 std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
00201 } else {
00202 str_index_map::iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
00203 for ( ; i != iend; ++i ) {
00204 std::string key = i->first;
00205 str_index_map::const_iterator j = r.map_.find( key );
00206 if ( j == r.map_.end() ) {
00207 std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
00208 } else {
00209 (*this)[key] = (*this)[key] && r[key];
00210 }
00211 }
00212 }
00213 return *this;
00214 }
00215
00216
00218 strbitset & operator|=( const strbitset & r) {
00219 if ( map_.size() != r.map_.size() ) {
00220 std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
00221 } else {
00222 str_index_map::iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
00223 for ( ; i != iend; ++i ) {
00224 std::string key = i->first;
00225 str_index_map::const_iterator j = r.map_.find( key );
00226 if ( j == r.map_.end() ) {
00227 std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
00228 } else {
00229 (*this)[key] = (*this)[key] || r[key];
00230 }
00231 }
00232 }
00233 return *this;
00234 }
00235
00236
00237
00239 strbitset & operator^=( const strbitset & r) {
00240 if ( map_.size() != r.map_.size() ) {
00241 std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
00242 } else {
00243 str_index_map::iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
00244 for ( ; i != iend; ++i ) {
00245 std::string key = i->first;
00246 str_index_map::const_iterator j = r.map_.find( key );
00247 if ( j == r.map_.end() ) {
00248 std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
00249 } else {
00250 (*this)[key] = ( (*this)[key] || r[key]) && ! ((*this)[key] && r[key]);
00251 }
00252 }
00253 }
00254 return *this;
00255 }
00256
00257
00258
00259
00260
00262 bool operator==( const strbitset & r) const {
00263 if ( map_.size() != r.map_.size() ) {
00264 std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
00265 } else {
00266 str_index_map::const_iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
00267 for ( ; i != iend; ++i ) {
00268 std::string key = i->first;
00269 str_index_map::const_iterator j = r.map_.find( key );
00270 if ( j == r.map_.end() ) {
00271 std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
00272 } else {
00273 if ( (*this)[key] != r[key] ) return false;
00274 }
00275 }
00276 }
00277 return true;
00278 }
00279
00281 bool operator==( bool b ) const {
00282 bool result = true;
00283 for ( bit_vector::const_iterator iBegin = bits_.begin(),
00284 iEnd = bits_.end(), ibit = iBegin;
00285 ibit != iEnd; ++ibit ) {
00286 result &= ( *ibit == b );
00287 }
00288 return result;
00289 }
00290
00291
00293 bool operator!=( const strbitset & r) const {
00294 return ! (operator==(r));
00295 }
00296
00298 bool operator!=( bool b ) const {
00299 return ! ( operator!=(b));
00300 }
00301
00303 size_t count() const {
00304 size_t ret = 0;
00305 for ( bit_vector::const_iterator ibegin = bits_.begin(),
00306 iend = bits_.end(), i = ibegin;
00307 i != iend; ++i ) {
00308 if ( *i ) ++ret;
00309 }
00310 return ret;
00311 }
00312
00313
00314
00316 size_t any() const {
00317 for ( bit_vector::const_iterator ibegin = bits_.begin(),
00318 iend = bits_.end(), i = ibegin;
00319 i != iend; ++i ) {
00320 if ( *i ) return true;
00321 }
00322 return true;
00323 }
00324
00326 size_t none () const {
00327 return !any();
00328 }
00329
00331 bool test(std::string s) const {
00332 return (*this)[s] == true;
00333 }
00334
00335 bool test(index_type const &i) const {
00336 return (*this)[i] == true;
00337 }
00338
00340 const bit_vector& bits() const {
00341 return bits_;
00342 }
00343
00344
00346 const std::vector<std::string> strings() const {
00347 std::vector<std::string> strings;
00348 strings.resize(bits_.size());
00349 for (str_index_map::const_iterator it = map_.begin(),
00350 end = map_.end(); it != end; ++it){
00351 strings[it->second] = it->first;
00352 }
00353 return strings;
00354 }
00355
00356
00357
00358 friend strbitset operator&(const strbitset& l, const strbitset& r);
00359 friend strbitset operator|(const strbitset& l, const strbitset& r);
00360 friend strbitset operator^(const strbitset& l, const strbitset& r);
00361
00362
00363 private:
00364
00365
00368 size_t index(std::string s) const {
00369 str_index_map::const_iterator f = map_.find(s);
00370 if ( f == map_.end() ) {
00371 std::cout << "Cannot find " << s << ", returning size()" << std::endl;
00372 return map_.size();
00373 } else {
00374 return f->second;
00375 }
00376 }
00377
00378 std::string const & index( size_t i ) const {
00379 for ( str_index_map::const_iterator f = map_.begin(),
00380 fBegin = map_.begin(), fEnd = map_.end();
00381 f != fEnd; ++f ) {
00382 if ( f->second == i ) return f->first;
00383 }
00384 std::cout << "Cannot find " << i << ", returning dummy" << std::endl;
00385 return dummy_;
00386
00387 }
00388
00389 static const std::string dummy_;
00390 str_index_map map_;
00391 bit_vector bits_;
00392 };
00393
00394 strbitset operator&(const strbitset& l, const strbitset& r);
00395
00396 strbitset operator|(const strbitset& l, const strbitset& r);
00397 strbitset operator^(const strbitset& l, const strbitset& r);
00398
00399
00400
00401 }
00402
00403 #endif