home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tlx501.zip / SRC / BITVECT.CPP < prev    next >
C/C++ Source or Header  |  1996-07-08  |  22KB  |  676 lines

  1. /****************************************************************************
  2.     $Id: bitvect.cpp 501.0 1995/03/07 12:26:08 RON Exp $
  3.  
  4.     Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
  5.  
  6.     Project:    Tarma Library for C++ V5.0
  7.     Author:    Ron van der Wal
  8.  
  9.     Implementation of class TLBitVector.
  10.  
  11.     $Log: bitvect.cpp $
  12.     Revision 501.0  1995/03/07 12:26:08  RON
  13.     Updated for TLX 5.01
  14.     Revision 1.10  1995/01/31 16:30:04  RON
  15.     Update for release 012
  16.     Added partial support for SunPro C++ compiler
  17.     Revision 1.9  1995/01/06  15:57:26  ron
  18.     Corrected Revision keyword
  19.  
  20.     Revision 1.8  1994/11/16  15:36:28  ron
  21.     Changed several signed/unsigned conflicts
  22.     Added module info; rearranged #include directives
  23.  
  24.     Revision 1.7  1994/10/07  17:00:27  ron
  25.     Corrected useless value >> 1 code to value >>= 1
  26.  
  27.     Revision 1.6  1994/10/05  18:34:33  ron
  28.     Formatting changes
  29.  
  30.     Revision 1.5  1994/09/28  14:13:42  ron
  31.     Removed Macintosh-style #include references
  32.  
  33.     Revision 1.4  1994/09/27  20:22:03  ron
  34.     Changed path separator from / to \
  35.  
  36.     Revision 1.3  1994/09/26  15:40:04  ron
  37.     Changed from size_t to index_t bit indices
  38.  
  39.     Revision 1.2  1994/09/06  14:10:43  ron
  40.     Adapted to changes in tlx.h
  41.  
  42.     Revision 1.1  1994/08/16  18:12:54  ron
  43.     Initial revision
  44.  
  45. ****************************************************************************/
  46.  
  47. #include <tlx\501\_build.h>
  48.  
  49. TLX_MODULE_INFO("$Revision: 501.0 $");
  50.  
  51. #include <iostream.h>
  52. #include <stdlib.h>        // mem... routines
  53. #include <string.h>        // mem... routines
  54. #include <tlx\501\bitvect.h>
  55. #include <tlx\501\except.h>
  56.  
  57. /*---------------------------------------------------------------------------
  58.     Implementation notes:
  59.     ---------------------
  60.     Throughout this file, we assume that:
  61.  
  62.     - kMaxAlloc < kMaxSize (kMaxSize = maximum value of size_t type)
  63.     - each TLBitVector allocation will be <= kMaxAlloc
  64.  
  65.     and that therefore:
  66.  
  67.     - max(ByteIndex()) will be strictly less than kMaxSize
  68.     - max(ByteIndex()) + 1 is still within the 'size_t' range.
  69.  
  70.     We also use the malloc()/free() family of memory allocators to take
  71.     advantage of the realloc() facility; operator new()/delete() do not
  72.     have a similar renew().
  73.  
  74.     Layout of bits within vector
  75.     ----------------------------
  76.     The BitVector class allocates a vector of bytes (with CHAR_BIT bits/
  77.     byte) to store the individual bits. The position of bits as indexed
  78.     with the various BitVector member functions is as follows:
  79.  
  80.               +-----------------------++-----------------------++------
  81.               |07 06 05 04 03 02 01 00||15 14 13 12 11 10 09 08||23 22  etc.
  82.               +-----------------------++-----------------------++------
  83.  BitIndex(bit)  7  6  5  4  3  2  1  0   7  6  5  4  3  2  1  0   7  6
  84. ByteIndex(bit) \----------0-----------/\-----------1-----------/\------
  85.  
  86. ---------------------------------------------------------------------------*/
  87.  
  88. /*---------------------------------------------------------------------------
  89.     Implementation helper functions. Return the byte and bit indices of
  90.     a given bit in the vector.
  91. ---------------------------------------------------------------------------*/
  92.  
  93. inline size_t BitIndex(size_t bit) { return bit % CHAR_BIT; }
  94. inline size_t ByteIndex(size_t bit) { return bit / CHAR_BIT; }
  95.  
  96. /*-------------------------------------------------------------------------*/
  97.     TLBitVector::TLBitVector(size_t aLimit)
  98.  
  99. /*  Constructor, also doubles as the default constructor. Creates a
  100.     bitvector with the given initial bit size.
  101. ---------------------------------------------------------------------------*/
  102. {
  103.     mVector   = 0;
  104.     mBitSize  =
  105.     mVectSize = 0;
  106.     Resize(aLimit);
  107. }
  108.  
  109. /*-------------------------------------------------------------------------*/
  110.     TLBitVector::TLBitVector(const char *aVector)
  111.  
  112. /*  Constructor that takes a C-style string to specify the length and
  113.     initial values of the bitvector. The new bitvector has a length
  114.     equal to strlen(aVector) and has '1' bits in each position, except
  115.     where 'aVector' contains '0' characters.
  116. ---------------------------------------------------------------------------*/
  117. {
  118.     TLX_ASSERT_PTR(aVector);
  119.  
  120.     mVector   = 0;
  121.     mBitSize  =
  122.     mVectSize = 0;
  123.     Resize(strlen(aVector));
  124.  
  125.     for (size_t i = 0; i < mBitSize; i++)
  126.     if (aVector[i] != '0')
  127.         Set(i);
  128. }
  129.  
  130. /*-------------------------------------------------------------------------*/
  131.     TLBitVector::TLBitVector(const TLBitVector &bv)
  132.  
  133. /*  Copy constructor. Allocates its own vector.
  134. ---------------------------------------------------------------------------*/
  135. {
  136.     mBitSize = bv.mBitSize;
  137.  
  138.     // By definition, sizeof(byte_t) == 1
  139.     mVector = (byte_t *) malloc(mVectSize = bv.mVectSize);
  140.  
  141.     if (TLX_CHECK_PTR(mVector))
  142.     memcpy(mVector, bv.mVector, mVectSize);
  143.     else
  144.         mBitSize = mVectSize = 0;
  145. }
  146.  
  147. /*-------------------------------------------------------------------------*/
  148.     TLBitVector::~TLBitVector()
  149.  
  150. /*  Destructor. Deletes allocated vector.
  151. ---------------------------------------------------------------------------*/
  152. {
  153.     if (mVector) free(mVector);
  154. }
  155.  
  156. /*-------------------------------------------------------------------------*/
  157.     size_t TLBitVector::First() const
  158.  
  159. /*  Returns the index of the first '1' bit in the vector. It is an error
  160.     to call this function if the vector is empty.
  161. ---------------------------------------------------------------------------*/
  162. {
  163.     if (IsEmpty())
  164.     THROW(TLXEmpty(LOCUS));
  165.  
  166.     // Search byte-wise for the first non-0 byte
  167.     byte_t *bptr = mVector;
  168.     for (size_t i = 0; i < mVectSize; i++, bptr++) {
  169.     if (*bptr) {
  170.         // Found byte; now locate first bit
  171.         byte_t value = *bptr;
  172.         for (size_t bit = 0; bit < 8; bit++) {
  173.         if (value & 1)
  174.             return i * CHAR_BIT + bit;
  175.         value >>= 1;
  176.         }
  177.         TLX_ASSERT_UNREACHABLE;
  178.     }
  179.     }
  180.  
  181.     TLX_ASSERT_UNREACHABLE;
  182.     return 0;
  183. }
  184.  
  185. /*-------------------------------------------------------------------------*/
  186.     void TLBitVector::Invert()
  187.  
  188. /*  Inverts all bits in the vector.
  189. ---------------------------------------------------------------------------*/
  190. {
  191.     byte_t *aPtr = mVector;
  192.     for (size_t i = mVectSize; i; i--)
  193.     *aPtr++ ^= 0xff;
  194. }
  195.  
  196. /*-------------------------------------------------------------------------*/
  197.     void TLBitVector::Invert(size_t bit)
  198.  
  199. /*  Inverts the given bit.
  200. ---------------------------------------------------------------------------*/
  201. {
  202.     if (!IsValidIndex(bit))
  203.     THROW(TLXIndex(LOCUS, (index_t)bit));
  204.  
  205.     mVector[ByteIndex(bit)] ^= (char)(1 << BitIndex(bit));
  206. }
  207.  
  208. /*-------------------------------------------------------------------------*/
  209.     void TLBitVector::Invert(size_t from, size_t to)
  210.  
  211. /*  Inverts all bits in the given range.
  212. ---------------------------------------------------------------------------*/
  213. {
  214.     if (!IsValidIndex(from))
  215.     THROW(TLXIndex(LOCUS, (index_t)from));
  216.     if (!IsValidIndex(to))
  217.     THROW(TLXIndex(LOCUS, (index_t)to));
  218.  
  219.     if (from > to) return;
  220.  
  221.     size_t i1 = ByteIndex(from);
  222.     size_t i2 = ByteIndex(to);
  223.  
  224.     // Invert all but the first and last bytes
  225.     if (i2 > i1 + 1) {
  226.     byte_t *aPtr = &mVector[i1 + 1];
  227.     for (size_t i = i2 - i1 - 1; i; i--)
  228.         *aPtr++ ^= 0xff;
  229.     }
  230.  
  231.     char lowPattern  = (char)(0xff << BitIndex(from));
  232.     char highPattern = (char)(0xff >> (CHAR_BIT - BitIndex(to) - 1));
  233.  
  234.     // Invert the first and the last byte(s)
  235.     if (i1 == i2)
  236.     mVector[i1] ^= (lowPattern & highPattern);
  237.     else {
  238.     mVector[i1] ^= lowPattern;
  239.     mVector[i2] ^= highPattern;
  240.     }
  241. }
  242.  
  243. /*-------------------------------------------------------------------------*/
  244.     bool TLBitVector::IsEmpty() const
  245.  
  246. /*  Checks whether the bitvector is empty, i.e. contains no '1' bits.
  247. ---------------------------------------------------------------------------*/
  248. {
  249.     return Test() == 0;
  250. }
  251.  
  252. /*-------------------------------------------------------------------------*/
  253.     bool TLBitVector::IsValidIndex(size_t aIndex) const
  254.  
  255. /*  Tests whether the given bit index is valid for the bitvector. Returns
  256.     nonzero if it is, else zero.
  257. ---------------------------------------------------------------------------*/
  258. {
  259.     return aIndex < mBitSize;
  260. }
  261.  
  262. /*-------------------------------------------------------------------------*/
  263.     size_t TLBitVector::Last() const
  264.  
  265. /*  Returns the index of the last '1' bit in the vector. It is an error
  266.     to call this function if the vector is empty.
  267. ---------------------------------------------------------------------------*/
  268. {
  269.     if (IsEmpty())
  270.     THROW(TLXEmpty(LOCUS));
  271.  
  272.     // Search byte-wise for the last non-0 byte
  273.     TLX_ASSERT(mVectSize > 0);
  274.     byte_t *bptr = &mVector[mVectSize - 1];
  275.     for (size_t i = mVectSize; i; i--, bptr--) {
  276.     if (*bptr) {
  277.         // Found byte; now locate last bit
  278.         byte_t value = *bptr;
  279.         for (size_t bit = 0; bit < 8; bit++) {
  280.         if (value & 0x80) {
  281.             TLX_ASSERT(i > 0);
  282.             return (i - 1) * CHAR_BIT + (7 - bit);
  283.         }
  284.         value <<= 1;
  285.         }
  286.         TLX_ASSERT_UNREACHABLE;
  287.     }
  288.     }
  289.  
  290.     TLX_ASSERT_UNREACHABLE;
  291.     return 0;
  292. }
  293.  
  294. /*-------------------------------------------------------------------------*/
  295.     TLBitVector &TLBitVector::operator =(const TLBitVector &bv)
  296.  
  297. /* Overloading of asignment operator to create a new copy of the actual
  298.    vector.
  299. ---------------------------------------------------------------------------*/
  300. {
  301.     if (this != &bv) {        // Check for assignment to self
  302.         if (mBitSize != bv.mBitSize)
  303.         Resize(bv.mBitSize);
  304.         memcpy(mVector, bv.mVector, mVectSize);
  305.     }
  306.     return *this;
  307. }
  308.  
  309. /*-------------------------------------------------------------------------*/
  310.     TLBitVector &TLBitVector::operator &=(const TLBitVector &bv)
  311.  
  312. /*  Performs bitwise AND on the current vector and its argument.
  313. ---------------------------------------------------------------------------*/
  314. {
  315.     size_t size = tlMin(mVectSize, bv.mVectSize);
  316.  
  317.     // Perform 'and' on the common part
  318.     for (size_t i = 0; i < size; i++)
  319.         mVector[i] &= bv.mVector[i];
  320.  
  321.     // If the current vector is larger than the other one, set the remaining
  322.     // bits to 0 as if the other vector were extended with '0' bits.
  323.     if (size < mVectSize)
  324.         memset(&mVector[size], 0, mVectSize - size);
  325.  
  326.     return *this;
  327. }
  328.  
  329. /*-------------------------------------------------------------------------*/
  330.     TLBitVector &TLBitVector::operator ^=(const TLBitVector &bv)
  331.  
  332. /*  Performs bitwise XOR on the current vector and its argument.
  333. ---------------------------------------------------------------------------*/
  334. {
  335.     size_t size = tlMin(mVectSize, bv.mVectSize);
  336.  
  337.     for (size_t i = 0; i < size; i++)
  338.         mVector[i] ^= bv.mVector[i];
  339.  
  340.     return *this;
  341. }
  342.  
  343. /*-------------------------------------------------------------------------*/
  344.     TLBitVector &TLBitVector::operator |=(const TLBitVector &bv)
  345.  
  346. /*  Performs bitwise OR on the current vector and its argument.
  347. ---------------------------------------------------------------------------*/
  348. {
  349.     size_t size = tlMin(mVectSize, bv.mVectSize);
  350.  
  351.     for (size_t i = 0; i < size; i++)
  352.         mVector[i] |= bv.mVector[i];
  353.  
  354.     return *this;
  355. }
  356.  
  357. /*-------------------------------------------------------------------------*/
  358.     void TLBitVector::Reset()
  359.  
  360. /*  Sets all bits to 0.
  361. ---------------------------------------------------------------------------*/
  362. {
  363.     memset(mVector, 0, mVectSize);
  364. }
  365.  
  366. /*-------------------------------------------------------------------------*/
  367.     void TLBitVector::Reset(size_t bit)
  368.  
  369. /*  Sets a single bit to 0.
  370. ---------------------------------------------------------------------------*/
  371. {
  372.     if (!IsValidIndex(bit))
  373.     THROW(TLXIndex(LOCUS, (index_t)bit));
  374.  
  375.     mVector[ByteIndex(bit)] &= (byte_t)(~(1U << BitIndex(bit)));
  376. }
  377.  
  378. /*-------------------------------------------------------------------------*/
  379.     void TLBitVector::Reset(size_t from, size_t to)
  380.  
  381. /*  Sets all bits in a range to 0.
  382. ---------------------------------------------------------------------------*/
  383. {
  384.     if (!IsValidIndex(from))
  385.     THROW(TLXIndex(LOCUS, (index_t)from));
  386.     if (!IsValidIndex(to))
  387.     THROW(TLXIndex(LOCUS, (index_t)to));
  388.  
  389.     if (from > to) return;
  390.  
  391.     size_t i1 = ByteIndex(from);
  392.     size_t i2 = ByteIndex(to);
  393.  
  394.     // Clear ranges of bytes (if any)
  395.     if (i2 > i1 + 1) memset(&mVector[i1 + 1], 0, i2 - i1 - 1);
  396.  
  397.     // Clear remaining bits at the low and high ends
  398.     char lowPattern  = (char)(0xff << BitIndex(from));
  399.     char highPattern = (char)(0xff >> (CHAR_BIT - BitIndex(to) - 1));
  400.  
  401.     if (i1 == i2)
  402.     mVector[i1] &= (lowPattern | highPattern);
  403.     else {
  404.     mVector[i1] &= lowPattern;
  405.     mVector[i2] &= highPattern;
  406.     }
  407. }
  408.  
  409. /*-------------------------------------------------------------------------*/
  410.     void TLBitVector::Resize(size_t aBitSize)
  411.  
  412.  
  413. /*  Changes the bit size of the vector. This might involve resizing the
  414.     underlying byte vector.
  415. ---------------------------------------------------------------------------*/
  416. {
  417.     if (aBitSize == mBitSize) return;
  418.  
  419.     // Round size up to next multiple of CHAR_BIT
  420.     size_t newVectSize = (aBitSize + CHAR_BIT - 1) / CHAR_BIT;
  421.  
  422.     // According to our assumptions (see Implementation Note above), it
  423.     // should not be possible for the new byte vector size to be larger
  424.     // than the maximum allocation size... But we'll check nevertheless.
  425.     TLX_ASSERT(newVectSize <= kMaxAlloc);
  426.  
  427.     if (newVectSize == mVectSize) {
  428.     // Byte vector is the right size; just resize the bit vector and
  429.     // clear out the new bits in the last byte of the byte vector.
  430.     if (aBitSize > mBitSize) {
  431.         TLX_ASSERT(ByteIndex(aBitSize-1) == ByteIndex(mBitSize-1));
  432.         mVector[ByteIndex(mBitSize-1)] &=
  433.             (char)(0xff >> (CHAR_BIT - BitIndex(mBitSize-1) - 1));
  434.     } else {
  435.         mVector[ByteIndex(aBitSize-1)] &=
  436.             (char)(0xff >> (CHAR_BIT - BitIndex(aBitSize-1) - 1));
  437.     }
  438.  
  439.     mBitSize = aBitSize;
  440.     } else {
  441.     // We need to resize the byte vector before we resize the bit vector.
  442.     // We take advantage of the following behavior of realloc():
  443.     //
  444.     // - if the original pointer was 0, it works like malloc()
  445.     // - if the new size is 0, it works like free()
  446.  
  447.     byte_t *tmp = (byte_t *) realloc(mVector, newVectSize);
  448.     if (tmp == 0 && newVectSize > 0)
  449.         THROW(TLXAlloc(LOCUS, newVectSize));
  450.  
  451.     // Vector resized; clear out new bytes and the last bits in
  452.     // the newly created copy. If the new vector is larger than
  453.     // the old vector, we clear everything from the previous bit
  454.     // size upwards; else (new vector smaller) we clear from the
  455.     // new bit size onwards. In the latter case, we only have to
  456.     // clear out the last byte of the new vector.
  457.  
  458.     if (newVectSize > mVectSize) {
  459.         memset(&tmp[mVectSize], 0, newVectSize - mVectSize);
  460.         tmp[ByteIndex(mBitSize-1)] &=
  461.             (char)(0xff >> (CHAR_BIT - BitIndex(mBitSize-1) - 1));
  462.     } else {
  463.         // New vector is smaller
  464.         tmp[ByteIndex(aBitSize-1)] &=
  465.             (char)(0xff >> (CHAR_BIT - BitIndex(aBitSize-1) - 1));
  466.     }
  467.  
  468.     mVector   = tmp;    // It may have moved
  469.     mVectSize = newVectSize;
  470.     mBitSize  = aBitSize;
  471.     }
  472. }
  473.  
  474. /*-------------------------------------------------------------------------*/
  475.     void TLBitVector::Set()
  476.  
  477. /*  Sets all bits to 1.
  478. ---------------------------------------------------------------------------*/
  479. {
  480.     memset(mVector, 0xff, mVectSize);
  481.     if (mVectSize * CHAR_BIT > mBitSize) {
  482.         mVector[ByteIndex(mBitSize-1)] &=
  483.         (char)(0xff >> (CHAR_BIT - BitIndex(mBitSize-1) - 1));
  484.     }
  485. }
  486.  
  487. /*-------------------------------------------------------------------------*/
  488.     void TLBitVector::Set(size_t bit)
  489.  
  490. /*  Sets a single bit to 1.
  491. ---------------------------------------------------------------------------*/
  492. {
  493.     if (!IsValidIndex(bit))
  494.     THROW(TLXIndex(LOCUS, (index_t)bit));
  495.  
  496.     mVector[ByteIndex(bit)] |= (char)(1 << BitIndex(bit));
  497. }
  498.  
  499. /*-------------------------------------------------------------------------*/
  500.     void TLBitVector::Set(size_t from, size_t to)
  501.  
  502. /*  Sets all bits in a range to 1.
  503. ---------------------------------------------------------------------------*/
  504. {
  505.     if (!IsValidIndex(from))
  506.     THROW(TLXIndex(LOCUS, (index_t)from));
  507.     if (!IsValidIndex(to))
  508.     THROW(TLXIndex(LOCUS, (index_t)to));
  509.  
  510.     if (from > to) return;
  511.  
  512.     size_t i1 = ByteIndex(from);
  513.     size_t i2 = ByteIndex(to);
  514.  
  515.     if (i2 > i1 + 1)
  516.         memset(&mVector[i1 + 1], 0xff, i2 - i1 - 1);
  517.  
  518.     char lowPattern  = (char)(0xff << BitIndex(from));
  519.     char highPattern = (char)(0xff >> (CHAR_BIT - BitIndex(to) - 1));
  520.  
  521.     if (i1 == i2)
  522.     mVector[i1] |= (lowPattern & highPattern);
  523.     else {
  524.     mVector[i1] |= lowPattern;
  525.     mVector[i2] |= highPattern;
  526.     }
  527. }
  528.  
  529. /*---------------------------------------------------------------------------
  530.     Helper function that counts bits in a byte by counting the bits in its
  531.     nibbles.
  532. ---------------------------------------------------------------------------*/
  533.  
  534. static size_t bit_table[16] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
  535.  
  536. inline size_t bit_count(byte_t b)
  537.     { return bit_table[b & 0xf] + bit_table[(b & 0xf0) >> 4]; }
  538.  
  539. /*-------------------------------------------------------------------------*/
  540.     size_t TLBitVector::Test() const
  541.  
  542. /*  Returns number of bits set in the vector.
  543. ---------------------------------------------------------------------------*/
  544. {
  545.     size_t cnt   = 0;
  546.     byte_t *aPtr = mVector;
  547.  
  548.     for (size_t aTop = mVectSize; aTop; aTop--, aPtr++)
  549.     cnt += bit_count(*aPtr);
  550.     return cnt;
  551. }
  552.  
  553. /*-------------------------------------------------------------------------*/
  554.     size_t TLBitVector::Test(size_t bit) const
  555.  
  556. /*  Returns 1 if bit is set, else 0.
  557. ---------------------------------------------------------------------------*/
  558. {
  559.     if (!IsValidIndex(bit))
  560.     THROW(TLXIndex(LOCUS, (index_t)bit));
  561.  
  562.     return (mVector[ByteIndex(bit)] & (1 << BitIndex(bit))) != 0;
  563. }
  564.  
  565. /*-------------------------------------------------------------------------*/
  566.     size_t TLBitVector::Test(size_t from, size_t to) const
  567.  
  568. /*  Returns number of bits set in a range.
  569. ---------------------------------------------------------------------------*/
  570. {
  571.     if (!IsValidIndex(from))
  572.     THROW(TLXIndex(LOCUS, (index_t)from));
  573.     if (!IsValidIndex(to))
  574.     THROW(TLXIndex(LOCUS, (index_t)to));
  575.  
  576.     if (from > to) return 0;
  577.  
  578.     size_t i1  = ByteIndex(from);
  579.     size_t i2  = ByteIndex(to);
  580.     size_t cnt = 0;
  581.  
  582.     if (i2 > i1 + 1) {
  583.     byte_t *aPtr = &mVector[i1 + 1];
  584.     for (size_t i = i2 - i1 - 1; i; i--)
  585.         cnt += bit_count(*aPtr);
  586.     }
  587.  
  588.     byte_t lowPattern  = (byte_t)(0xff << BitIndex(from));
  589.     byte_t highPattern = (byte_t)(0xff >> (CHAR_BIT - 1 - BitIndex(to)));
  590.  
  591.     if (i1 == i2)
  592.     cnt += bit_count(mVector[i1] & (lowPattern | highPattern));
  593.     else {
  594.     cnt += bit_count(mVector[i1] & lowPattern);
  595.     cnt += bit_count(mVector[i2] & highPattern);
  596.     }
  597.     return cnt;
  598. }
  599.  
  600. /*-------------------------------------------------------------------------*/
  601.     TLBitVector _TLXFUNC operator ~(const TLBitVector &bv)
  602.  
  603. /*  Creates inverse of bit vector.
  604. ---------------------------------------------------------------------------*/
  605. {
  606.     TLBitVector result = bv;
  607.     result.Invert();
  608.     return result;
  609. }
  610.  
  611. /*-------------------------------------------------------------------------*/
  612.     TLBitVector _TLXFUNC operator &(
  613.         const TLBitVector &bv1,
  614.     const TLBitVector &bv2
  615.     )
  616.  
  617. /*  Creates bitwise AND of both vectors.
  618. ---------------------------------------------------------------------------*/
  619. {
  620.     TLBitVector result = bv1;
  621.     return result &= bv2;
  622. }
  623.  
  624. /*-------------------------------------------------------------------------*/
  625.     TLBitVector _TLXFUNC operator ^(
  626.         const TLBitVector &bv1,
  627.     const TLBitVector &bv2
  628.     )
  629.  
  630. /*  Creates bitwise XOR of both vectors.
  631. ---------------------------------------------------------------------------*/
  632. {
  633.     TLBitVector result = bv1;
  634.     return result ^= bv2;
  635. }
  636.  
  637. /*-------------------------------------------------------------------------*/
  638.     TLBitVector _TLXFUNC operator |(
  639.         const TLBitVector &bv1,
  640.     const TLBitVector &bv2
  641.     )
  642.  
  643. /*  Creates bitwise or of both vectors.
  644. ---------------------------------------------------------------------------*/
  645. {
  646.     TLBitVector result = bv1;
  647.     return result |= bv2;
  648. }
  649.  
  650. /*-------------------------------------------------------------------------*/
  651.     bool _TLXFUNC operator ==(const TLBitVector &bv1, const TLBitVector &bv2)
  652.  
  653. /*  Compares BitVectors bitwise, returning one of the following values:
  654.  
  655.     < 0 if the first one is less than the second one
  656.       0 if they are equal
  657.     > 0 if the first one is greater than the second one
  658. ---------------------------------------------------------------------------*/
  659. {
  660.     return bv1.mVectSize == bv2.mVectSize &&
  661.         memcmp(bv1.mVector, bv2.mVector, bv1.mVectSize) == 0;
  662. }
  663.  
  664. /*-------------------------------------------------------------------------*/
  665.     ostream & _TLXFUNC operator <<(ostream &os, const TLBitVector &bv)
  666.  
  667. /*  Overloading of the stream output operator for bitvectors. The bits are
  668.     printed from index 0 to Size() - 1.
  669. ---------------------------------------------------------------------------*/
  670. {
  671.     for (size_t i = 0; i < bv.mBitSize; i++)
  672.         os << bv.Test(i);
  673.     return os;
  674. }
  675.  
  676.