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