atlas  0.6
bitset.h
Go to the documentation of this file.
1 
5 /*
6  This is bitset.h.
7 
8  Copyright (C) 2004,2005 Fokko du Cloux
9  part of the Atlas of Lie Groups and Representations
10 
11  For license information see the LICENSE file
12 */
13 
14 #ifndef BITSET_H /* guard against multiple inclusions */
15 #define BITSET_H
16 
17 #include "bitset_fwd.h"
18 
19 #include <iterator>
20 
21 #include "bits.h"
22 #include "constants.h"
23 
24 /******** type definitions ***************************************************/
25 
26 namespace atlas {
27 
28 namespace bitset {
29 
30 /*****************************************************************************
31 
32  The |BitSet| class has essentially the functionality of the |stl::bitset
33  class| from the STL, but I have redone it because I needed some things that
34  bitset doesn't seem to provide. This is a very important data type for the
35  program, and it is crucial that it should be efficiently implemented. [Fokko]
36 
37  An important difference with |stl::bitset| is that whereas the latter models
38  sets of exactly |n| bits, where |n| is the template parameter, |BitSet| will
39  often be used to model sets of at most |n| bits. The exact size is not
40  stored in the |BitSet| for efficiency reasons, and is therefore supplied
41  explicitly to various methods; the class guarantees that if the same size is
42  systematically used with an object, then no bits beyond that limit will be
43  set. Then iterators of the set bits in the |BitSet| can be safely used. One
44  consequence of this is that there can be no |operator~|, but rather a method
45  |complement| is defined with a second |size| argument.
46 
47  Only fixed template instances are defined here, the template for general |n|
48  is left undefined. The intention is to use |BitSet| for small bitmaps with
49  size bounded at compile time, typically |constants::RankMax|. This allows
50  for optimal speed, at the cost of some code duplication.
51 
52  Just as for the implementation of bitset in the STL that I took as a model,
53  the template paramter |n| is passed to a base class template |BitSetBase|
54  after conversion to number of |unsigned long|s needed rather than bits.
55  Only a few instantiations of |BitSetBase| are provided, currently only the
56  single-word vesrion is complete and the 2-word version is partially defined.
57 
58  The main difference with the STL is the |to_ulong()| method; mine will
59  truncate the bitset when the number of bits is too long, instead of
60  throwing an exception.
61 
62  No bit-references are implemented, and |operator[]| is defined as accessor,
63  equivalent to |test()|. In other respects method naming conventions are not
64  yet coherent with those of |BitMap|, a desirable future change.
65 
66  The output operator is in io/ioutils.h.
67 
68 ******************************************************************************/
69 
70 /*
71  First a template class BitSetBase is defined, which provides the basic
72  implementation (a small fixed number of unsigned long integers), but not
73  yet the desired interface. Instances of the template class BitSet will be
74  privately derived from instances of BitSetBase (with a different argument).
75 */
76 
77 template <size_t n> class BitSetBase;
78 
89 template<> class BitSetBase<1>
90 {
94  unsigned long d_bits;
95 
96  protected:
97 
98 // associated types
99  class iterator;
100 
101 // constructors
102  BitSetBase<1>() : d_bits(0) {}
103  explicit BitSetBase<1>(unsigned long b): d_bits(b) {}
104 
109  template<size_t m>
110  explicit BitSetBase<1>(const BitSet<m>& b) : d_bits(b.to_ulong(0)) {}
111 
112 // accessors
113 
114  public:
115  bool operator==(const BitSetBase<1>& b) const { return d_bits == b.d_bits; }
116  bool operator!=(const BitSetBase<1>& b) const { return d_bits != b.d_bits; }
117  bool operator< (const BitSetBase<1>& b) const { return d_bits < b.d_bits; }
118 
119  bool any() const { return d_bits!=0; }
120  bool none() const { return d_bits==0; }
121 
122  bool any(const BitSetBase<1>& b) const
123  { return (d_bits & b.d_bits)!=0; }
124  bool contains (const BitSetBase<1>& b) const
125  { return (~d_bits & b.d_bits)==0; }
126 
127  unsigned int count() const { return bits::bitCount(d_bits); }
128  unsigned int firstBit() const // index of least set bit; |longBits| if none
129  { return bits::firstBit(d_bits); }
130  unsigned int lastBit() const // index of highest set bit PLUS ONE, 0 if none
131  { return bits::lastBit(d_bits); }
132 
133  bool test(unsigned int j) const
134  { return (d_bits & constants::bitMask[j])!=0; }
135 
136  unsigned int position(unsigned int j) const // rank among set bits of bit |j|
137  { return bits::bitCount(d_bits & constants::lMask[j]); }
138 
139  bool scalarProduct(const BitSetBase<1>& b) const
140  { return bits::bitCount(d_bits&b.d_bits)%2 != 0; }
141 
142  unsigned long to_ulong() const { return d_bits; }
143  unsigned long to_ulong(unsigned int n) const { return n==0 ? d_bits : 0; }
144 
145  iterator begin() const;
146 
147 // manipulators
148 
149  protected: // these cannot be called directly: no return value is available
150  void operator^= (const BitSetBase<1>& b) { d_bits ^= b.d_bits; }
151  void operator|= (const BitSetBase<1>& b) { d_bits |= b.d_bits; }
152  void operator&= (const BitSetBase<1>& b) { d_bits &= b.d_bits; }
153  void andnot(const BitSetBase<1>& b) { d_bits &= ~b.d_bits; }
154 
155  // next two methods make sure that shift by |constants::longBits| yields 0.
156  void operator<<= (unsigned int c)
157  {
158  if (c < constants::longBits) // bit shifts by more than this are undefined!
159  d_bits <<= c;
160  else
161  d_bits = 0ul; // simulate shifting out of all bits
162  }
163  void operator>>= (unsigned int c)
164  {
165  if (c < constants::longBits) // bit shifts by more than this are undefined!
166  d_bits >>= c;
167  else
168  d_bits = 0ul; // simulate shifting out of all bits
169  }
170 
171  void flip(unsigned int j) { d_bits ^= constants::bitMask[j]; }
172  void reset() { d_bits = 0ul; }
173  void reset(unsigned int j) { d_bits &= ~constants::bitMask[j]; }
174  void set(unsigned int j) { d_bits |= constants::bitMask[j]; }
175  void fill(unsigned int limit) { d_bits |= constants::lMask[limit]; }
176 
177  void complement(unsigned int limit) { d_bits ^= constants::lMask[limit]; }
178  void truncate(unsigned int limit)
179  { if (limit<constants::longBits) d_bits &= constants::lMask[limit]; }
180 
181  void slice(const BitSetBase<1>& c); // extract bits set in |c|, compacting
182  void unslice(const BitSetBase<1>& c); // expand bits to positions set in |c|
183  void swap(BitSetBase<1>& source) { std::swap(d_bits,source.d_bits); }
184 
185  }; // |class BitSetBase<1>|
186 
194 template<> class BitSetBase<2>
195 {
196  unsigned long d_bits0,d_bits1;
197 
198  protected:
199 
200 // associated types
201  class iterator;
202 
203 // constructors and destructors
204  BitSetBase<2>() { d_bits0 = 0ul; d_bits1 = 0ul; }
205 
223  explicit BitSetBase<2>(unsigned long b) { d_bits0 = b; d_bits1 = 0ul; }
224 
225 // copy constructor, possibly from from other (shorter) size
226  template<size_t m>
227  explicit BitSetBase<2>(const BitSet<m>& b)
228  {
229  d_bits0 = b.to_ulong(0);
230  d_bits1 = b.to_ulong(1);
231  }
232 
233 // accessors
234 
235  public:
236  bool operator==(const BitSetBase<2>& b) const
237  { return d_bits0==b.d_bits0 and d_bits1==b.d_bits1; }
238  bool operator!=(const BitSetBase<2>& b) const
239  { return d_bits0!=b.d_bits0 or d_bits1!=b.d_bits1; }
240  bool operator< (const BitSetBase<2>& b) const
241  { return d_bits1==b.d_bits1 ? d_bits0<b.d_bits0 : d_bits1<b.d_bits1; }
242 
243  bool any() const { return d_bits0!=0 or d_bits1!=0; }
244  bool none() const { return d_bits0==0 and d_bits1==0; }
245 
246  bool any(const BitSetBase<2>& b) const
247  { return (d_bits0 & b.d_bits0)!=0 or (d_bits1 & b.d_bits1)!=0; }
248  bool contains (const BitSetBase<2>& b) const
249  { return (b.d_bits0 & ~d_bits0)==0 and (b.d_bits1 & ~d_bits1)==0; }
250 
251  unsigned int count() const
252  { return bits::bitCount(d_bits0) + bits::bitCount(d_bits1); }
253  unsigned int firstBit() const;
254  unsigned int lastBit() const;
255  bool test(unsigned int j) const;
256  unsigned int position(unsigned int j) const;
257  bool scalarProduct(const BitSetBase<2>& b) const;
258 
259  unsigned long to_ulong() const { return d_bits0; }
260  unsigned long to_ulong(unsigned int n) const
261  { return n==0 ? d_bits0 : n==1 ? d_bits1 : 0; }
262 
263  iterator begin() const;
264 
265 // manipulators
266 
267  void operator^= (const BitSetBase<2>& b);
268  void operator|= (const BitSetBase<2>& b);
269  void operator&= (const BitSetBase<2>& b);
270  void operator<<= (unsigned int c);
271  void operator>>= (unsigned int c);
272  void andnot(const BitSetBase<2>& b);
273  void flip(unsigned int j);
274 
275  void reset() { d_bits0 = 0ul; d_bits1 = 0ul; }
276  void reset(unsigned int j) ;
277  void set(unsigned int j);
278  void fill(unsigned int limit);
279 
280  void complement(unsigned int limit);
281  void truncate(unsigned int limit);
282 
283  void slice(const BitSetBase<2>& c); // extract bits set in |c|, compacting
284  void unslice(const BitSetBase<2>& c); // expand bits to positions set in |c|
285  void swap(BitSetBase<2>& source);
286  }; // |class BitSetBase<2>|
287 
288 
299 template<size_t n> struct BaseSize
300 {
301  static const size_t value = (n + constants::posBits)/constants::longBits;
302 }; // |struct BaseSize|
303 
304 // the actual BitSet class
321 template<size_t n> class BitSet
322  : public BitSetBase<BaseSize<n>::value>
323 {
325 
326  public:
327 
328 // associated types; there are only constant iterators
329  struct iterator : public Base::iterator
330  {
331  // associated types
332 
333  typedef std::forward_iterator_tag iterator_category;
334  typedef unsigned int value_type;
335 
336  iterator() : Base::iterator() {} // zero (end) iterator
337  explicit iterator(const typename Base::iterator& b) : Base::iterator(b) {}
338 
339  };
341 
342 // constructors and destructors
343  BitSet() : Base() {}
344  explicit BitSet(unsigned long b) : Base(b) {} // set at most |longBits| bits
345 
346  template<typename I> // integer type
347  explicit BitSet(const std::vector<I>& v); // takes parity bit of each entry
348 
350  template<size_t m> BitSet(const BitSet<m>& b) : Base(b) {}
351 
352 // accessors
353 
354 #if 0 // these are now publicly inherited methods
355  bool operator== (const BitSet& b) const { return Base::operator== (b); }
356  bool operator!= (const BitSet& b) const { return Base::operator!= (b); }
357  bool operator< (const BitSet& b) const { return Base::operator< (b); }
358 
359  bool any() const { return Base::any(); }
360  bool none() const { return Base::none(); }
361 
362  bool any(const BitSet& b) const { return Base::any(b); }
363  bool contains(const BitSet& b) const { return Base::contains(b); }
364 
365  unsigned int count() const { return Base::count(); }
366  unsigned int firstBit() const { return Base::firstBit(); }
367  unsigned int lastBit() const { return Base::lastBit(); }
368 
369  bool test(unsigned int j) const { return Base::test(j); }
370 
371  // rank among the set bits of bit number |j| (assuming it were set)
372  unsigned int position(unsigned int j) const { return Base::position(j); }
373 
374  bool scalarProduct(const BitSet& b) const { return Base::scalarProduct(b); }
375 
376  unsigned long to_ulong() const { return Base::to_ulong(); }
377  unsigned long to_ulong(unsigned int i) const { return Base::to_ulong(i); }
378 #endif
379 
380  iterator begin() const { return iterator(Base::begin()); }
381  iterator end() const { return iterator(); } // zero value is end indicator
382 
383 // manipulators
384 
385  BitSet& operator^= (const BitSet& b) { Base::operator^=(b); return *this; }
386  BitSet& operator|= (const BitSet& b) { Base::operator|=(b); return *this; }
387  BitSet& operator&= (const BitSet& b) { Base::operator&=(b); return *this; }
388 
389  BitSet& operator<<= (unsigned int c) { Base::operator<<=(c); return *this; }
390  BitSet& operator>>= (unsigned int c) { Base::operator>>=(c); return *this; }
391 
392  BitSet& andnot (const BitSet& b) { Base::andnot(b); return *this; }
393  BitSet& flip(unsigned int j) { Base::flip(j); return *this; }
394 
395  BitSet& reset() { Base::reset(); return *this; }
396  BitSet& reset(unsigned int j) { Base::reset(j); return *this; }
397  BitSet& set(unsigned int j) { Base::set(j); return *this; }
398  BitSet& set(unsigned int j, bool b)
399  { if (b) Base::set(j); else Base::reset(j); return *this; }
400  BitSet& fill(unsigned int limit) { Base::fill(limit); return *this; }
401  BitSet& complement(unsigned int limit)
402  { Base::complement(limit); return *this; }
403  BitSet& truncate(unsigned int m) { Base::truncate(m); return *this; }
404 
405  BitSet& slice(const BitSet& c) { Base::slice(c); return *this; }
406  BitSet& unslice(const BitSet& c) { Base::unslice(c); return *this; }
407 
408  void swap(BitSet& source) { Base::swap(source); }
409 
410  // accessors (non inherited)
411 
412  bool operator[] (unsigned int j) const { return Base::test(j); }
413 
414  // non-assignment logical operators added by MvL
415  BitSet operator& (const BitSet& b) const // logical AND
416  { BitSet t(*this); return t&=b; }
417  BitSet operator| (const BitSet& b) const // logical OR
418  { BitSet t(*this); return t|=b; }
419  BitSet operator^ (const BitSet& b) const // logical XOR
420  { BitSet t(*this); return t^=b; }
421  BitSet operator- (const BitSet& b) const // logical difference (AND NOT)
422  { BitSet t(*this); return t.andnot(b); }
423 
424 
425  bool dot(BitSet b) const { return Base::scalarProduct(b); }
426 
427 }; // |class BitSet|
428 
429 
430 
432 class BitSetBase<1>::iterator
433  : public std::iterator<std::input_iterator_tag,unsigned int>
434 {
435  unsigned long d_bits; // iterator contains a copy of the set iterated over
436 
437  public:
438 
439 // constructors and destructors
440  iterator() : d_bits(0ul) {}
441  explicit iterator(const BitSetBase<1>& b) : d_bits(b.to_ulong()) {}
442 
443 // accessors
444  bool operator== (const iterator& i) const; // can usefully test for end
445  bool operator!= (const iterator& i) const; // can usefully test for end
446  unsigned int operator* () const { return bits::firstBit(d_bits); }
447  bool operator() () const { return d_bits!=0; }
448 
449 // manipulators
450  iterator& operator++ () { d_bits &= d_bits-1; return *this; }
451  iterator operator++ (int) { iterator tmp(*this); ++(*this); return tmp; }
452 }; // |class BitSetBase<1>::iterator|
453 
454 class BitSetBase<2>::iterator
455  : public std::iterator<std::input_iterator_tag,unsigned int>
456 {
457  unsigned long d_bits0,d_bits1; // copy of bitset data
458 
459  public:
460 
461 // constructors and destructors
462  iterator() : d_bits0(0), d_bits1(0) {}
463  explicit iterator(const BitSetBase<2>& b)
464  : d_bits0(b.to_ulong()), d_bits1(b.to_ulong(1)) {}
465 
466 // accessors
467  bool operator== (const iterator& i) const;
468  bool operator!= (const iterator& i) const;
469  unsigned int operator* () const;
470  bool operator() () const { return d_bits0!=0 or d_bits1!=0; }
471 
472 // manipulators
473  iterator& operator++ ();
474  iterator operator++ (int) { iterator tmp(*this); ++(*this); return tmp; }
475 }; // |class BitSetBase<2>::iterator|
476 
477 } // |namespace bitset|
478 
479 } // |namespace atlas|
480 
481 #endif
bool any() const
Definition: bitset.h:119
Definition: parse_types.h:142
unsigned int firstBit() const
Definition: bitset.h:128
BitSet & complement(unsigned int limit)
Definition: bitset.h:401
bool operator!=(const BitSetBase< 2 > &b) const
Definition: bitset.h:238
iterator begin() const
Definition: bitset.h:380
BitSet & reset(unsigned int j)
Definition: bitset.h:396
bool operator!=(const type_expr &x, const type_expr &y)
Definition: axis-types.h:374
unsigned long d_bits0
Definition: bitset.h:196
void truncate(unsigned int limit)
Definition: bitset.h:178
BitSet(unsigned long b)
Definition: bitset.h:344
static const unsigned long posBits
Definition: constants.h:44
Definition: bitset.h:329
PID_Matrix< C > operator-(PID_Matrix< C > A, C c)
Definition: matrix.h:51
unsigned int count() const
Definition: bitset.h:251
bool operator!=(const BitSetBase< 1 > &b) const
Definition: bitset.h:116
iterator()
Definition: bitset.h:462
void test(std::vector< ulong > &moduli, std::vector< ChineseBox * > &box)
Definition: coef-merge.cpp:450
bool any(const BitSetBase< 1 > &b) const
Definition: bitset.h:122
static const unsigned longBits
Definition: constants.h:40
iterator(const typename Base::iterator &b)
Definition: bitset.h:337
value_base * value
Definition: axis-types.h:129
unsigned long d_bits
Definition: bitset.h:435
iterator()
Definition: bitset.h:336
bool dot(BitSet b) const
Definition: bitset.h:425
unsigned int count() const
Definition: bitset.h:127
Set of n bits.
Definition: Atlas.h:57
static unsigned long lMask[longBits+1]
Definition: constants.h:52
iterator const_iterator
Definition: bitset.h:340
void swap(simple_list< T, Alloc > &x, simple_list< T, Alloc > &y)
Definition: sl_list.h:674
size_t lastBit(unsigned long f)
Definition: bits.cpp:89
BitSet & truncate(unsigned int m)
Definition: bitset.h:403
char * limit
Definition: common.c:91
The class BaseSize computes (with its member &#39;value&#39;) the base size.
Definition: bitset.h:299
bool none() const
Definition: bitset.h:244
BitSet & fill(unsigned int limit)
Definition: bitset.h:400
unsigned int position(unsigned int j) const
Definition: bitset.h:136
iterator()
Definition: bitset.h:440
Definition: cweave.c:245
void flip(unsigned int j)
Definition: bitset.h:171
void andnot(const BitSetBase< 1 > &b)
Definition: bitset.h:153
unsigned long d_bits1
Definition: bitset.h:196
bool operator==(const BitSetBase< 1 > &b) const
Definition: bitset.h:115
void complement(unsigned int limit)
Definition: bitset.h:177
unsigned long to_ulong(unsigned int n) const
Definition: bitset.h:143
unsigned int bitCount(unsigned long x)
Definition: bits.cpp:30
Base for a non-empty BitSet that fits in two words but not one.
Definition: bitset.h:194
BitSet & reset()
Definition: bitset.h:395
void swap(BitSetBase< 1 > &source)
Definition: bitset.h:183
unsigned int value_type
Definition: bitset.h:334
RationalVector< C2 > operator*(const matrix::Matrix< C1 > &M, const RationalVector< C2 > &v)
Definition: ratvec.cpp:158
void fill(unsigned int limit)
Definition: bitset.h:175
unsigned long to_ulong() const
Definition: bitset.h:142
void reset()
Definition: bitset.h:172
bool scalarProduct(const BitSetBase< 1 > &b) const
Definition: bitset.h:139
bool operator==(const BitSetBase< 2 > &b) const
Definition: bitset.h:236
void reset(unsigned int j)
Definition: bitset.h:173
iterator(const BitSetBase< 1 > &b)
Definition: bitset.h:441
unsigned long d_bits1
Definition: bitset.h:457
unsigned long d_bits
Word that holds the BitSet.
Definition: bitset.h:94
Type definitions for the class BitSet.
BitSet & slice(const BitSet &c)
Definition: bitset.h:405
Definition: constants.h:35
BitSet(const BitSet< m > &b)
Copy from other size BitSets, only to be used with |m<n|.
Definition: bitset.h:350
bool test(unsigned int j) const
Definition: bitset.h:133
void reset()
Definition: bitset.h:275
iterator end() const
Definition: bitset.h:381
BitSet & andnot(const BitSet &b)
Definition: bitset.h:392
unsigned long to_ulong(unsigned int n) const
Definition: bitset.h:260
size_t firstBit(unsigned long f)
Definition: bits.cpp:64
static unsigned long bitMask[longBits]
Definition: constants.h:48
bool none() const
Definition: bitset.h:120
unsigned long n
Definition: axis.cpp:77
bool operator==(const type_expr &x, const type_expr &y)
Definition: axis-types.cpp:257
Base for a non-empty BitSet that fits in one word.
Definition: bitset.h:89
BitSet & flip(unsigned int j)
Definition: bitset.h:393
Definition: Atlas.h:38
void swap(BitSet &source)
Definition: bitset.h:408
unsigned long to_ulong() const
Definition: bitset.h:259
iterator(const BitSetBase< 2 > &b)
Definition: bitset.h:463
bool contains(const BitSetBase< 1 > &b) const
Definition: bitset.h:124
unsigned int lastBit() const
Definition: bitset.h:130
Definition: bitset.h:77
bool any() const
Definition: bitset.h:243
BitSetBase< BaseSize< n >::value > Base
Definition: bitset.h:324
bool contains(const BitSetBase< 2 > &b) const
Definition: bitset.h:248
BitSet & unslice(const BitSet &c)
Definition: bitset.h:406
BitSet()
Definition: bitset.h:343
bool any(const BitSetBase< 2 > &b) const
Definition: bitset.h:246
std::forward_iterator_tag iterator_category
Definition: bitset.h:333
Vertex v
Definition: graph.cpp:116