BitArray.cpp
author StephaneLenclud
Sat, 07 Feb 2015 13:50:11 +0100
changeset 32 2c844ef1ff4b
parent 0 0f874d9e4130
permissions -rw-r--r--
MDM166AA: Improved icon APIs.
     1 /***************************************************************************
     2 *                         Arrays of Arbitrary Bit Length
     3 *
     4 *   File    : bitarray.cpp
     5 *   Purpose : Provides object with methods for creation and manipulation of
     6 *             arbitrary length arrays of bits.
     7 *
     8 *             Bit arrays are implemented as vectors of unsigned chars.  Bit
     9 *             0 is the MSB of char 0, and the last bit is the least
    10 *             significant (non-spare) bit of the last unsigned char.
    11 *
    12 *             Example: array of 20 bits (0 through 19) with 8 bit unsigned
    13 *                      chars requires 3 unsigned chars (0 through 2) to
    14 *                      store all the bits.
    15 *
    16 *                        char       0       1         2
    17 *                               +--------+--------+--------+
    18 *                               |        |        |        |
    19 *                               +--------+--------+--------+
    20 *                        bit     01234567 8911111111111XXXX
    21 *                                           012345 6789
    22 *
    23 *   Author  : Michael Dipperstein
    24 *   Date    : July 23, 2004
    25 *
    26 ****************************************************************************
    27 *   HISTORY
    28 *
    29 *   $Id: bitarray.cpp,v 1.7 2010/02/04 03:31:43 michael Exp $
    30 *   $Log: bitarray.cpp,v $
    31 *   Revision 1.7  2010/02/04 03:31:43  michael
    32 *   Replaced vector<unsigned char> with an array of unsigned char.
    33 *
    34 *   Made updates for GCC 4.4.
    35 *
    36 *   Revision 1.5  2007/08/06 05:23:29  michael
    37 *   Updated for LGPL Version 3.
    38 *
    39 *   All methods that don't modify object have been made
    40 *   const to increase functionality of const bit_array_c.
    41 *
    42 *   All assignment operators return a reference to the object being assigned a value so that operator chaining will work.
    43 *
    44 *   Added >> and << operators.
    45 *
    46 *   Revision 1.3  2006/04/30 23:34:07  michael
    47 *   Improved performance by incorporating Benjamin Schindler's
    48 *   <bschindler@student.ethz.ch> changes to pass arguments as a reference.
    49 *
    50 *   Revision 1.2  2004/08/05 22:16:49  michael
    51 *   Add overloads for bitwise operators returning values.
    52 *   Add a more natural looking way to set bit values.
    53 *
    54 *   Revision 1.1.1.1  2004/08/04 13:28:20  michael
    55 *   bit_array_c
    56 *
    57 ****************************************************************************
    58 *
    59 * Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays
    60 * Copyright (C) 2004, 2006-2007, 2010 by
    61 *       Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
    62 *
    63 * This file is part of the bit array library.
    64 *
    65 * The bit array library is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU Lesser General Public License as
    67 * published by the Free Software Foundation; either version 3 of the
    68 * License, or (at your option) any later version.
    69 *
    70 * The bit array library is distributed in the hope that it will be useful,
    71 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    72 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
    73 * General Public License for more details.
    74 *
    75 * You should have received a copy of the GNU Lesser General Public License
    76 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    77 *
    78 ***************************************************************************/
    79 
    80 /***************************************************************************
    81 *                             INCLUDED FILES
    82 ***************************************************************************/
    83 #include <iostream>
    84 #include <climits>
    85 #include "bitarray.h"
    86 
    87 using namespace std;
    88 
    89 /***************************************************************************
    90 *                                 MACROS
    91 ***************************************************************************/
    92 
    93 /* make CHAR_BIT 8 if it's not defined in limits.h */
    94 #ifndef CHAR_BIT
    95 #warning CHAR_BIT not defined.  Assuming 8 bits.
    96 #define CHAR_BIT 8
    97 #endif
    98 
    99 /* position of bit within character */
   100 #define BIT_CHAR(bit)         ((bit) / CHAR_BIT)
   101 
   102 /* array index for character containing bit */
   103 //SL: We had to change that macro since bits in our frame buffer are the other way around
   104 //TODO: Find a solution to tackle that problem
   105 
   106 //Bits are indexed: 01234567
   107 //#define BIT_IN_CHAR(bit)      (1 << (CHAR_BIT - 1 - ((bit)  % CHAR_BIT)))
   108 
   109 //Bits are indexed: 76543210
   110 //#define BIT_IN_CHAR(bit)      (1 << (((bit)  % CHAR_BIT)))
   111 
   112 /* number of characters required to contain number of bits */
   113 #define BITS_TO_CHARS(bits)   ((((bits) - 1) / CHAR_BIT) + 1)
   114 
   115 /* most significant bit in a character */
   116 #define MS_BIT                (1 << (CHAR_BIT - 1))
   117 
   118 /***************************************************************************
   119 *                                 METHODS
   120 ***************************************************************************/
   121 
   122 /***************************************************************************
   123 *   Method     : bit_array_c - constructor
   124 *   Description: This is the bit_array_c constructor.  It reserves memory
   125 *                for the vector storing the array.
   126 *   Parameters : numBits - number of bits in the array
   127 *   Effects    : Allocates vectory for array bits
   128 *   Returned   : None
   129 ***************************************************************************/
   130 template <TBitInChar F>
   131 BitArray<F>::BitArray(const int numBits):
   132     m_NumBits(numBits),
   133     m_Array(NULL),
   134     m_OwnsBuffer(true)
   135 {
   136     m_SizeInBytes = BITS_TO_CHARS(numBits);
   137 
   138 
   139     /* allocate space for bit array */
   140     m_Array = new unsigned char[m_SizeInBytes];
   141 
   142     /* set all bits to 0 */
   143     fill_n(m_Array, m_SizeInBytes, 0);
   144 }
   145 
   146 /***************************************************************************
   147 *   Method     : bit_array_c - constructor
   148 *   Description: This is the bit_array_c constructor.  It copies the
   149 *                for contents of a vector of unsigned char into the
   150 *                bitarray.
   151 *   Parameters : vect - vector to be copied
   152 *                numBits - number of bits in the array
   153 *   Effects    : Allocates vectory for array bits
   154 *   Returned   : None
   155 ***************************************************************************/
   156 template <TBitInChar F>
   157 BitArray<F>::BitArray(unsigned char *array, const int numBits,bool aOwnsBuffer):
   158     m_NumBits(numBits),
   159     m_Array(array),
   160     m_OwnsBuffer(aOwnsBuffer)
   161 {
   162 
   163 }
   164 
   165 /***************************************************************************
   166 *   Method     : ~bit_array_c - destructor
   167 *   Description: This is the bit_array_c destructor.  At this point it's
   168 *                just a place holder.
   169 *   Parameters : None
   170 *   Effects    : None
   171 *   Returned   : None
   172 ***************************************************************************/
   173 template <TBitInChar F>
   174 BitArray<F>::~BitArray(void)
   175 {
   176     if (m_OwnsBuffer)
   177     {
   178         delete[] m_Array;
   179         m_Array = NULL;
   180     }
   181 }
   182 
   183 /***************************************************************************
   184 *   Method     : Dump
   185 *   Description: This method dumps the conents of a bit array to stdout.
   186 *                The format of the dump is a series of bytes represented in
   187 *                hexadecimal.
   188 *   Parameters : outStream - stream to write to
   189 *   Effects    : Array contents are dumped to stdout
   190 *   Returned   : None
   191 ***************************************************************************/
   192 template <TBitInChar F>
   193 void BitArray<F>::Dump(std::ostream &outStream)
   194 {
   195     int size;
   196 
   197     size = BITS_TO_CHARS(m_NumBits);
   198 
   199     outStream.width(2);
   200     outStream.fill('0');
   201     outStream << uppercase << hex << (int)(m_Array[0]);  /* first byte */
   202 
   203     for (int i = 1; i < size; i++)
   204     {
   205         /* remaining bytes with a leading space */
   206         outStream << " ";
   207         outStream.width(2);
   208         outStream.fill('0');
   209         outStream << (int)(m_Array[i]);
   210     }
   211 
   212     outStream << dec;
   213 }
   214 
   215 /***************************************************************************
   216 *   Method     : SetAll
   217 *   Description: This method sets every bit in the bit array to 1.  This
   218 *                method uses UCHAR_MAX to determine what it means to set
   219 *                all bits in an unsigned char, so it is crucial that the
   220 *                machine implementation of unsigned char utilizes all of
   221 *                the bits in the memory allocated for an unsigned char.
   222 *   Parameters : None
   223 *   Effects    : Each of the bits used in the bit array are set to 1.
   224 *                Unused (spare) bits are set to 0.
   225 *   Returned   : None
   226 ***************************************************************************/
   227 template <TBitInChar F>
   228 void BitArray<F>::SetAll(void)
   229 {
   230     int bits, size;
   231     unsigned char mask;
   232 
   233     size = BITS_TO_CHARS(m_NumBits);
   234 
   235     /* set bits in all bytes to 1 */
   236     fill_n(m_Array, size, UCHAR_MAX);
   237 
   238     /* zero any spare bits so increment and decrement are consistent */
   239     bits = m_NumBits % CHAR_BIT;
   240     if (bits != 0)
   241     {
   242         mask = UCHAR_MAX << (CHAR_BIT - bits);
   243         m_Array[BIT_CHAR(m_NumBits - 1)] = mask;
   244     }
   245 }
   246 
   247 /***************************************************************************
   248 *   Method     : ClearAll
   249 *   Description: This method sets every bit in the bit array to 0.
   250 *   Parameters : None
   251 *   Effects    : Each of the bits in the bit array are set to 0.
   252 *   Returned   : None
   253 ***************************************************************************/
   254 template <TBitInChar F>
   255 void BitArray<F>::ClearAll(void)
   256 {
   257     int size;
   258 
   259     size = BITS_TO_CHARS(m_NumBits);
   260 
   261     /* set bits in all bytes to 0 */
   262     fill_n(m_Array, size, 0);
   263 }
   264 
   265 /***************************************************************************
   266 *   Method     : SetBit
   267 *   Description: This method sets a bit in the bit array to 1.
   268 *   Parameters : bit - the number of the bit to set
   269 *   Effects    : The specified bit will be set to 1.
   270 *   Returned   : None
   271 ***************************************************************************/
   272 template <TBitInChar F>
   273 void BitArray<F>::SetBit(const unsigned int bit)
   274 {
   275     if (m_NumBits <= bit)
   276     {
   277         return;         /* bit out of range */
   278     }
   279 
   280     m_Array[BIT_CHAR(bit)] |= F(bit);
   281 }
   282 
   283 /**
   284 */
   285 template <TBitInChar F>
   286 void BitArray<F>::SetBitValue(const unsigned int bit, bool aValue)
   287 	{
   288 	if (aValue)
   289 		{
   290 		SetBit(bit);
   291 		}
   292 	else
   293 		{
   294 		ClearBit(bit);
   295 		}
   296 	}
   297 
   298 /***************************************************************************
   299 *   Method     : ClearBit
   300 *   Description: This method sets a bit in the bit array to 0.
   301 *   Parameters : bit - the number of the bit to clear
   302 *   Effects    : The specified bit will be set to 0.
   303 *   Returned   : None
   304 ***************************************************************************/
   305 template <TBitInChar F>
   306 void BitArray<F>::ClearBit(const unsigned int bit)
   307 {
   308     unsigned char mask;
   309 
   310     if (m_NumBits <= bit)
   311     {
   312         return;         /* bit out of range */
   313     }
   314 
   315     /* create a mask to zero out desired bit */
   316     mask =  F(bit);
   317     mask = ~mask;
   318 
   319     m_Array[BIT_CHAR(bit)] &= mask;
   320 }
   321 
   322 /***************************************************************************
   323 *   Method     : operator()
   324 *   Description: Overload of the () operator.  This method approximates
   325 *                array indices used for assignment.  It returns a
   326 *                bit_array_index_c which includes an = method used to
   327 *                set bit values.
   328 *   Parameters : bit - index of array bit
   329 *   Effects    : None
   330 *   Returned   : bit_array_index_c (pointer to bit)
   331 ***************************************************************************/
   332 template <TBitInChar F>
   333 BitArrayIndex<F> BitArray<F>::operator()(const unsigned int bit)
   334 {
   335     BitArrayIndex<F> result(this, bit);
   336 
   337     return result;
   338 }
   339 
   340 /***************************************************************************
   341 *   Method     : operator[]
   342 *   Description: Overload of the [] operator.  This method returns the
   343 *                value of a bit in the bit array.
   344 *   Parameters : bit - index of array bit
   345 *   Effects    : None
   346 *   Returned   : The value of the specified bit.
   347 ***************************************************************************/
   348 template <TBitInChar F>
   349 bool BitArray<F>::operator[](const unsigned int bit) const
   350 {
   351     return((m_Array[BIT_CHAR(bit)] & F(bit)) != 0);
   352 }
   353 
   354 /***************************************************************************
   355 *   Method     : operator==
   356 *   Description: overload of the == operator
   357 *   Parameters : other - bit array to compare
   358 *   Effects    : None
   359 *   Returned   : True if this == other.  Otherwise false.
   360 ***************************************************************************/
   361 template <TBitInChar F>
   362 bool BitArray<F>::operator==(const BitArray &other) const
   363 {
   364     if (m_NumBits != other.m_NumBits)
   365     {
   366         /* unequal sizes */
   367         return false;
   368     }
   369 
   370     return (this->m_Array == other.m_Array);
   371 }
   372 
   373 /***************************************************************************
   374 *   Method     : operator!=
   375 *   Description: overload of the != operator
   376 *   Parameters : other - bit array to compare
   377 *   Effects    : None
   378 *   Returned   : True if this != other.  Otherwise false.
   379 ***************************************************************************/
   380 template <TBitInChar F>
   381 bool BitArray<F>::operator!=(const BitArray &other) const
   382 {
   383     if (m_NumBits != other.m_NumBits)
   384     {
   385         /* unequal sizes */
   386         return true;
   387     }
   388 
   389     return (this->m_Array != other.m_Array);
   390 }
   391 
   392 /***************************************************************************
   393 *   Method     : operator<
   394 *   Description: overload of the < operator
   395 *   Parameters : other - bit array to compare
   396 *   Effects    : None
   397 *   Returned   : True if this < other.  Otherwise false.
   398 ***************************************************************************/
   399 template <TBitInChar F>
   400 bool BitArray<F>::operator<(const BitArray &other) const
   401 {
   402     if (m_NumBits != other.m_NumBits)
   403     {
   404         /* unequal sizes */
   405         return false;
   406     }
   407 
   408     return (this->m_Array < other.m_Array);
   409 }
   410 
   411 /***************************************************************************
   412 *   Method     : operator<=
   413 *   Description: overload of the <= operator
   414 *   Parameters : other - bit array to compare
   415 *   Effects    : None
   416 *   Returned   : True if this <= other.  Otherwise false.
   417 ***************************************************************************/
   418 template <TBitInChar F>
   419 bool BitArray<F>::operator<=(const BitArray &other) const
   420 {
   421     if (m_NumBits != other.m_NumBits)
   422     {
   423         /* unequal sizes */
   424         return false;
   425     }
   426 
   427     return (this->m_Array <= other.m_Array);
   428 }
   429 
   430 /***************************************************************************
   431 *   Method     : operator>
   432 *   Description: overload of the > operator
   433 *   Parameters : other - bit array to compare
   434 *   Effects    : None
   435 *   Returned   : True if this > other.  Otherwise false.
   436 ***************************************************************************/
   437 template <TBitInChar F>
   438 bool BitArray<F>::operator>(const BitArray &other) const
   439 {
   440     if (m_NumBits != other.m_NumBits)
   441     {
   442         /* unequal sizes */
   443         return false;
   444     }
   445 
   446     return (this->m_Array > other.m_Array);
   447 }
   448 
   449 /***************************************************************************
   450 *   Method     : operator>=
   451 *   Description: overload of the >= operator
   452 *   Parameters : other - bit array to compare
   453 *   Effects    : None
   454 *   Returned   : True if this >= other.  Otherwise false.
   455 ***************************************************************************/
   456 template <TBitInChar F>
   457 bool BitArray<F>::operator>=(const BitArray &other) const
   458 {
   459     if (m_NumBits != other.m_NumBits)
   460     {
   461         /* unequal sizes */
   462         return false;
   463     }
   464 
   465     return (this->m_Array >= other.m_Array);
   466 }
   467 
   468 /***************************************************************************
   469 *   Method     : operator~
   470 *   Description: overload of the ~ operator.  Negates all non-spare bits in
   471 *                bit array
   472 *   Parameters : None
   473 *   Effects    : None
   474 *   Returned   : value of this after bitwise not
   475 ***************************************************************************/
   476 template <TBitInChar F>
   477 BitArray<F> BitArray<F>::operator~(void) const
   478 {
   479     BitArray result(this->m_NumBits);
   480     result = *this;
   481     result.Not();
   482 
   483     return result;
   484 }
   485 
   486 /***************************************************************************
   487 *   Method     : operator&
   488 *   Description: overload of the & operator.  Performs a bitwise and
   489 *                between the source array and this bit array.
   490 *   Parameters : other - bit array on righthand side of &
   491 *   Effects    : None
   492 *   Returned   : value of bitwise and of this and other.
   493 ***************************************************************************/
   494 template <TBitInChar F>
   495 BitArray<F> BitArray<F>::operator&(const BitArray<F> &other) const
   496 {
   497     BitArray<F> result(this->m_NumBits);
   498     result = *this;
   499     result &= other;
   500 
   501     return result;
   502 }
   503 
   504 
   505 /***************************************************************************
   506 *   Method     : operator^
   507 *   Description: overload of the ^ operator.  Performs a bitwise xor
   508 *                between the source array and this bit array.
   509 *   Parameters : other - bit array on righthand side of ^
   510 *   Effects    : None
   511 *   Returned   : value of bitwise xor of this and other.
   512 ***************************************************************************/
   513 template <TBitInChar F>
   514 BitArray<F> BitArray<F>::operator^(const BitArray<F> &other) const
   515 {
   516     BitArray<F> result(this->m_NumBits);
   517     result = *this;
   518     result ^= other;
   519 
   520     return result;
   521 }
   522 
   523 /***************************************************************************
   524 *   Method     : operator|
   525 *   Description: overload of the | operator.  Performs a bitwise or
   526 *                between the source array and this bit array.
   527 *   Parameters : other - bit array on righthand side of |
   528 *   Effects    : None
   529 *   Returned   : value of bitwise or of this and other.
   530 ***************************************************************************/
   531 template <TBitInChar F>
   532 BitArray<F> BitArray<F>::operator|(const BitArray<F> &other) const
   533 {
   534     BitArray<F> result(this->m_NumBits);
   535     result = *this;
   536     result |= other;
   537 
   538     return result;
   539 }
   540 
   541 /***************************************************************************
   542 *   Method     : operator<<
   543 *   Description: overload of the << operator.  Performs a bitwise left
   544 *                shift of this bit array.
   545 *   Parameters : count - the number of bits to shift left
   546 *   Effects    : None
   547 *   Returned   : result of bitwise left shift
   548 ***************************************************************************/
   549 template <TBitInChar F>
   550 BitArray<F> BitArray<F>::operator<<(const unsigned int count) const
   551 {
   552     BitArray<F> result(this->m_NumBits);
   553     result = *this;
   554     result <<= count;
   555 
   556     return result;
   557 }
   558 
   559 /***************************************************************************
   560 *   Method     : operator>>
   561 *   Description: overload of the >> operator.  Performs a bitwise right
   562 *                shift of this bit array.
   563 *   Parameters : count - the number of bits to shift right
   564 *   Effects    : None
   565 *   Returned   : result of bitwise right shift
   566 ***************************************************************************/
   567 template <TBitInChar F>
   568 BitArray<F> BitArray<F>::operator>>(const unsigned int count) const
   569 {
   570     BitArray<F> result(this->m_NumBits);
   571     result = *this;
   572     result >>= count;
   573 
   574     return result;
   575 }
   576 
   577 /***************************************************************************
   578 *   Method     : operator++ (prefix)
   579 *   Description: overload of the ++ operator.  Increments the contents of
   580 *                a bit array.  Overflows cause rollover.
   581 *   Parameters : None
   582 *   Effects    : Bit array contents are incremented
   583 *   Returned   : Reference to this array after increment
   584 ***************************************************************************/
   585 template <TBitInChar F>
   586 BitArray<F>& BitArray<F>::operator++(void)
   587 {
   588     int i;
   589     unsigned char maxValue;     /* maximum value for current char */
   590     unsigned char one;          /* least significant bit in current char */
   591 
   592     if (m_NumBits == 0)
   593     {
   594         return *this;           /* nothing to increment */
   595     }
   596 
   597     /* handle arrays that don't use every bit in the last character */
   598     i = (m_NumBits % CHAR_BIT);
   599     if (i != 0)
   600     {
   601         maxValue = UCHAR_MAX << (CHAR_BIT - i);
   602         one = 1 << (CHAR_BIT - i);
   603     }
   604     else
   605     {
   606         maxValue = UCHAR_MAX;
   607         one = 1;
   608     }
   609 
   610     for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
   611     {
   612         if (m_Array[i] != maxValue)
   613         {
   614             m_Array[i] = m_Array[i] + one;
   615             return *this;
   616         }
   617         else
   618         {
   619             /* need to carry to next byte */
   620             m_Array[i] = 0;
   621 
   622             /* remaining characters must use all bits */
   623             maxValue = UCHAR_MAX;
   624             one = 1;
   625         }
   626     }
   627 
   628     return *this;
   629 }
   630 
   631 /***************************************************************************
   632 *   Method     : operator++ (postfix)
   633 *   Description: overload of the ++ operator.  Increments the contents of
   634 *                a bit array.  Overflows cause rollover.
   635 *   Parameters : dumy - needed for postfix increment
   636 *   Effects    : Bit array contents are incremented
   637 *   Returned   : Reference to this array after increment
   638 ***************************************************************************/
   639 template <TBitInChar F>
   640 BitArray<F>& BitArray<F>::operator++(int dummy)
   641 {
   642     ++(*this);
   643     return *this;
   644 }
   645 
   646 /***************************************************************************
   647 *   Method     : operator-- (prefix)
   648 *   Description: overload of the -- operator.  Decrements the contents of
   649 *                a bit array.  Underflows cause rollover.
   650 *   Parameters : None
   651 *   Effects    : Bit array contents are decremented
   652 *   Returned   : None
   653 ***************************************************************************/
   654 template <TBitInChar F>
   655 BitArray<F>& BitArray<F>::operator--(void)
   656 {
   657     int i;
   658     unsigned char maxValue;     /* maximum value for current char */
   659     unsigned char one;          /* least significant bit in current char */
   660 
   661     if (m_NumBits == 0)
   662     {
   663         return *this;           /* nothing to decrement */
   664     }
   665 
   666     /* handle arrays that don't use every bit in the last character */
   667     i = (m_NumBits % CHAR_BIT);
   668     if (i != 0)
   669     {
   670         maxValue = UCHAR_MAX << (CHAR_BIT - i);
   671         one = 1 << (CHAR_BIT - i);
   672     }
   673     else
   674     {
   675         maxValue = UCHAR_MAX;
   676         one = 1;
   677     }
   678 
   679     for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
   680     {
   681         if (m_Array[i] >= one)
   682         {
   683             m_Array[i] = m_Array[i] - one;
   684             return *this;
   685         }
   686         else
   687         {
   688             /* need to borrow from the next byte */
   689             m_Array[i] = maxValue;
   690 
   691             /* remaining characters must use all bits */
   692             maxValue = UCHAR_MAX;
   693             one = 1;
   694         }
   695     }
   696 
   697     return *this;
   698 }
   699 
   700 /***************************************************************************
   701 *   Method     : operator-- (postfix)
   702 *   Description: overload of the -- operator.  Decrements the contents of
   703 *                a bit array.  Underflows cause rollover.
   704 *   Parameters : dumy - needed for postfix decrement
   705 *   Effects    : Bit array contents are decremented
   706 *   Returned   : None
   707 ***************************************************************************/
   708 template <TBitInChar F>
   709 BitArray<F>& BitArray<F>::operator--(int dummy)
   710 {
   711     --(*this);
   712     return *this;
   713 }
   714 
   715 /***************************************************************************
   716 *   Method     : operator=
   717 *   Description: overload of the = operator.  Copies source contents into
   718 *                this bit array.
   719 *   Parameters : src - Source bit array
   720 *   Effects    : Source bit array contents are copied into this array
   721 *   Returned   : Reference to this array after copy
   722 ***************************************************************************/
   723 template <TBitInChar F>
   724 BitArray<F>& BitArray<F>::operator=(const BitArray<F> &src)
   725 {
   726     if (*this == src)
   727     {
   728         /* don't do anything for a self assignment */
   729         return *this;
   730     }
   731 
   732     if (m_NumBits != src.m_NumBits)
   733     {
   734         /* don't do assignment with different array sizes */
   735         return *this;
   736     }
   737 
   738     if ((m_NumBits == 0) || (src.m_NumBits == 0))
   739     {
   740         /* don't do assignment with unallocated array */
   741         return *this;
   742     }
   743 
   744     /* copy bits from source */
   745     int size;
   746     size = BITS_TO_CHARS(m_NumBits);
   747 
   748     copy(src.m_Array, &src.m_Array[size], this->m_Array);
   749     return *this;
   750 }
   751 
   752 /***************************************************************************
   753 *   Method     : operator&=
   754 *   Description: overload of the &= operator.  Performs a bitwise and
   755 *                between the source array and this bit array.  This bit
   756 *                array will contain the result.
   757 *   Parameters : src - Source bit array
   758 *   Effects    : Results of bitwise and are stored in this array
   759 *   Returned   : Reference to this array after and
   760 ***************************************************************************/
   761 template <TBitInChar F>
   762 BitArray<F>& BitArray<F>::operator&=(const BitArray<F> &src)
   763 {
   764     int size;
   765 
   766     size = BITS_TO_CHARS(m_NumBits);
   767 
   768     if (m_NumBits != src.m_NumBits)
   769     {
   770         /* don't do assignment with different array sizes */
   771         return *this;
   772     }
   773 
   774     /* AND array one unsigned char at a time */
   775     for(int i = 0; i < size; i++)
   776     {
   777         m_Array[i] = m_Array[i] & src.m_Array[i];
   778     }
   779 
   780     return *this;
   781 }
   782 
   783 /***************************************************************************
   784 *   Method     : operator^=
   785 *   Description: overload of the ^= operator.  Performs a bitwise xor
   786 *                between the source array and this bit array.  This bit
   787 *                array will contain the result.
   788 *   Parameters : src - Source bit array
   789 *   Effects    : Results of bitwise xor are stored in this array
   790 *   Returned   : Reference to this array after xor
   791 ***************************************************************************/
   792 template <TBitInChar F>
   793 BitArray<F>& BitArray<F>::operator^=(const BitArray<F> &src)
   794 {
   795     int size;
   796 
   797     size = BITS_TO_CHARS(m_NumBits);
   798 
   799     if (m_NumBits != src.m_NumBits)
   800     {
   801         /* don't do assignment with different array sizes */
   802         return *this;
   803     }
   804 
   805     /* XOR array one unsigned char at a time */
   806     for(int i = 0; i < size; i++)
   807     {
   808         m_Array[i] = m_Array[i] ^ src.m_Array[i];
   809     }
   810 
   811     return *this;
   812 }
   813 
   814 /***************************************************************************
   815 *   Method     : operator|=
   816 *   Description: overload of the |= operator.  Performs a bitwise or
   817 *                between the source array and this bit array.  This bit
   818 *                array will contain the result.
   819 *   Parameters : src - Source bit array
   820 *   Effects    : Results of bitwise or are stored in this array
   821 *   Returned   : Reference to this array after or
   822 ***************************************************************************/
   823 template <TBitInChar F>
   824 BitArray<F>& BitArray<F>::operator|=(const BitArray<F> &src)
   825 {
   826     int size;
   827 
   828     size = BITS_TO_CHARS(m_NumBits);
   829 
   830     if (m_NumBits != src.m_NumBits)
   831     {
   832         /* don't do assignment with different array sizes */
   833         return *this;
   834     }
   835 
   836     /* OR array one unsigned char at a time */
   837     for(int i = 0; i < size; i++)
   838     {
   839         m_Array[i] = m_Array[i] | src.m_Array[i];
   840     }
   841 
   842     return *this;
   843 }
   844 
   845 /***************************************************************************
   846 *   Method     : Not
   847 *   Description: Negates all non-spare bits in bit array.
   848 *   Parameters : None
   849 *   Effects    : Contents of bit array are negated.  Any spare bits are
   850 *                left at 0.
   851 *   Returned   : Reference to this array after not
   852 ***************************************************************************/
   853 template <TBitInChar F>
   854 BitArray<F>& BitArray<F>::Not(void)
   855 {
   856     int bits;
   857     unsigned char mask;
   858     int size;
   859 
   860     size = BITS_TO_CHARS(m_NumBits);
   861 
   862     if (m_NumBits == 0)
   863     {
   864         /* don't do not with unallocated array */
   865         return *this;
   866     }
   867 
   868     /* NOT array one unsigned char at a time */
   869     for(int i = 0; i < size; i++)
   870     {
   871         m_Array[i] = ~m_Array[i];
   872     }
   873 
   874     /* zero any spare bits so increment and decrement are consistent */
   875     bits = m_NumBits % CHAR_BIT;
   876     if (bits != 0)
   877     {
   878         mask = UCHAR_MAX << (CHAR_BIT - bits);
   879         m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
   880     }
   881 
   882     return *this;
   883 }
   884 
   885 /***************************************************************************
   886 *   Method     : operator<<=
   887 *   Description: overload of the <<= operator.  Performs a left shift on
   888 *                this bit array.  This bit array will contain the result.
   889 *   Parameters : shifts - number of bit positions to shift
   890 *   Effects    : Results of the shifts are stored in this array
   891 *   Returned   : Reference to this array after shift
   892 ***************************************************************************/
   893 template <TBitInChar F>
   894 BitArray<F>& BitArray<F>::operator<<=(const unsigned int shifts)
   895 {
   896     int i;
   897     int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
   898 
   899     if (shifts >= m_NumBits)
   900     {
   901         /* all bits have been shifted off */
   902         this->ClearAll();
   903         return *this;
   904     }
   905 
   906     /* first handle big jumps of bytes */
   907     if (chars > 0)
   908     {
   909         int size;
   910 
   911         size = BITS_TO_CHARS(m_NumBits);
   912 
   913         for (i = 0; (i + chars) < size; i++)
   914         {
   915             m_Array[i] = m_Array[i + chars];
   916         }
   917 
   918         /* now zero out new bytes on the right */
   919         for (i = size; chars > 0; chars--)
   920         {
   921             m_Array[i - chars] = 0;
   922         }
   923     }
   924 
   925     /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
   926     for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
   927     {
   928         for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++)
   929         {
   930             m_Array[j] <<= 1;
   931 
   932             /* handle shifts across byte bounds */
   933             if (m_Array[j + 1] & MS_BIT)
   934             {
   935                 m_Array[j] |= 0x01;
   936             }
   937         }
   938 
   939         m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1;
   940     }
   941 
   942     return *this;
   943 }
   944 
   945 /***************************************************************************
   946 *   Method     : operator>>=
   947 *   Description: overload of the >>= operator.  Performs a right shift on
   948 *                this bit array.  This bit array will contain the result.
   949 *   Parameters : shifts - number of bit positions to shift
   950 *   Effects    : Results of the shifts are stored in this array
   951 *   Returned   : Reference to this array after shift
   952 ***************************************************************************/
   953 template <TBitInChar F>
   954 BitArray<F>& BitArray<F>::operator>>=(const unsigned int shifts)
   955 {
   956     int i;
   957     char mask;
   958     int chars = shifts / CHAR_BIT;  /* number of whole byte shifts */
   959 
   960     if (shifts >= m_NumBits)
   961     {
   962         /* all bits have been shifted off */
   963         this->ClearAll();
   964         return *this;
   965     }
   966 
   967     /* first handle big jumps of bytes */
   968     if (chars > 0)
   969     {
   970         for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--)
   971         {
   972             m_Array[i] = m_Array[i - chars];
   973         }
   974 
   975         /* now zero out new bytes on the right */
   976         for (; chars > 0; chars--)
   977         {
   978             m_Array[chars - 1] = 0;
   979         }
   980     }
   981 
   982     /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
   983     for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
   984     {
   985         for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--)
   986         {
   987             m_Array[j] >>= 1;
   988 
   989             /* handle shifts across byte bounds */
   990             if (m_Array[j - 1] & 0x01)
   991             {
   992                 m_Array[j] |= MS_BIT;
   993             }
   994         }
   995 
   996         m_Array[0] >>= 1;
   997     }
   998 
   999     /***********************************************************************
  1000     * zero any spare bits that are shifted beyond the end of the bit array
  1001     * so that increment and decrement are consistent.
  1002     ***********************************************************************/
  1003     i = m_NumBits % CHAR_BIT;
  1004     if (i != 0)
  1005     {
  1006         mask = UCHAR_MAX << (CHAR_BIT - i);
  1007         m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
  1008     }
  1009 
  1010     return *this;
  1011 }
  1012 
  1013 /***************************************************************************
  1014 *   Method     : bit_array_index_c - constructor
  1015 *   Description: This is the bit_array_index_c constructor.  It stores a
  1016 *                pointer to the bit array and the bit index.
  1017 *   Parameters : array - pointer to bit array
  1018 *                index - index of bit in array
  1019 *   Effects    : Pointer to bit array and bit index are stored.
  1020 *   Returned   : None
  1021 ***************************************************************************/
  1022 template <TBitInChar F>
  1023 BitArrayIndex<F>::BitArrayIndex(BitArray<F> *array,
  1024     const unsigned int index)
  1025 {
  1026     m_BitArray = array;
  1027     m_Index = index;
  1028 }
  1029 
  1030 /***************************************************************************
  1031 *   Method     : operator=
  1032 *   Description: overload of the = operator.  Sets the bit array bit to
  1033 *                the value of src.
  1034 *   Parameters : src - bit value
  1035 *   Effects    : Bit pointed to by this object is set to the value of
  1036 *                source.
  1037 *   Returned   : None
  1038 ***************************************************************************/
  1039 template <TBitInChar F>
  1040 void BitArrayIndex<F>::operator=(const bool src)
  1041 {
  1042     if (m_BitArray == NULL)
  1043     {
  1044         return;     /* no array */
  1045     }
  1046 
  1047     if (m_BitArray->SizeInBits() <= m_Index)
  1048     {
  1049         return;     /* index is out of bounds */
  1050     }
  1051 
  1052     if (src)
  1053     {
  1054         m_BitArray->SetBit(m_Index);
  1055     }
  1056     else
  1057     {
  1058         m_BitArray->ClearBit(m_Index);
  1059     }
  1060 }
  1061 
  1062 
  1063 template class BitArray<HighBitHighIndex>;
  1064 template class BitArray<HighBitLowIndex>;
  1065 template class BitArrayIndex<HighBitHighIndex>;
  1066 template class BitArrayIndex<HighBitLowIndex>;