ROSE  0.10.5.0
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 = int64_t>
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 isEmpty() const {
113  return 0 == vector_;
114  }
115 
117  bool isClear(Enum e) const {
118  return !isSet(e);
119  }
120 
122  BitFlags& set(Enum e) {
123  vector_ |= Vector(e);
124  return *this;
125  }
126 
129  vector_ |= other.vector_;
130  return *this;
131  }
132 
134  BitFlags& clear(Enum e) {
135  vector_ &= ~Vector(e);
136  return *this;
137  }
138 
141  vector_ &= ~other.vector_;
142  return *this;
143  }
144 
147  vector_ = Vector(0);
148  return *this;
149  }
150 
152  bool testAndClear(Enum e) {
153  bool retval = isSet(e);
154  clear(e);
155  return retval;
156  }
157 
159  bool testAndSet(Enum e) {
160  bool retval = isSet(e);
161  set(e);
162  return retval;
163  }
164 
166  BitFlags& operator=(Vector v) {
167  vector_ = v;
168  return *this;
169  }
170 
173  vector_ = other.vector_;
174  return *this;
175  }
176 
180  BitFlags operator|(BitFlags other) const {
181  return vector_ | other.vector_;
182  }
183  BitFlags operator|(Enum e) const {
184  return vector_ | Vector(e);
185  }
192  return vector_ & other.vector_;
193  }
194  BitFlags intersection(Enum e) const {
195  return vector_ & Vector(e);
196  }
197  BitFlags operator&(BitFlags other) const {
198  return intersection(other);
199  }
200  BitFlags operator&(Enum e) const {
201  return intersection(e);
202  }
208  bool operator==(BitFlags other) const {
209  return vector_ == other.vector_;
210  }
211  bool operator!=(BitFlags other) const {
212  return vector_ != other.vector_;
213  }
214  bool operator<(BitFlags other) const {
215  return vector_ < other.vector_;
216  }
217  bool operator<=(BitFlags other) const {
218  return vector_ <= other.vector_;
219  }
220  bool operator>(BitFlags other) const {
221  return vector_ > other.vector_;
222  }
223  bool operator>=(BitFlags other) const {
224  return vector_ >= other.vector_;
225  }
233  std::vector<Enum> split(std::vector<int64_t> constants, Vector &leftovers /*out*/) const {
234  leftovers = Vector(0);
235  std::vector<Enum> retval;
236  std::sort(constants.begin(), constants.end(), moreBits);
237  Vector tmp = vector_;
238  while (tmp) {
239  bool found = false;
240  for (size_t i=0; i<constants.size() && !found; ++i) {
241  if (Vector(tmp & constants[i]) == Vector(constants[i])) {
242  retval.push_back(Enum(constants[i]));
243  tmp &= ~constants[i];
244  found = true;
245  }
246  }
247  if (!found) {
248  leftovers = tmp;
249  tmp = 0;
250  }
251  }
252  return retval;
253  }
254 
259  std::string toString(std::vector<int64_t> constants, const char*(*stringifier)(int64_t)) const {
260  std::string retval;
261  if (vector_ != Vector(0)) {
262  Vector leftovers(0);
263  std::vector<Enum> members = split(constants, leftovers /*out*/);
264  BOOST_FOREACH (Enum member, members) {
265  const char *name = stringifier(member);
266  ASSERT_not_null(name);
267  retval += std::string(retval.empty()?"":"|") + name;
268  }
269  if (leftovers != Vector(0))
270  retval += retval.empty()?"":"|" + (boost::format("%lx") % (unsigned long)leftovers).str();
271  } else {
272  if (const char* name = stringifier(0)) {
273  retval = name;
274  } else {
275  retval = "0";
276  }
277  }
278  return retval;
279  }
280 
281 private:
282  static size_t nBits(Vector vector) {
283  size_t retval = 0;
284  for (size_t i = 0; i < 8*sizeof(Vector); ++i) {
285  if ((vector & (Vector(1) << i)) != 0)
286  ++retval;
287  }
288  return retval;
289  }
290 
291  static bool moreBits(Vector a, Vector b) {
292  return nBits(a) > nBits(b);
293  }
294 };
295 
296 
297 } // namespace
298 
299 #endif
BitFlags & set(BitFlags other)
Set all bits that are set in other.
Definition: BitFlags.h:128
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:134
bool operator==(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:208
bool testAndSet(Enum e)
Test whether a bit is set, then set it.
Definition: BitFlags.h:159
bool operator>=(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:223
bool operator<=(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:217
BitFlags operator&(BitFlags other) const
Create a new vector that's the intersection of two vectors.
Definition: BitFlags.h:197
bool operator>(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:220
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 isEmpty() const
True if no bits are set.
Definition: BitFlags.h:112
std::string toString(std::vector< int64_t > constants, const char *(*stringifier)(int64_t)) const
Convert to string.
Definition: BitFlags.h:259
bool operator!=(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:211
bool testAndClear(Enum e)
Test whether a bit is set, then clear it.
Definition: BitFlags.h:152
BitFlags & clear()
Clear all bits.
Definition: BitFlags.h:146
BitFlags intersection(BitFlags other) const
Create a new vector that's the intersection of two vectors.
Definition: BitFlags.h:191
BitFlags & set(Enum e)
Set the specified bit.
Definition: BitFlags.h:122
BitFlags & operator=(Vector v)
Set the vector to an exact value.
Definition: BitFlags.h:166
bool isClear(Enum e) const
Test whether a bit is clear.
Definition: BitFlags.h:117
std::vector< Enum > split(std::vector< int64_t > constants, Vector &leftovers) const
Split a vector into the individual enum values.
Definition: BitFlags.h:233
BitFlags & operator=(BitFlags other)
Set the vector to the same as another.
Definition: BitFlags.h:172
BitFlags operator|(Enum e) const
Create a new vector that's the union of two vectors.
Definition: BitFlags.h:183
BitFlags & clear(BitFlags other)
Clear all bits that are set in other.
Definition: BitFlags.h:140
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:194
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:200
BitFlags operator|(BitFlags other) const
Create a new vector that's the union of two vectors.
Definition: BitFlags.h:180
bool operator<(BitFlags other) const
Compare two vectors.
Definition: BitFlags.h:214