Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:33:17

0001 #ifndef strbitset_h
0002 #define strbitset_h
0003 
0004 /**
0005   \class    strbitset strbitset.h "CommonTools/Utils/interface/strbitset.h"
0006   \brief    Implements a string-indexed bit_vector
0007 
0008    The strbitset implements a string-indexed bit vector that will allow users
0009    to access the underlying bits by a string name instead of via an index.
0010 
0011   \author Salvatore Rappoccio
0012   \version  $Id: strbitset.h,v 1.7 2010/07/23 01:25:22 srappocc Exp $
0013 */
0014 
0015 #include <string>
0016 #include <map>
0017 #include <vector>
0018 #include <iostream>
0019 #include <fstream>
0020 
0021 namespace pat {
0022 
0023   class strbitset {
0024   public:
0025     class index_type {
0026     public:
0027       typedef unsigned int size_t;
0028 
0029       friend class strbitset;
0030 
0031       index_type() : bitset_(nullptr), i_(0) {}
0032 
0033       index_type(strbitset const* b, std::string const& s) : bitset_(b) {
0034         if (bitset_) {
0035           i_ = bitset_->index(s);
0036         } else {
0037           i_ = 0;
0038         }
0039       }
0040 
0041       std::string const& str() const { return bitset_->index(i_); }
0042 
0043       bool operator<(index_type const& r) const { return i_ < r.i_; }
0044       bool operator>(index_type const& r) const { return i_ > r.i_; }
0045       bool operator<=(index_type const& r) const { return i_ <= r.i_; }
0046       bool operator>=(index_type const& r) const { return i_ >= r.i_; }
0047       bool operator==(index_type const& r) const { return i_ == r.i_; }
0048 
0049       friend std::ostream& operator<<(std::ostream& out, const index_type& r);
0050 
0051     protected:
0052       strbitset const* bitset_;
0053       size_t i_;
0054     };
0055 
0056     friend class index_type;
0057 
0058     // Add typedefs
0059     typedef unsigned int size_t;
0060     typedef std::map<std::string, size_t> str_index_map;
0061     typedef std::vector<bool> bit_vector;
0062 
0063     //! constructor: just clears the bitset and map
0064     strbitset() { clear(); }
0065 
0066     //! clear the bitset and map
0067     void clear() {
0068       map_.clear();
0069       bits_.clear();
0070     }
0071 
0072     ///! cast to bool
0073     operator bool() const {
0074       bool b = true;
0075       for (bit_vector::const_iterator bitsBegin = bits_.begin(), bitsEnd = bits_.end(), ibit = bitsBegin;
0076            ibit != bitsEnd;
0077            ++ibit) {
0078         if (*ibit == false)
0079           b = false;
0080       }
0081       return b;
0082     }
0083 
0084     ///! Logical negation of bool()
0085     bool operator!() const { return !(operator bool()); }
0086 
0087     /// adds an item that is indexed by the string. this
0088     /// can then be sorted, cut, whatever, and the
0089     /// index mapping is kept
0090     void push_back(std::string s) {
0091       if (map_.find(s) == map_.end()) {
0092         map_[s] = bits_.size();
0093         bits_.resize(bits_.size() + 1);
0094         *(bits_.rbegin()) = false;
0095       } else {
0096         std::cout << "Duplicate entry " << s << ", not added to registry" << std::endl;
0097       }
0098     }
0099 
0100     //! print method
0101     void print(std::ostream& out) const {
0102       for (str_index_map::const_iterator mbegin = map_.begin(), mend = map_.end(), mit = mbegin; mit != mend; ++mit) {
0103         char buff[100];
0104         sprintf(buff, "%10s = %6i", mit->first.c_str(), (int)(bits_.at(mit->second)));
0105         out << buff << std::endl;
0106       }
0107     }
0108 
0109     //! access method const
0110     bit_vector::const_reference operator[](const std::string s) const {
0111       size_t index = this->index(s);
0112       return bits_.operator[](index);
0113     }
0114 
0115     bit_vector::const_reference operator[](index_type const& i) const { return bits_.operator[](i.i_); }
0116 
0117     //! access method non-const
0118     bit_vector::reference operator[](const std::string s) {
0119       size_t index = this->index(s);
0120       return bits_.operator[](index);
0121     }
0122 
0123     bit_vector::reference operator[](index_type const& i) { return bits_.operator[](i.i_); }
0124 
0125     //! set method of all bits
0126     strbitset& set(bool val = true) {
0127       for (bit_vector::iterator ibegin = bits_.begin(), iend = bits_.end(), i = ibegin; i != iend; ++i) {
0128         *i = val;
0129       }
0130       return *this;
0131     }
0132 
0133     //! flip method of all bits
0134     strbitset& flip() {
0135       for (bit_vector::iterator ibegin = bits_.begin(), iend = bits_.end(), i = ibegin; i != iend; ++i) {
0136         *i = !(*i);
0137       }
0138       return *this;
0139     }
0140 
0141     //! set method of one bit
0142     strbitset& set(std::string s, bool val = true) {
0143       (*this)[s] = val;
0144       return *this;
0145     }
0146 
0147     strbitset& set(index_type const& i, bool val = true) {
0148       (*this)[i] = val;
0149       return *this;
0150     }
0151 
0152     //! flip method of one bit
0153     strbitset& flip(std::string s) {
0154       (*this)[s] = !((*this)[s]);
0155       return *this;
0156     }
0157 
0158     strbitset& flip(index_type const& i) {
0159       (*this)[i] = !((*this)[i]);
0160       return *this;
0161     }
0162 
0163     //! logical negation
0164     strbitset operator~() {
0165       strbitset ret(*this);
0166       for (bit_vector::iterator ibegin = ret.bits_.begin(), iend = ret.bits_.end(), i = ibegin; i != iend; ++i) {
0167         *i = !(*i);
0168       }
0169       return ret;
0170     }
0171 
0172     //! bitwise and
0173     strbitset& operator&=(const strbitset& r) {
0174       if (map_.size() != r.map_.size()) {
0175         std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
0176       } else {
0177         str_index_map::iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
0178         for (; i != iend; ++i) {
0179           std::string key = i->first;
0180           str_index_map::const_iterator j = r.map_.find(key);
0181           if (j == r.map_.end()) {
0182             std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
0183           } else {
0184             (*this)[key] = (*this)[key] && r[key];
0185           }
0186         }
0187       }
0188       return *this;
0189     }
0190 
0191     //! bitwise or
0192     strbitset& operator|=(const strbitset& r) {
0193       if (map_.size() != r.map_.size()) {
0194         std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
0195       } else {
0196         str_index_map::iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
0197         for (; i != iend; ++i) {
0198           std::string key = i->first;
0199           str_index_map::const_iterator j = r.map_.find(key);
0200           if (j == r.map_.end()) {
0201             std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
0202           } else {
0203             (*this)[key] = (*this)[key] || r[key];
0204           }
0205         }
0206       }
0207       return *this;
0208     }
0209 
0210     //! bitwise xor
0211     strbitset& operator^=(const strbitset& r) {
0212       if (map_.size() != r.map_.size()) {
0213         std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
0214       } else {
0215         str_index_map::iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
0216         for (; i != iend; ++i) {
0217           std::string key = i->first;
0218           str_index_map::const_iterator j = r.map_.find(key);
0219           if (j == r.map_.end()) {
0220             std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
0221           } else {
0222             (*this)[key] = ((*this)[key] || r[key]) && !((*this)[key] && r[key]);
0223           }
0224         }
0225       }
0226       return *this;
0227     }
0228 
0229     //! equality operator
0230     bool operator==(const strbitset& r) const {
0231       if (map_.size() != r.map_.size()) {
0232         std::cout << "strbitset operator&= : bitsets not the same size" << std::endl;
0233       } else {
0234         str_index_map::const_iterator ibegin = map_.begin(), iend = map_.end(), i = ibegin;
0235         for (; i != iend; ++i) {
0236           std::string key = i->first;
0237           str_index_map::const_iterator j = r.map_.find(key);
0238           if (j == r.map_.end()) {
0239             std::cout << "strbitset operator&= : cannot find key " << key << std::endl;
0240           } else {
0241             if ((*this)[key] != r[key])
0242               return false;
0243           }
0244         }
0245       }
0246       return true;
0247     }
0248 
0249     //! equality operator to bool
0250     bool operator==(bool b) const {
0251       bool result = true;
0252       for (bit_vector::const_iterator iBegin = bits_.begin(), iEnd = bits_.end(), ibit = iBegin; ibit != iEnd; ++ibit) {
0253         result &= (*ibit == b);
0254       }
0255       return result;
0256     }
0257 
0258     //! inequality operator
0259     bool operator!=(const strbitset& r) const { return !(operator==(r)); }
0260 
0261     //! inequality operator to bool
0262     bool operator!=(bool b) const { return !(operator==(b)); }
0263 
0264     //! returns number of bits set
0265     size_t count() const {
0266       size_t ret = 0;
0267       for (bit_vector::const_iterator ibegin = bits_.begin(), iend = bits_.end(), i = ibegin; i != iend; ++i) {
0268         if (*i)
0269           ++ret;
0270       }
0271       return ret;
0272     }
0273 
0274     //! returns true if any are set
0275     size_t any() const {
0276       for (bit_vector::const_iterator ibegin = bits_.begin(), iend = bits_.end(), i = ibegin; i != iend; ++i) {
0277         if (*i)
0278           return true;
0279       }
0280       return true;
0281     }
0282 
0283     //! returns true if none are set
0284     size_t none() const { return !any(); }
0285 
0286     //! test
0287     bool test(std::string s) const { return (*this)[s] == true; }
0288 
0289     bool test(index_type const& i) const { return (*this)[i] == true; }
0290 
0291     //! give access to the ordered bits
0292     const bit_vector& bits() const { return bits_; }
0293 
0294     //! give access to the ordered strings
0295     const std::vector<std::string> strings() const {
0296       std::vector<std::string> strings;
0297       strings.resize(bits_.size());
0298       for (str_index_map::const_iterator it = map_.begin(), end = map_.end(); it != end; ++it) {
0299         strings[it->second] = it->first;
0300       }
0301       return strings;
0302     }
0303 
0304     friend strbitset operator&(const strbitset& l, const strbitset& r);
0305     friend strbitset operator|(const strbitset& l, const strbitset& r);
0306     friend strbitset operator^(const strbitset& l, const strbitset& r);
0307 
0308   private:
0309     /// workhorse: this gets the index of "bits" that is pointed to by
0310     /// the string "s"
0311     size_t index(std::string s) const {
0312       str_index_map::const_iterator f = map_.find(s);
0313       if (f == map_.end()) {
0314         std::cout << "Cannot find " << s << ", returning size()" << std::endl;
0315         return map_.size();
0316       } else {
0317         return f->second;
0318       }
0319     }
0320 
0321     std::string const& index(size_t i) const {
0322       for (str_index_map::const_iterator f = map_.begin(), fEnd = map_.end(); f != fEnd; ++f) {
0323         if (f->second == i)
0324           return f->first;
0325       }
0326       std::cout << "Cannot find " << i << ", returning dummy" << std::endl;
0327       return dummy_;
0328     }
0329 
0330     static const std::string dummy_;
0331     str_index_map map_;  //!< map that holds the string-->index map
0332     bit_vector bits_;    //!< the actual bits, indexed by the index in "map_"
0333   };
0334 
0335   strbitset operator&(const strbitset& l, const strbitset& r);
0336 
0337   strbitset operator|(const strbitset& l, const strbitset& r);
0338   strbitset operator^(const strbitset& l, const strbitset& r);
0339 
0340 }  // namespace pat
0341 
0342 #endif