ROSE  0.9.10.205
BitFlags.h
1 #ifndef Rose_BitFlags_H
2 #define Rose_BitFlags_H
3 
4 #include <rosePublicConfig.h>
5 #include <boost/foreach.hpp>
6 #include <boost/format.hpp>
7 #include <boost/serialization/access.hpp>
8 #include <Sawyer/Assert.h>
9 #include <vector>
10 
11 namespace Rose {
12 
58 template<typename E, typename V = unsigned long>
59 class BitFlags {
60 public:
61  typedef E Enum;
62  typedef V Vector;
63 
64 private:
65  Vector vector_;
66 
67 private:
68 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
69  friend class boost::serialization::access;
70 
71  template<class S>
72  void serialize(S &s, const unsigned /*version*/) {
73  s & BOOST_SERIALIZATION_NVP(vector_);
74  }
75 #endif
76 
77 public:
80  : vector_(0) {}
81 
83  BitFlags(Vector v) /*implicit*/
84  : vector_(v) {}
85 
87  Vector vector() const {
88  return vector_;
89  }
90 
92  bool isSet(Enum e) const {
93  return (vector_ & Vector(e)) != 0;
94  }
95 
97  bool isAllSet(BitFlags other) const {
98  return (vector_ & other.vector_) == other.vector_;
99  }
100 
102  bool isAnySet(BitFlags other) const {
103  return (vector_ & other.vector_) != 0;
104  }
105 
107  bool isAnySet() const {
108  return vector_ != 0;
109  }
110 
112  bool isClear(Enum e) const {
113  return !isSet(e);
114  }
115 
117  BitFlags& set(Enum e) {
118  vector_ |= Vector(e);
119  return *this;
120  }
121 
124  vector_ |= other.vector_;
125  return *this;
126  }
127 
129  BitFlags& clear(Enum e) {
130  vector_ &= ~Vector(e);
131  return *this;
132  }
133 
136  vector_ &= ~other.vector_;
137  return *this;
138  }
139 
142  vector_ = Vector(0);
143  return *this;
144  }
145 
147  bool testAndClear(Enum e) {
148  bool retval = isSet(e);
149  clear(e);
150  return retval;
151  }
152 
154  bool testAndSet(Enum e) {
155  bool retval = isSet(e);
156  set(e);
157  return retval;
158  }
159 
161  BitFlags& operator=(Vector v) {
162  vector_ = v;
163  return *this;
164  }
165 
168  vector_ = other.vector_;
169  return *this;
170  }
171 
175  BitFlags operator|(BitFlags other) const {
176  return vector_ | other.vector_;
177  }
178  BitFlags operator|(Enum e) const {
179  return vector_ | Vector(e);
180  }
187  return vector_ & other.vector_;
188  }
189  BitFlags intersection(Enum e) const {
190  return vector_ & Vector(e);
191  }
192  BitFlags operator&(BitFlags other) const {
193  return intersection(other);
194  }
195  BitFlags operator&(Enum e) const {
196  return intersection(e);
197  }
203  bool operator==(BitFlags other) const {
204  return vector_ == other.vector_;
205  }
206  bool operator!=(BitFlags other) const {
207  return vector_ != other.vector_;
208  }
209  bool operator<(BitFlags other) const {
210  return vector_ < other.vector_;
211  }
212  bool operator<=(BitFlags other) const {
213  return vector_ <= other.vector_;
214  }
215  bool operator>(BitFlags other) const {
216  return vector_ > other.vector_;
217  }
218  bool operator>=(BitFlags other) const {
219  return vector_ >= other.vector_;
220  }
228  std::vector<Enum> split(std::vector<long> constants, Vector &leftovers /*out*/) const {
229  leftovers = Vector(0);
230  std::vector<Enum> retval;
231  std::sort(constants.begin(), constants.end(), moreBits);
232  Vector tmp = vector_;
233  while (tmp) {
234  bool found = false;
235  for (size_t i=0; i<constants.size() && !found; ++i) {
236  if (Vector(tmp & constants[i]) == Vector(constants[i])) {
237  retval.push_back(Enum(constants[i]));
238  tmp &= ~constants[i];
239  found = true;
240  }
241  }
242  if (!found) {
243  leftovers = tmp;
244  tmp = 0;
245  }
246  }
247  return retval;
248  }
249 
254  std::string toString(std::vector<long> constants, const char*(*stringifier)(long)) const {
255  std::string retval;
256  if (vector_ != Vector(0)) {
257  Vector leftovers(0);
258  std::vector<Enum> members = split(constants, leftovers /*out*/);
259  BOOST_FOREACH (Enum member, members) {
260  const char *name = stringifier(member);
261  ASSERT_not_null(name);
262  retval += std::string(retval.empty()?"":"|") + name;
263  }
264  if (leftovers != Vector(0))
265  retval += retval.empty()?"":"|" + (boost::format("%lx") % (unsigned long)leftovers).str();
266  } else {
267  if (const char* name = stringifier(0)) {
268  retval = name;
269  } else {
270  retval = "0";
271  }
272  }
273  return retval;
274  }
275 
276 private:
277  static size_t nBits(Vector vector) {
278  size_t retval = 0;
279  for (size_t i = 0; i < 8*sizeof(Vector); ++i) {
280  if ((vector & (Vector(1) << i)) != 0)
281  ++retval;
282  }
283  return retval;
284  }
285 
286  static bool moreBits(Vector a, Vector b) {
287  return nBits(a) > nBits(b);
288  }
289 };
290 
291 
292 } // namespace
293 
294 #endif
BitFlags & set(BitFlags other)
Set all bits that are set in other.
Definition: BitFlags.h:123
bool isAllSet(BitFlags other) const
True if all specified bits are set.
Definition: BitFlags.h:97
BitFlags & clear(Enum e)
Clear the specified bit.
Definition: BitFlags.h:129
bool operator==(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:203
bool testAndSet(Enum e)
Test whether a bit is set, then set it.
Definition: BitFlags.h:154
std::string toString(std::vector< long > constants, const char *(*stringifier)(long)) const
Convert to string.
Definition: BitFlags.h:254
bool operator>=(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:218
bool operator<=(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:212
std::vector< Enum > split(std::vector< long > constants, Vector &leftovers) const
Split a vector into the individual enum values.
Definition: BitFlags.h:228
BitFlags operator&(BitFlags other) const
Create a new vector that's the intersection of two vectors.
Definition: BitFlags.h:192
bool operator>(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:215
Main namespace for the ROSE library.
Stores a vector of enum bit flags.
Definition: BitFlags.h:59
BitFlags(Vector v)
Construct bit vector from value or bit.
Definition: BitFlags.h:83
bool isAnySet() const
True if any bit is set.
Definition: BitFlags.h:107
bool operator!=(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:206
bool testAndClear(Enum e)
Test whether a bit is set, then clear it.
Definition: BitFlags.h:147
BitFlags & clear()
Clear all bits.
Definition: BitFlags.h:141
BitFlags intersection(BitFlags other) const
Create a new vector that's the intersection of two vectors.
Definition: BitFlags.h:186
BitFlags & set(Enum e)
Set the specified bit.
Definition: BitFlags.h:117
BitFlags & operator=(Vector v)
Set the vector to an exact value.
Definition: BitFlags.h:161
bool isClear(Enum e) const
Test whether a bit is clear.
Definition: BitFlags.h:112
BitFlags & operator=(BitFlags other)
Set the vector to the same as another.
Definition: BitFlags.h:167
BitFlags operator|(Enum e) const
Create a new vector that's the union of two vectors.
Definition: BitFlags.h:178
BitFlags & clear(BitFlags other)
Clear all bits that are set in other.
Definition: BitFlags.h:135
BitFlags()
Default constructor with all bits clear.
Definition: BitFlags.h:79
bool isAnySet(BitFlags other) const
True if any of the specified bits are set.
Definition: BitFlags.h:102
bool isSet(Enum e) const
Test whether a bit is set.
Definition: BitFlags.h:92
BitFlags intersection(Enum e) const
Create a new vector that's the intersection of two vectors.
Definition: BitFlags.h:189
Vector vector() const
Current value of the bit vector.
Definition: BitFlags.h:87
BitFlags operator&(Enum e) const
Create a new vector that's the intersection of two vectors.
Definition: BitFlags.h:195
BitFlags operator|(BitFlags other) const
Create a new vector that's the union of two vectors.
Definition: BitFlags.h:175
bool operator<(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:209