PVData C++  8.0.2
bitSet.h
1 /* bitSet.h */
2 /*
3  * Copyright information and license terms for this software can be
4  * found in the file LICENSE that is included with the distribution
5  */
6 /**
7  * @author mse
8  */
9 #ifndef BITSET_H
10 #define BITSET_H
11 
12 #if __cplusplus>=201103L
13 # include <initializer_list>
14 #endif
15 
16 #include <vector>
17 
18 #include <pv/pvType.h>
19 #include <pv/serialize.h>
20 #include <pv/sharedPtr.h>
21 
22 #include <shareLib.h>
23 
24 namespace epics { namespace pvData {
25 
26  class BitSet;
27  typedef std::tr1::shared_ptr<BitSet> BitSetPtr;
28 
29  /**
30  * @brief A vector of bits.
31  *
32  * This class implements a vector of bits that grows as needed. Each
33  * component of the bit set has a @c bool value. The bits of a
34  * @c BitSet are indexed by nonnegative integers. Individual
35  * indexed bits can be examined, set, or cleared. One @c BitSet may
36  * be used to modify the contents of another @c BitSet through
37  * logical AND, logical inclusive OR, and logical exclusive OR
38  * operations.
39  *
40  * <p>By default, all bits in the set initially have the value
41  * @c false.
42  *
43  * <p>Every bit set has a current size, which is the number of bits
44  * of space currently in use by the bit set. Note that the size is
45  * related to the implementation of a bit set, so it may change with
46  * implementation. The length of a bit set relates to logical length
47  * of a bit set and is defined independently of implementation.
48  *
49  * <p>A @c BitSet is not safe for multithreaded use without external
50  * synchronization.
51  *
52  * Based on Java implementation.
53  *
54  * @since 7.0.0 Many methods return BitSet& to facilite method chaining.
55  */
56  class epicsShareClass BitSet : public Serializable {
57  public:
59  static BitSetPtr create(uint32 nbits);
60  /**
61  * Creates a new bit set. All bits are initially @c false.
62  */
63  BitSet();
64 
65  /**
66  * Creates a bit set whose initial size is large enough to explicitly
67  * represent bits with indices in the range @c 0 through
68  * @c nbits-1. All bits are initially @c false.
69  *
70  * @param nbits the initial size of the bit set
71  */
73 
74 #if __cplusplus>=201103L
75  /** Initialize from a list of indicies
76  @code
77  BitSet X({1, 5});
78  assert(X.get(1) && X.get(5));
79  @endcode
80  */
82 #endif
83 
84  /**
85  * Destructor.
86  */
87  virtual ~BitSet();
88 
89  /**
90  * Sets the bit at the specified index to the complement of its
91  * current value.
92  *
93  * @param bitIndex the index of the bit to flip
94  */
96 
97  /**
98  * Sets the bit at the specified index to @c true.
99  *
100  * @param bitIndex a bit index
101  */
103 
104  /**
105  * Sets the bit specified by the index to @c false.
106  *
107  * @param bitIndex the index of the bit to be cleared
108  */
110 
111  /**
112  * Sets the bit at the specified index to the specified value.
113  *
114  * @param bitIndex a bit index
115  * @param value a boolean value to set
116  */
117  void set(uint32 bitIndex, bool value);
118 
119  /**
120  * Returns the value of the bit with the specified index. The value
121  * is @c true if the bit with the index @c bitIndex is currently
122  * set in this @c BitSet; otherwise, the result is @c false.
123  *
124  * @param bitIndex the bit index
125  * @return the value of the bit with the specified index
126  */
127  bool get(uint32 bitIndex) const;
128 
129  /**
130  * Sets all of the bits in this BitSet to @c false.
131  */
132  void clear();
133 
134  /**
135  * Returns the index of the first bit that is set to @c true that
136  * occurs on or after the specified starting index. If no such bit
137  * exists then @c -1 is returned.
138  *
139  * <p>To iterate over the @c true bits in a @c BitSet,
140  * use the following loop:
141  *
142  * <pre> {@code
143  * for (int32 i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
144  * // operate on index i here
145  * }}</pre>
146  *
147  * @param fromIndex the index to start checking from (inclusive)
148  * @return the index of the next set bit, or @c -1 if there
149  * is no such bit
150  */
152 
153  /**
154  * Returns the index of the first bit that is set to @c false
155  * that occurs on or after the specified starting index.
156  *
157  * @param fromIndex the index to start checking from (inclusive)
158  * @return the index of the next clear bit
159  */
161 
162  /**
163  * Returns true if this @c BitSet contains no bits that are set
164  * to @c true.
165  *
166  * @return indicating whether this @c BitSet is empty
167  */
168  bool isEmpty() const;
169 
170  /**
171  * Returns the number of bits set to @c true in this @c BitSet.
172  *
173  * @return the number of bits set to @c true in this @c BitSet
174  */
175  uint32 cardinality() const;
176 
177  /**
178  * Returns the number of bits of space actually in use by this
179  * @c BitSet to represent bit values.
180  * The maximum element in the set is the size - 1st element.
181  *
182  * @return the number of bits currently in this bit set
183  */
184  uint32 size() const;
185 
186  //! Returns true if any bit is set in both *this and other
187  bool logical_and(const BitSet& other) const;
188  //! Returns true if any bit is set in both *this or other
189  bool logical_or(const BitSet& other) const;
190 
191  /**
192  * Performs a bitwise <b>AND</b> of this target bit set with the
193  * argument bit set. This bit set is modified so that each bit in it
194  * has the value @c true if and only if it both initially
195  * had the value @c true and the corresponding bit in the
196  * bit set argument also had the value @c true.
197  *
198  * @param set a bit set
199  */
200  BitSet& operator&=(const BitSet& set);
201 
202  /**
203  * Performs a bitwise <b>OR</b> of this bit set with the bit set
204  * argument. This bit set is modified so that a bit in it has the
205  * value @c true if and only if it either already had the
206  * value @c true or the corresponding bit in the bit set
207  * argument has the value @c true.
208  *
209  * @param set a bit set
210  */
211  BitSet& operator|=(const BitSet& set);
212 
213  /**
214  * Performs a bitwise <b>XOR</b> of this bit set with the bit set
215  * argument. This bit set is modified so that a bit in it has the
216  * value @c true if and only if one of the following
217  * statements holds:
218  * <ul>
219  * <li>The bit initially has the value @c true, and the
220  * corresponding bit in the argument has the value @c false.
221  * <li>The bit initially has the value @c false, and the
222  * corresponding bit in the argument has the value @c true.
223  * </ul>
224  *
225  * @param set a bit set
226  */
227  BitSet& operator^=(const BitSet& set);
228 
229  /**
230  * Assignment operator.
231  */
232  BitSet& operator=(const BitSet &set);
233 
234  //! Swap contents
235  void swap(BitSet& set);
236 
237  /**
238  * Perform AND operation on <code>set1</code> and <code>set2</code>,
239  * and OR on result and this instance.
240  * @param set1
241  * @param set2
242  */
243  void or_and(const BitSet& set1, const BitSet& set2);
244 
245  /**
246  * Comparison operator.
247  */
248  bool operator==(const BitSet &set) const;
249 
250  bool operator!=(const BitSet &set) const;
251 
252  virtual void serialize(ByteBuffer *buffer,
254  virtual void deserialize(ByteBuffer *buffer,
256 
257  private:
258 
259  typedef std::vector<uint64> words_t;
260  /** The internal field corresponding to the serialField "bits". */
261  words_t words;
262 
263  private:
264  /**
265  * Sets the field wordsInUse to the logical size in words of the bit set.
266  * WARNING: This method assumes that the number of words actually in use is
267  * less than or equal to the current value of wordsInUse!
268  */
269  void recalculateWordsInUse();
270 
271  /**
272  * Ensures that the BitSet can hold enough words.
273  * @param wordsRequired the minimum acceptable number of words.
274  */
276 
277  /**
278  * Ensures that the BitSet can accommodate a given wordIndex,
279  * temporarily violating the invariants. The caller must
280  * restore the invariants before returning to the user,
281  * possibly using recalculateWordsInUse().
282  * @param wordIndex the index to be accommodated.
283  */
284  void expandTo(uint32 wordIndex);
285 
286  /**
287  * Returns the number of zero bits following the lowest-order ("rightmost")
288  * one-bit in the two's complement binary representation of the specified
289  * <tt>long</tt> value. Returns 64 if the specified value has no
290  * one-bits in its two's complement representation, in other words if it is
291  * equal to zero.
292  *
293  * @return the number of zero bits following the lowest-order ("rightmost")
294  * one-bit in the two's complement binary representation of the
295  * specified <tt>long</tt> value, or 64 if the value is equal
296  * to zero.
297  */
299 
300  /**
301  * Returns the number of one-bits in the two's complement binary
302  * representation of the specified <tt>long</tt> value. This function is
303  * sometimes referred to as the <i>population count</i>.
304  *
305  * @return the number of one-bits in the two's complement binary
306  * representation of the specified <tt>long</tt> value.
307  */
308  static uint32 bitCount(uint64 i);
309 
310  };
311 
312  epicsShareExtern std::ostream& operator<<(std::ostream& o, const BitSet& b);
313 
314 }}
315 #endif /* BITSET_H */
#define POINTER_DEFINITIONS(clazz)
Definition: sharedPtr.h:198
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher, std::size_t offset, std::size_t count) const =0
A vector of bits.
Definition: bitSet.h:56