"Fossies" - the Fresh Open Source Software Archive 
Member "muscle/support/BitChord.h" (21 Nov 2020, 60717 Bytes) of package /linux/privat/muscle7.62.zip:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "BitChord.h" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
7.61_vs_7.62.
1 /* This file is Copyright 2000-2013 Meyer Sound Laboratories Inc. See the included LICENSE.txt file for details. */
2
3 #ifndef MuscleBitChord_h
4 #define MuscleBitChord_h
5
6 #include "support/Void.h"
7 #include "support/MuscleSupport.h"
8 #include "support/PseudoFlattenable.h"
9 #include "util/String.h"
10
11 namespace muscle {
12
13 #if defined(MUSCLE_AVOID_CPLUSPLUS11) && !defined (MUSCLE_AVOID_CPLUSPLUS11_BITCHORD)
14 # define MUSCLE_AVOID_CPLUSPLUS11_BITCHORD
15 #endif
16
17 /** A templated class for implement an N-bit-long bit-chord. Useful for doing efficient parallel boolean operations
18 * on bits-strings of lengths that can't fit in any of the standard integer types, and also for holding bit-shifted
19 * boolean flags in a "safe" container so that you can query or manipulate the flags via human-readable method-calls
20 * instead of easy-to-get-wrong bit-shifting operators.
21 *
22 * @note that the TagClass template-parameter's value isn't directly used for anything; it's provided only as a way
23 * to help make unrelated BitChords' template-instantiations unique and not-implicitly-convertible to each other
24 * even if they happen to specify the same value for the NumBits template-parameter. See the
25 * DECLARE_BITCHORD_FLAGS_TYPE macro at the bottom of BitChord.h for more information.
26 */
27 template <uint32 NumBits, class TagClass=Void> class BitChord : public PseudoFlattenable
28 {
29 public:
30 /** Default constructor */
31 BitChord() {ClearAllBits();}
32
33 #ifndef MUSCLE_AVOID_CPLUSPLUS11_BITCHORD
34 /** Variadic constructor; takes a list of bit-indices indicating which bits should be set in this BitChord.
35 * @param bits any number of bit-index arguments may be supplied, and the correspond bits will be set.
36 * @note for example, BitChord bc(a, b, c); is equivalent to BitChord bc; bc.SetBit(a); bc.SetBit(b); bc.SetBit(c);
37 * @note this constructor can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
38 */
39 template<typename ...Bits> explicit BitChord(Bits... bits) {ClearAllBits(); const int arr[] {bits...}; for (auto bit : arr) SetBit(bit);}
40 #endif
41
42 /** @copydoc DoxyTemplate::DoxyTemplate(const DoxyTemplate &) */
43 BitChord(const BitChord & rhs) {*this = rhs;}
44
45 /** Destructor */
46 ~BitChord() {/* empty */}
47
48 /** @copydoc DoxyTemplate::operator=(const DoxyTemplate &) */
49 BitChord & operator =(const BitChord & rhs) {for (int i=0; i<NUM_WORDS; i++) _words[i] = rhs._words[i]; return *this;}
50
51 /** Returns the state of the specified bit
52 * @param whichBit the index of the bit to query (e.g. 0 indicates the first bit, 1 indicates the second bit, 2 indicates the third bit, and so on)
53 * @returns true iff the bit was set
54 */
55 bool IsBitSet(uint32 whichBit) const
56 {
57 MASSERT(whichBit < NumBits, "BitChord::IsBitSet: whichBit was out of range!\n");
58 return IsBitSetUnchecked(whichBit);
59 }
60
61 /** Sets the state of the specified bit to 1.
62 * @param whichBit the index of the bit to set to 1 (e.g. 0 indicates the first bit, 1 indicates the second bit, 2 indicates the third bit, and so on)
63 */
64 void SetBit(uint32 whichBit)
65 {
66 MASSERT(whichBit < NumBits, "BitChord::SetBit: whichBit was out of range!\n");
67 SetBitUnchecked(whichBit);
68 }
69
70 /** Sets the state of the specified bit to the specified boolean value.
71 * @param whichBit the index of the bit to set (e.g. 0 indicates the first bit, 1 indicates the second bit, 2 indicates the third bit, and so on)
72 * @param newValue true to set the bit, or false to clear it
73 */
74 void SetBit(uint32 whichBit, bool newValue)
75 {
76 MASSERT(whichBit < NumBits, "BitChord::SetBit: whichBit was out of range!\n");
77 SetBitUnchecked(whichBit, newValue);
78 }
79
80 /** Clears the state of the specified bit
81 * @param whichBit the index of the bit to set (e.g. 0 indicates the first bit, 1 indicates the second bit, 2 indicates the third bit, and so on)
82 */
83 void ClearBit(uint32 whichBit)
84 {
85 MASSERT(whichBit < NumBits, "BitChord::ClearBit: whichBit was out of range!\n");
86 ClearBitUnchecked(whichBit);
87 }
88
89 /** Toggles the state of the specified bit from 1 to 0, or vice-versa
90 * @param whichBit the index of the bit to toggle (e.g. 0 indicates the first bit, 1 indicates the second bit, 2 indicates the third bit, and so on)
91 */
92 void ToggleBit(uint32 whichBit)
93 {
94 MASSERT(whichBit < NumBits, "BitChord::ToggleBit: whichBit was out of range!\n");
95 SetBitUnchecked(whichBit, !IsBitSetUnchecked(whichBit));
96 }
97
98 /** Sets all our bits to false */
99 void ClearAllBits() {for (uint32 i=0; i<NUM_WORDS; i++) _words[i] = 0;}
100
101 /** Sets all our bits to true */
102 void SetAllBits()
103 {
104 for (uint32 i=0; i<NUM_WORDS; i++) _words[i] = ((uint32)-1);
105 ClearUnusedBits();
106 }
107
108 /** Inverts the set/clear state of all our bits */
109 void ToggleAllBits()
110 {
111 for (uint32 i=0; i<NUM_WORDS; i++) _words[i] = ~_words[i];
112 ClearUnusedBits();
113 }
114
115 /** Returns true iff at least one bit is set in this bit-chord. */
116 bool AreAnyBitsSet() const
117 {
118 for (uint32 i=0; i<NUM_WORDS; i++) if (_words[i] != 0) return true;
119 return false;
120 }
121
122 /** Returns true iff all bits in this bit-chord are set. */
123 bool AreAllBitsSet() const
124 {
125 if ((NumBits%NUM_BITS_PER_WORD) == 0)
126 {
127 for (uint32 i=0; i<NUM_WORDS; i++) if (_words[i] != ((uint32)-1)) return false;
128 }
129 else
130 {
131 for (uint32 i=0; i<NUM_WORDS-1; i++) if (_words[i] != ((uint32)-1)) return false;
132 for (uint32 j=(NUM_WORDS-1)*NUM_BITS_PER_WORD; j<NumBits; j++) if (IsBitSet(j) == false) return false;
133 }
134 return true;
135 }
136
137 /** Convenience method: Returns the current value of the given bit,
138 * and clears the bit as a side-effect.
139 * @param whichBit the index of the bit to return and then clear.
140 */
141 bool GetAndClearBit(uint32 whichBit)
142 {
143 const bool ret = IsBitSet(whichBit);
144 ClearBit(whichBit);
145 return ret;
146 }
147
148 /** Convenience method: Returns the current value of the given bit,
149 * and set the bit as a side-effect.
150 * @param whichBit the index of the bit to return and then set.
151 */
152 bool GetAndSetBit(uint32 whichBit)
153 {
154 const bool ret = IsBitSet(whichBit);
155 SetBit(whichBit);
156 return ret;
157 }
158
159 /** Convenience method: Returns the current value of the given bit,
160 * and toggles the bit as a side-effect.
161 * @param whichBit the index of the bit to return and then toggles.
162 */
163 bool GetAndToggleBit(uint32 whichBit)
164 {
165 const bool ret = IsBitSet(whichBit);
166 ToggleBit(whichBit);
167 return ret;
168 }
169
170 /** Returns true iff at least one bit is unset in this bit-chord. */
171 bool AreAnyBitsUnset() const {return (AreAllBitsSet() == false);}
172
173 /** Returns true iff all bits in this bit-chord are unset */
174 bool AreAllBitsUnset() const {return (AreAnyBitsSet() == false);}
175
176 /** @copydoc DoxyTemplate::operator|=(const DoxyTemplate &) */
177 BitChord & operator |=(const BitChord & rhs) {for (int i=0; i<NUM_WORDS; i++) _words[i] |= rhs._words[i]; return *this;}
178
179 /** @copydoc DoxyTemplate::operator&=(const DoxyTemplate &) */
180 BitChord & operator &=(const BitChord & rhs) {for (int i=0; i<NUM_WORDS; i++) _words[i] &= rhs._words[i]; return *this;}
181
182 /** @copydoc DoxyTemplate::operator^=(const DoxyTemplate &) */
183 BitChord & operator ^=(const BitChord & rhs) {for (int i=0; i<NUM_WORDS; i++) _words[i] ^= rhs._words[i]; return *this;}
184
185 /** @copydoc DoxyTemplate::operator==(const DoxyTemplate &) const */
186 bool operator ==(const BitChord & rhs) const {if (this != &rhs) {for (int i=0; i<NUM_WORDS; i++) if (_words[i] != rhs._words[i]) return false;} return true;}
187
188 /** @copydoc DoxyTemplate::operator!=(const DoxyTemplate &) const */
189 bool operator !=(const BitChord & rhs) const {return !(*this == rhs);}
190
191 /** @copydoc DoxyTemplate::operator<(const DoxyTemplate &) const */
192 bool operator < (const BitChord &rhs) const {if (this != &rhs) {for (int i=0; i<NUM_WORDS; i++) {if (_words[i] < rhs._words[i]) return true; if (_words[i] > rhs._words[i]) return false;}} return false;}
193
194 /** @copydoc DoxyTemplate::operator>(const DoxyTemplate &) const */
195 bool operator > (const BitChord &rhs) const {if (this != &rhs) {for (int i=0; i<NUM_WORDS; i++) {if (_words[i] > rhs._words[i]) return true; if (_words[i] < rhs._words[i]) return false;}} return false;}
196
197 /** @copydoc DoxyTemplate::operator<=(const DoxyTemplate &) const */
198 bool operator <=(const BitChord &rhs) const {return !(*this > rhs);}
199
200 /** @copydoc DoxyTemplate::operator>=(const DoxyTemplate &) const */
201 bool operator >=(const BitChord &rhs) const {return !(*this < rhs);}
202
203 /** Returns a BitChord that is the bitwise-inverse of this BitChord (i.e. all bits flipped). */
204 BitChord operator ~() const
205 {
206 BitChord ret; for (uint32 i=0; i<NUM_WORDS; i++) ret._words[i] = ~_words[i];
207 ret.ClearUnusedBits(); // don't let (ret) get into a non-normalized state
208 return ret;
209 }
210
211 /** Part of the pseudo-Flattenable API: Returns false (because even though all BitChords of a given
212 * BitChord template-instantiation will always have the same flattened-size, different template-instantiations
213 * of BitChords can have different flattened-sizes and they all share the same type-code)
214 */
215 bool IsFixedSize() const {return false;}
216
217 /** Part of the pseudo-Flattenable API: Returns B_BITCHORD_TYPE. */
218 uint32 TypeCode() const {return B_BITCHORD_TYPE;}
219
220 /** Returns true iff (tc) equals B_BITCHORD_TYPE.
221 * @param tc the type code to examine
222 */
223 bool AllowsTypeCode(uint32 tc) const {return (TypeCode()==tc);}
224
225 /** @copydoc DoxyTemplate::FlattenedSize() const */
226 uint32 FlattenedSize() const {return sizeof(uint32)+(NUM_WORDS*sizeof(uint32));}
227
228 /** @copydoc DoxyTemplate::Flatten(uint8 *) const */
229 void Flatten(uint8 * buffer) const
230 {
231 muscleCopyOut(buffer, B_HOST_TO_LENDIAN_INT32(NumBits)); // just so we can handle versioning issues more intelligently later on
232 buffer += sizeof(uint32);
233 for (uint32 i=0; i<NUM_WORDS; i++) muscleCopyOut(&buffer[i*sizeof(int32)], B_HOST_TO_LENDIAN_INT32(_words[i]));
234 }
235
236 /** @copydoc DoxyTemplate::Unflatten(const uint8 *, uint32) */
237 status_t Unflatten(const uint8 * buffer, uint32 size)
238 {
239 if (size < sizeof(uint32)) return B_BAD_DATA; // not enough data to even read the #-of-valid-bits header?
240
241 const uint32 numBitsToRead = muscleMin(B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(buffer)), NumBits);
242 buffer += sizeof(uint32); size -= sizeof(uint32);
243
244 const uint32 numWordsToRead = (numBitsToRead+NUM_BITS_PER_WORD-1)/NUM_BITS_PER_WORD;
245 if (size < numWordsToRead) return B_BAD_DATA;
246
247 for (uint32 i=0; i<numWordsToRead; i++) _words[i] = B_LENDIAN_TO_HOST_INT32(muscleCopyIn<uint32>(&buffer[i*sizeof(uint32)]));
248
249 ClearUnusedBits(); // make sure we didn't read in non-zero values for any bits that we don't use
250 for (uint32 i=numBitsToRead; i<NumBits; i++) ClearBit(i); // any bits that we didn't read (because the data was too short) should be cleared
251 return B_NO_ERROR;
252 }
253
254 /** @copydoc DoxyTemplate::CalculateChecksum() const */
255 uint32 CalculateChecksum() const
256 {
257 uint32 ret = 0;
258 for (uint32 i=0; i<NUM_WORDS; i++) ret += ((i+1)*_words[i]);
259 return ret;
260 }
261
262 /** @copydoc DoxyTemplate::HashCode() const */
263 uint32 HashCode() const {return CalculateChecksum();}
264
265 #ifndef MUSCLE_AVOID_CPLUSPLUS11_BITCHORD
266 /** Equivalent to calling SetBit() multiple times; once per supplied argument.
267 * e.g. calling SetBits(a,b,c) is equivalent to calling SetBit(a);SetBit(b);SetBit(c).
268 * @param bits a list of bit-indices indicating which bit(s) to set
269 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
270 */
271 template<typename ...Bits> void SetBits(Bits... bits) {const int arr[] {bits...}; for (auto bit : arr) SetBit(bit);}
272
273 /** Equivalent to calling ClearBit() multiple times; once per supplied argument.
274 * e.g. calling ClearBits(a,b,c) is equivalent to calling ClearBit(a);ClearBit(b);ClearBit(c).
275 * @param bits a list of bit-indices indicating which bit(s) to unset
276 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
277 */
278 template<typename ...Bits> void ClearBits(Bits... bits) {const int arr[] {bits...}; for (auto bit : arr) ClearBit(bit);}
279
280 /** Equivalent to calling ToggleBit() multiple times; once per supplied argument.
281 * e.g. calling ToggleBits(a,b,c) is equivalent to calling ToggleBit(a);ToggleBit(b);ToggleBit(c).
282 * @param bits a list of bit-indices indicating which bit(s) to toggle
283 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
284 */
285 template<typename ...Bits> void ToggleBits(Bits... bits) {const int arr[] {bits...}; for (auto bit : arr) ToggleBit(bit);}
286
287 /** Convenience method. Returns a BitChord that is identical to this one, except that the
288 * bits at the specified indices have been set.
289 * @param bits a list of bit-indices indicating which bit(s) to toggle
290 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
291 */
292 template<typename ...Bits> BitChord WithBits(Bits... bits) const {BitChord ret(*this); const int arr[] {bits...}; for (auto bit : arr) ret.SetBit(bit); return ret;}
293
294 /** Convenience method. Returns a BitChord that is identical to this one, except that the
295 * bits at the specified indices have been cleared.
296 * @param bits a list of bit-indices indicating which bit(s) to toggle
297 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
298 */
299 template<typename ...Bits> BitChord WithoutBits(Bits... bits) const {BitChord ret(*this); const int arr[] {bits...}; for (auto bit : arr) ret.ClearBit(bit); return ret;}
300
301 /** Convenience method. Returns a BitChord that is identical to this one, except that the
302 * bits at the specified indices have been toggled.
303 * @param bits a list of bit-indices indicating which bit(s) to toggle
304 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
305 */
306 template<typename ...Bits> BitChord WithToggledBits(Bits... bits) const {BitChord ret(*this); const int arr[] {bits...}; for (auto bit : arr) ret.ToggleBit(bit); return ret;}
307
308 /** Convenience method. Returns true if at least one of the specified bits is set.
309 * @param bits a list of bit-indices indicating which bit(s) to test
310 * @returns true iff at least one of the specified bits is set
311 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
312 */
313 template<typename ...Bits> bool AreAnyOfTheseBitsSet(Bits... bits) const {const int arr[] {bits...}; for (auto bit : arr) if (IsBitSet(bit)) return true; return false;}
314
315 /** Convenience method. Returns true if at least one of the specified bits is set.
316 * @param bits a list of bit-indices indicating which bit(s) to test
317 * @returns true iff every one of the specified bits is set
318 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
319 */
320 template<typename ...Bits> bool AreAllOfTheseBitsSet(Bits... bits) const {const int arr[] {bits...}; for (auto bit : arr) if (IsBitSet(bit) == false) return false; return true;}
321
322 /** Convenience method. Returns true if at least one of the specified bits is unset.
323 * @param bits a list of bit-indices indicating which bit(s) to test
324 * @returns true iff at least one of the specified bits is unset
325 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
326 */
327 template<typename ...Bits> bool AreAnyOfTheseBitsUnset(Bits... bits) const {const int arr[] {bits...}; for (auto bit : arr) if (IsBitSet(bit) == false) return true; return false;}
328
329 /** Convenience method. Returns true if at least one of the specified bits is unset.
330 * @param bits a list of bit-indices indicating which bit(s) to test
331 * @returns true iff every one of the specified bits is unset
332 * @note this method can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
333 */
334 template<typename ...Bits> bool AreAllOfTheseBitsUnset(Bits... bits) const {const int arr[] {bits...}; for (auto bit : arr) if (IsBitSet(bit)) return false; return true;}
335
336 /** Pseudo-constructor: Returns a BitChord whose contents are copied from the supplied list of 32-bit words.
337 * @param words a list of uint32s to copy into our internal array. The number of arguments must be equal to NUM_WORDS.
338 * @note this constructor can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
339 */
340 template<typename ...Words> static BitChord FromWords(Words... words)
341 {
342 const uint32 arr[] {words...};
343 static_assert(ARRAYITEMS(arr) == NUM_WORDS, "Wrong number of 32-bit-word arguments was supplied to BitChord::FromWords()");
344
345 uint32 i = 0;
346 BitChord ret;
347 for (auto w : arr) ret.SetWord(i++, w);
348 return ret;
349 }
350
351 /** Pseudo-constructor: Returns a BitChord whose contents are copied from the supplied list of 32-bit words.
352 * @param bytes a list of uint8s to copy into our internal array. The number of arguments must be equal to NUM_BYTES.
353 * @note this constructor can be used (with up to 32 arguments) even when MUSCLE_AVOID_CPLUSPLUS11 is defined, via clever ifdef and macro magic
354 */
355 template<typename ...Bytes> static BitChord FromBytes(Bytes... bytes)
356 {
357 const uint8 arr[] {bytes...};
358 static_assert(ARRAYITEMS(arr) == NUM_BYTES, "Wrong number of 8-bit-byte arguments was supplied to BitChord::FromBytes()");
359
360 uint32 i = 0;
361 BitChord ret;
362 for (auto b : arr) ret.SetByte(i++, b);
363 return ret;
364 }
365
366 /** Pseudo-constructor: Returns a BitChord with all of its bits set EXCEPT the bits specified as arguments.
367 * @param bits a list of bit-indices that should remain cleared
368 */
369 template<typename ...Bits> static BitChord WithAllBitsSetExceptThese(Bits... bits)
370 {
371 const int arr[] {bits...};
372
373 BitChord ret = BitChord::WithAllBitsSet();
374 for (auto b : arr) ret.ClearBit(b);
375 return ret;
376 }
377 #endif
378
379 /** Sets all the bits in this BitChord that are set in (bits)
380 * @param bits a set of bits indicating which bit-positions to set in (*this)
381 */
382 void SetBits(const BitChord & bits) {for (uint32 i=0; i<NUM_WORDS; i++) _words[i] |= bits._words[i];}
383
384 /** Sets all the bits in this BitChord that are set in (bits)
385 * @param bits a set of bits indicating which bit-positions to set in (*this)
386 * @param set if true, the specified bits will be set; if false, they will be cleared.
387 */
388 void SetBits(const BitChord & bits, bool set) {if (set) SetBits(bits); else ClearBits(bits);}
389
390 /** Clears all the bits in this BitChord that are set in (bits)
391 * @param bits a set of bits indicating which bit-positions to clear in (*this)
392 */
393 void ClearBits(const BitChord & bits) {for (uint32 i=0; i<NUM_WORDS; i++) _words[i] &= ~bits._words[i];}
394
395 /** Toggles all the bits in this BitChord that are set in (bits)
396 * @param bits a set of bits indicating which bit-positions to toggle in (*this)
397 */
398 void ToggleBits(const BitChord & bits) {for (uint32 i=0; i<NUM_WORDS; i++) _words[i] ^= bits._words[i];}
399
400 /** Convenience method. Returns a BitChord that is identical to this one, except that the
401 * bit at the specified index has been set.
402 * @param whichBit the index of the bit to set in the returned object.
403 */
404 BitChord WithBit(uint32 whichBit) const {BitChord ret(*this); ret.SetBit(whichBit); return ret;}
405
406 /** Convenience method. Returns a BitChord that is identical to this one, except that the
407 * bit at the specified index has been cleared.
408 * @param whichBit the index of the bit to clear in the returned object.
409 */
410 BitChord WithoutBit(uint32 whichBit) const {BitChord ret(*this); ret.ClearBit(whichBit); return ret;}
411
412 /** Convenience method. Returns a BitChord that is identical to this one, except that the
413 * bit at the specified index has been toggled.
414 * @param whichBit the index of the bit to toggled in the returned object.
415 */
416 BitChord WithToggledBit(uint32 whichBit) const {BitChord ret(*this); ret.ToggleBit(whichBit); return ret;}
417
418 /** Convenience method. Returns a BitChord that is identical to this one, except that the
419 * bits at the specified indices have been set.
420 * @param whichBits BitChord representing the indices to set.
421 */
422 BitChord WithBits(const BitChord & whichBits) const {BitChord ret(*this); ret.SetBits(whichBits); return ret;}
423
424 /** Convenience method. Returns a BitChord that is identical to this one, except that the
425 * bits at the specified indices has been cleared.
426 * @param whichBits the indices of the bits to clear in the returned object.
427 */
428 BitChord WithoutBits(const BitChord & whichBits) const {BitChord ret(*this); ret.ClearBits(whichBits); return ret;}
429
430 /** Convenience method. Returns a BitChord that is identical to this one, except that the
431 * bits at the specified indices have been toggled.
432 * @param whichBits the indices of the bits to toggle in the returned object.
433 */
434 BitChord WithToggledBits(const BitChord & whichBits) const {BitChord ret(*this); ret.ToggleBits(whichBits); return ret;}
435
436 /** Convenience method. Returns true if at least one of the specified bits is set.
437 * @param bits a BitChord indicating which bit(s) to test
438 * @returns true iff at least one of specified bits specified in (bits) is also set in (this)
439 */
440 bool AreAnyOfTheseBitsSet(const BitChord & bits) const {BitChord b(*this); b &= bits; return b.AreAnyBitsSet();}
441
442 /** Convenience method. Returns true if at least one of the specified bits is set.
443 * @param bits a BitChord indicating which bit(s) to test
444 * @returns true iff every one of the bits specified in (bits) is also set in (this)
445 */
446 bool AreAllOfTheseBitsSet(const BitChord & bits) const {BitChord b(*this); b &= bits; return (b==bits);}
447
448 /** Returns a BitChord identical to this one, except that the bits specified in the
449 * (whichBits) argument have been set or cleared, depending on the (setBits) argument
450 * @param whichBits the bits to set (or clear)
451 * @param setBits true iff (whichBits) should be set; false if they should be cleared.
452 */
453 BitChord WithOrWithoutBits(const BitChord & whichBits, bool setBits) const {return setBits ? WithBits(whichBits) : WithoutBits(whichBits);}
454
455 /** Returns a BitChord with all bits cleared (aka a default-constructed BitChord). */
456 static BitChord WithAllBitsCleared() {return BitChord();}
457
458 /** Returns a BitChord with all of its bits set. */
459 static BitChord WithAllBitsSet() {BitChord ret; return ~ret;}
460
461 /** Returns a BitChord just like this one, except with all of the bits toggled to their boolean inverse. */
462 BitChord WithAllBitsToggled() const {return ~(*this);}
463
464 /** Returns the number of bits that are represented by this bit-chord, as specified in the template arguments */
465 static MUSCLE_CONSTEXPR uint32 GetNumBitsInBitChord() {return NumBits;}
466
467 /** Returns the number of 8-bit-bytes that are represented by this bit-chord */
468 static MUSCLE_CONSTEXPR uint32 GetNumBytesInBitChord() {return NUM_BYTES;}
469
470 /** Returns the number of 32-bit-words that are represented by this bit-chord */
471 static MUSCLE_CONSTEXPR uint32 GetNumWordsInBitChord() {return NUM_WORDS;}
472
473 /** Returns a fixed-length hexadecimal representation of this bit-chord. */
474 String ToHexString() const
475 {
476 String ret; (void) ret.Prealloc(1+(NUM_BYTES*3));
477 for (int32 i=NUM_BYTES-1; i>=0; i--)
478 {
479 char buf[4]; muscleSprintf(buf, "%s%02x", (ret.IsEmpty())?"":" ", GetByte(i));
480 ret += buf;
481 }
482 return ret;
483 }
484
485 /** Returns a fixed-length binary representation of this bit-chord. */
486 String ToBinaryString() const
487 {
488 String ret; (void) ret.Prealloc(NumBits+1);
489 for (int32 i=NumBits-1; i>=0; i--) ret += IsBitSet(i)?'1':'0';
490 return ret;
491 }
492
493 /** Sets a given 32-bit word full of bits in our internal words-array.
494 * Don't call this unless you know what you're doing!
495 * @param whichWord index of the word to set
496 * @param wordValue the new value for the specified word.
497 */
498 void SetWord(uint32 whichWord, uint32 wordValue)
499 {
500 MASSERT(whichWord < NUM_WORDS, "BitChord::SetWord: whichWord was out of range!\n");
501 _words[whichWord] = wordValue;
502 if ((whichWord+1) == NUM_WORDS) ClearUnusedBits(); // keep us normalized
503 }
504
505 /** Returns the nth 32-bit word from our internal words-array.
506 * Don't call this unless you know what you're doing!
507 * @param whichWord index of the word to return
508 */
509 uint32 GetWord(uint32 whichWord) const
510 {
511 MASSERT(whichWord < NUM_WORDS, "BitChord::GetWord: whichWord was out of range!\n");
512 return _words[whichWord];
513 }
514
515 /** Sets a given 8-bit byte in our internal words-array.
516 * Don't call this unless you know what you're doing!
517 * @param whichByte index of the 8-bit byte to set
518 * @param byteValue the new value for the specified byte.
519 */
520 void SetByte(uint32 whichByte, uint32 byteValue)
521 {
522 MASSERT(whichByte < NUM_BYTES, "BitChord::SetByte: whichByte was out of range!\n");
523
524 const uint32 bitShiftOffset = (whichByte*NUM_BITS_PER_BYTE);
525 uint32 & word = _words[whichByte/NUM_BYTES_PER_WORD];
526 word &= ~(((uint32)0xFF) << bitShiftOffset);
527 word |= (((uint32)byteValue) << bitShiftOffset);
528 if ((whichByte+1) == NUM_BYTES) ClearUnusedBits(); // keep us normalized
529 }
530
531 /** Returns the nth 8-bit byte from our internal words-array.
532 * Don't call this unless you know what you're doing!
533 * @param whichByte index of the byte to return
534 */
535 uint8 GetByte(uint32 whichByte) const
536 {
537 MASSERT(whichByte < NUM_BYTES, "BitChord::GetByte: whichByte was out of range!\n");
538 return (uint8) ((_words[whichByte/NUM_BYTES_PER_WORD]>>((whichByte%NUM_BYTES_PER_WORD)*NUM_BITS_PER_BYTE)) & 0xFF);
539 }
540
541 private:
542 #ifdef MUSCLE_AVOID_CPLUSPLUS11_BITCHORD
543 int OneIffBitIsSet( uint32 whichBit) const {return IsBitSet(whichBit)?1:0;}
544 int OneIffBitIsUnset(uint32 whichBit) const {return IsBitSet(whichBit)?0:1;}
545 #else
546 static constexpr uint32 GetWordWithFirstNBitsSet(int numBits)
547 {
548 return (numBits <= 0) ? ((uint32)0) : ((((uint32)1)<<(numBits-1)) | GetWordWithFirstNBitsSet(numBits-1));
549 }
550 #endif
551
552 bool IsBitSetUnchecked(uint32 whichBit) const {return ((_words[whichBit/NUM_BITS_PER_WORD] & (1<<(whichBit%NUM_BITS_PER_WORD))) != 0);}
553 void ClearBitUnchecked(uint32 whichBit) {_words[whichBit/NUM_BITS_PER_WORD] &= ~(1<<(whichBit%NUM_BITS_PER_WORD));}
554 void SetBitUnchecked( uint32 whichBit) {_words[whichBit/NUM_BITS_PER_WORD] |= (1<<(whichBit%NUM_BITS_PER_WORD));}
555 void SetBitUnchecked( uint32 whichBit, bool newValue)
556 {
557 if (newValue) SetBitUnchecked(whichBit);
558 else ClearBitUnchecked(whichBit);
559 }
560
561 void ClearUnusedBits()
562 {
563 const uint32 numLeftoverBits = NumBits%NUM_BITS_PER_WORD;
564 if (numLeftoverBits > 0)
565 {
566 uint32 & lastWord = _words[NUM_WORDS-1];
567 #ifdef MUSCLE_AVOID_CPLUSPLUS11_BITCHORD
568 if (lastWord != 0) for (uint32 i=NumBits; i<(NUM_WORDS*NUM_BITS_PER_WORD); i++) ClearBitUnchecked(i);
569 #else
570 lastWord &= GetWordWithFirstNBitsSet(numLeftoverBits); // O(1) implementation
571 #endif
572 }
573 }
574
575 enum {NUM_BITS_PER_BYTE = 8};
576 enum {NUM_BYTES_PER_WORD = sizeof(uint32)};
577 enum {NUM_BITS_PER_WORD = (NUM_BYTES_PER_WORD*NUM_BITS_PER_BYTE)};
578 enum {NUM_WORDS = (NumBits+NUM_BITS_PER_WORD-1)/NUM_BITS_PER_WORD};
579 enum {NUM_BYTES = (NumBits+NUM_BITS_PER_BYTE-1)/NUM_BITS_PER_BYTE};
580
581 uint32 _words[NUM_WORDS];
582
583 public:
584 // This is the hacked-for-C++03 implementation of our variadic methods; it's here for backwards compatibility with old compilers only!
585 // It works the same as the above variadic implementation, but only for up to 32 arguments (and it's macro-based, so it's a total eyesore, sorry)
586 #ifdef MUSCLE_AVOID_CPLUSPLUS11_BITCHORD
587 # ifndef DOXYGEN_SHOULD_IGNORE_THIS
588
589 #define BC_ARGS_1 uint32 b1
590 #define BC_ARGS_2 uint32 b1, uint32 b2
591 #define BC_ARGS_3 uint32 b1, uint32 b2, uint32 b3
592 #define BC_ARGS_4 uint32 b1, uint32 b2, uint32 b3, uint32 b4
593 #define BC_ARGS_5 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5
594 #define BC_ARGS_6 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6
595 #define BC_ARGS_7 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7
596 #define BC_ARGS_8 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8
597 #define BC_ARGS_9 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9
598 #define BC_ARGS_10 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10
599 #define BC_ARGS_11 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11
600 #define BC_ARGS_12 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12
601 #define BC_ARGS_13 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13
602 #define BC_ARGS_14 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14
603 #define BC_ARGS_15 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15
604 #define BC_ARGS_16 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16
605 #define BC_ARGS_17 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17
606 #define BC_ARGS_18 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18
607 #define BC_ARGS_19 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19
608 #define BC_ARGS_20 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20
609 #define BC_ARGS_21 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21
610 #define BC_ARGS_22 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22
611 #define BC_ARGS_23 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23
612 #define BC_ARGS_24 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24
613 #define BC_ARGS_25 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25
614 #define BC_ARGS_26 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26
615 #define BC_ARGS_27 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26, uint32 b27
616 #define BC_ARGS_28 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26, uint32 b27, uint32 b28
617 #define BC_ARGS_29 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26, uint32 b27, uint32 b28, uint32 b29
618 #define BC_ARGS_30 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26, uint32 b27, uint32 b28, uint32 b29, uint32 b30
619 #define BC_ARGS_31 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26, uint32 b27, uint32 b28, uint32 b29, uint32 b30, uint32 b31
620 #define BC_ARGS_32 uint32 b1, uint32 b2, uint32 b3, uint32 b4, uint32 b5, uint32 b6, uint32 b7, uint32 b8, uint32 b9, uint32 b10, uint32 b11, uint32 b12, uint32 b13, uint32 b14, uint32 b15, uint32 b16, uint32 b17, uint32 b18, uint32 b19, uint32 b20, uint32 b21, uint32 b22, uint32 b23, uint32 b24, uint32 b25, uint32 b26, uint32 b27, uint32 b28, uint32 b29, uint32 b30, uint32 b31, uint32 b32
621
622 #define BC_CALL_1(o,cn) {o.cn(b1);}
623 #define BC_CALL_2(o,cn) {o.cn(b1); o.cn(b2);}
624 #define BC_CALL_3(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3);}
625 #define BC_CALL_4(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4);}
626 #define BC_CALL_5(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5);}
627 #define BC_CALL_6(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6);}
628 #define BC_CALL_7(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7);}
629 #define BC_CALL_8(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8);}
630 #define BC_CALL_9(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9);}
631 #define BC_CALL_10(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10);}
632 #define BC_CALL_11(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11);}
633 #define BC_CALL_12(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12);}
634 #define BC_CALL_13(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13);}
635 #define BC_CALL_14(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14);}
636 #define BC_CALL_15(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15);}
637 #define BC_CALL_16(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16);}
638 #define BC_CALL_17(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17);}
639 #define BC_CALL_18(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18);}
640 #define BC_CALL_19(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19);}
641 #define BC_CALL_20(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20);}
642 #define BC_CALL_21(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21);}
643 #define BC_CALL_22(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22);}
644 #define BC_CALL_23(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23);}
645 #define BC_CALL_24(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24);}
646 #define BC_CALL_25(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25);}
647 #define BC_CALL_26(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26);}
648 #define BC_CALL_27(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26); o.cn(b27);}
649 #define BC_CALL_28(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26); o.cn(b27); o.cn(b28);}
650 #define BC_CALL_29(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26); o.cn(b27); o.cn(b28); o.cn(b29);}
651 #define BC_CALL_30(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26); o.cn(b27); o.cn(b28); o.cn(b29); o.cn(b30);}
652 #define BC_CALL_31(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26); o.cn(b27); o.cn(b28); o.cn(b29); o.cn(b30); o.cn(b31);}
653 #define BC_CALL_32(o,cn) {o.cn(b1); o.cn(b2); o.cn(b3); o.cn(b4); o.cn(b5); o.cn(b6); o.cn(b7); o.cn(b8); o.cn(b9); o.cn(b10); o.cn(b11); o.cn(b12); o.cn(b13); o.cn(b14); o.cn(b15); o.cn(b16); o.cn(b17); o.cn(b18); o.cn(b19); o.cn(b20); o.cn(b21); o.cn(b22); o.cn(b23); o.cn(b24); o.cn(b25); o.cn(b26); o.cn(b27); o.cn(b28); o.cn(b29); o.cn(b30); o.cn(b31); o.cn(b32);}
654
655 #define BC_CALL2_1(o,cn) {o.cn(0,b1);}
656 #define BC_CALL2_2(o,cn) {o.cn(0,b1); o.cn(1,b2);}
657 #define BC_CALL2_3(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3);}
658 #define BC_CALL2_4(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4);}
659 #define BC_CALL2_5(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5);}
660 #define BC_CALL2_6(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6);}
661 #define BC_CALL2_7(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7);}
662 #define BC_CALL2_8(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8);}
663 #define BC_CALL2_9(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9);}
664 #define BC_CALL2_10(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10);}
665 #define BC_CALL2_11(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11);}
666 #define BC_CALL2_12(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12);}
667 #define BC_CALL2_13(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13);}
668 #define BC_CALL2_14(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14);}
669 #define BC_CALL2_15(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15);}
670 #define BC_CALL2_16(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16);}
671 #define BC_CALL2_17(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17);}
672 #define BC_CALL2_18(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18);}
673 #define BC_CALL2_19(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19);}
674 #define BC_CALL2_20(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20);}
675 #define BC_CALL2_21(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21);}
676 #define BC_CALL2_22(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22);}
677 #define BC_CALL2_23(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23);}
678 #define BC_CALL2_24(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24);}
679 #define BC_CALL2_25(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25);}
680 #define BC_CALL2_26(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26);}
681 #define BC_CALL2_27(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26); o.cn(26,b27);}
682 #define BC_CALL2_28(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26); o.cn(26,b27); o.cn(27,b28);}
683 #define BC_CALL2_29(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26); o.cn(26,b27); o.cn(27,b28); o.cn(28,b29);}
684 #define BC_CALL2_30(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26); o.cn(26,b27); o.cn(27,b28); o.cn(28,b29); o.cn(29,b30);}
685 #define BC_CALL2_31(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26); o.cn(26,b27); o.cn(27,b28); o.cn(28,b29); o.cn(29,b30); o.cn(30,b31);}
686 #define BC_CALL2_32(o,cn) {o.cn(0,b1); o.cn(1,b2); o.cn(2,b3); o.cn(3,b4); o.cn(4,b5); o.cn(5,b6); o.cn(6,b7); o.cn(7,b8); o.cn(8,b9); o.cn(9,b10); o.cn(10,b11); o.cn(11,b12); o.cn(12,b13); o.cn(13,b14); o.cn(14,b15); o.cn(15,b16); o.cn(16,b17); o.cn(17,b18); o.cn(18,b19); o.cn(19,b20); o.cn(20,b21); o.cn(21,b22); o.cn(22,b23); o.cn(23,b24); o.cn(24,b25); o.cn(25,b26); o.cn(26,b27); o.cn(27,b28); o.cn(28,b29); o.cn(29,b30); o.cn(30,b31); o.cn(31,b32);}
687
688 #define BC_SUM_1(o,cn) (o.cn(b1))
689 #define BC_SUM_2(o,cn) (o.cn(b1)+o.cn(b2))
690 #define BC_SUM_3(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3))
691 #define BC_SUM_4(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4))
692 #define BC_SUM_5(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5))
693 #define BC_SUM_6(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6))
694 #define BC_SUM_7(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7))
695 #define BC_SUM_8(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8))
696 #define BC_SUM_9(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9))
697 #define BC_SUM_10(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10))
698 #define BC_SUM_11(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11))
699 #define BC_SUM_12(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12))
700 #define BC_SUM_13(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13))
701 #define BC_SUM_14(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14))
702 #define BC_SUM_15(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15))
703 #define BC_SUM_16(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16))
704 #define BC_SUM_17(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17))
705 #define BC_SUM_18(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18))
706 #define BC_SUM_19(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19))
707 #define BC_SUM_20(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20))
708 #define BC_SUM_21(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21))
709 #define BC_SUM_22(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22))
710 #define BC_SUM_23(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23))
711 #define BC_SUM_24(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24))
712 #define BC_SUM_25(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25))
713 #define BC_SUM_26(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26))
714 #define BC_SUM_27(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26)+o.cn(b27))
715 #define BC_SUM_28(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26)+o.cn(b27)+o.cn(b28))
716 #define BC_SUM_29(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26)+o.cn(b27)+o.cn(b28)+o.cn(b29))
717 #define BC_SUM_30(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26)+o.cn(b27)+o.cn(b28)+o.cn(b29)+o.cn(b30))
718 #define BC_SUM_31(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26)+o.cn(b27)+o.cn(b28)+o.cn(b29)+o.cn(b30)+o.cn(b31))
719 #define BC_SUM_32(o,cn) (o.cn(b1)+o.cn(b2)+o.cn(b3)+o.cn(b4)+o.cn(b5)+o.cn(b6)+o.cn(b7)+o.cn(b8)+o.cn(b9)+o.cn(b10)+o.cn(b11)+o.cn(b12)+o.cn(b13)+o.cn(b14)+o.cn(b15)+o.cn(b16)+o.cn(b17)+o.cn(b18)+o.cn(b19)+o.cn(b20)+o.cn(b21)+o.cn(b22)+o.cn(b23)+o.cn(b24)+o.cn(b25)+o.cn(b26)+o.cn(b27)+o.cn(b28)+o.cn(b29)+o.cn(b30)+o.cn(b31)+o.cn(b32))
720
721 # define BC_VARIADIC_CTOR(X) explicit BitChord(BC_ARGS_##X) {ClearAllBits(); BC_CALL_##X((*this), SetBit);}
722 # define BC_SET_BITS(X) void SetBits(BC_ARGS_##X) {BC_CALL_##X((*this), SetBit);}
723 # define BC_CLEAR_BITS(X) void ClearBits(BC_ARGS_##X) {BC_CALL_##X((*this), ClearBit);}
724 # define BC_TOGGLE_BITS(X) void ToggleBits(BC_ARGS_##X) {BC_CALL_##X((*this), ToggleBit);}
725 # define BC_WITH_BITS(X) BitChord WithBits(BC_ARGS_##X) const {BitChord ret(*this); BC_CALL_##X(ret, SetBit); return ret;}
726 # define BC_WITHOUT_BITS(X) BitChord WithoutBits(BC_ARGS_##X) const {BitChord ret(*this); BC_CALL_##X(ret, ClearBit); return ret;}
727 # define BC_WITH_TOGGLED_BITS(X) BitChord WithToggledBits(BC_ARGS_##X) const {BitChord ret(*this); BC_CALL_##X(ret, ToggleBit); return ret;}
728 # define BC_WITH_ALL_EXCEPT(X) static BitChord WithAllBitsSetExceptThese(BC_ARGS_##X) {BitChord ret; ret.SetAllBits(); BC_CALL_##X(ret, ClearBit); return ret;}
729 # define BC_FROM_BYTES(X) static BitChord FromBytes(BC_ARGS_##X) {BitChord ret; BC_CALL2_##X(ret, SetByte); return ret;}
730 # define BC_FROM_WORDS(X) static BitChord FromWords(BC_ARGS_##X) {BitChord ret; BC_CALL2_##X(ret, SetWord); return ret;}
731 # define BC_ARE_ANY_BITS_SET(X) bool AreAnyOfTheseBitsSet(BC_ARGS_##X) const {return BC_SUM_##X((*this), OneIffBitIsSet) > 0;}
732 # define BC_ARE_ALL_BITS_SET(X) bool AreAllOfTheseBitsSet(BC_ARGS_##X) const {return BC_SUM_##X((*this), OneIffBitIsUnset) == 0;}
733 # define BC_ARE_ANY_BITS_UNSET(X) bool AreAnyOfTheseBitsUnset(BC_ARGS_##X) const {return BC_SUM_##X((*this), OneIffBitIsUnset) > 0;}
734 # define BC_ARE_ALL_BITS_UNSET(X) bool AreAllOfTheseBitsUnset(BC_ARGS_##X) const {return BC_SUM_##X((*this), OneIffBitIsSet) == 0;}
735 # define BC_DECLARE_ALL(X) X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) X(18) X(19) X(20) X(21) X(22) X(23) X(24) X(25) X(26) X(27) X(28) X(29) X(30) X(31) X(32)
736
737 // These macros expand out to all 32 supported overrides of each method...
738 BC_DECLARE_ALL(BC_VARIADIC_CTOR);
739 BC_DECLARE_ALL(BC_SET_BITS);
740 BC_DECLARE_ALL(BC_CLEAR_BITS);
741 BC_DECLARE_ALL(BC_TOGGLE_BITS);
742 BC_DECLARE_ALL(BC_WITH_BITS);
743 BC_DECLARE_ALL(BC_WITHOUT_BITS);
744 BC_DECLARE_ALL(BC_WITH_TOGGLED_BITS);
745 BC_DECLARE_ALL(BC_WITH_ALL_EXCEPT);
746 BC_DECLARE_ALL(BC_FROM_BYTES);
747 BC_DECLARE_ALL(BC_FROM_WORDS);
748 BC_DECLARE_ALL(BC_ARE_ANY_BITS_SET);
749 BC_DECLARE_ALL(BC_ARE_ALL_BITS_SET);
750 BC_DECLARE_ALL(BC_ARE_ANY_BITS_UNSET);
751 BC_DECLARE_ALL(BC_ARE_ALL_BITS_UNSET);
752 # endif
753 #endif
754 };
755
756 /** Binary bitwise-OR operator for two BitChord objects
757 * @param lhs The first BitChord object to OR together
758 * @param rhs The first BitChord object to OR together
759 * @returns a BitChord whose bits are the union of the bits of the two arguments
760 */
761 template<uint32 NumBits, class TagClass> const BitChord<NumBits,TagClass> operator | (const BitChord<NumBits,TagClass> & lhs, const BitChord<NumBits,TagClass> & rhs) {BitChord<NumBits,TagClass> ret(lhs); ret |= rhs; return ret;}
762
763 /** Binary bitwise-AND operator for two BitChord objects
764 * @param lhs The first BitChord object to AND together
765 * @param rhs The first BitChord object to AND together
766 * @returns a BitChord whose bits are the intersection of the bits of the two arguments
767 */
768 template<uint32 NumBits, class TagClass> const BitChord<NumBits,TagClass> operator & (const BitChord<NumBits,TagClass> & lhs, const BitChord<NumBits,TagClass> & rhs) {BitChord<NumBits,TagClass> ret(lhs); ret &= rhs; return ret;}
769
770 /** Binary bitwise-XOR operator for two BitChord objects
771 * @param lhs The first BitChord object to XOR together
772 * @param rhs The first BitChord object to XOR together
773 * @returns a BitChord whose bits are the XOR of the bits of the two arguments
774 */
775 template<uint32 NumBits, class TagClass> const BitChord<NumBits,TagClass> operator ^ (const BitChord<NumBits,TagClass> & lhs, const BitChord<NumBits,TagClass> & rhs) {BitChord<NumBits,TagClass> ret(lhs); ret ^= rhs; return ret;}
776
777 /** This macros declares a unique BitChord-type with a specified number of bits.
778 * @param typeName the name of the new type e.g. (MySpecialFlags)
779 * @param numBitsInType the number of bits a BitChord of this type will represent
780 * @note Example usage: enum {OPTION_A=0, OPTION_B, OPTION_C, NUM_OPTIONS}; DECLARE_BITCHORD_FLAGS_TYPE(MyOptionFlags, NUM_OPTIONS);
781 */
782 #define DECLARE_BITCHORD_FLAGS_TYPE(typeName, numBitsInType) struct _bitchord_tag_class_##typeName##_##numBitsInType {}; typedef BitChord<numBitsInType, _bitchord_tag_class_##typeName##_##numBitsInType> typeName;
783
784 } // end namespace muscle
785
786 #endif