"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