Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

bitstring.h

Go to the documentation of this file.
00001 /* -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
00002 /*********************************************************************
00003  *
00004  * Filename : bitstring.h (base)
00005  * C/C++ header.
00006  *
00007  * Basic operations on bits and strings of bits + BitString & Bit classes.
00008  *
00009  * This file is a part of the UPPAAL toolkit.
00010  * Copyright (c) 1995 - 2003, Uppsala University and Aalborg University.
00011  * All right reserved.
00012  *
00013  * v 1.1 reviewed.
00014  * $Id: bitstring.h,v 1.17 2005/05/14 16:57:34 behrmann Exp $
00015  *
00016  *********************************************************************/
00017 
00018 #ifndef INCLUDE_BASE_BIT_H
00019 #define INCLUDE_BASE_BIT_H
00020 
00021 #include <assert.h>
00022 #include <stddef.h>
00023 
00024 #include "base/intutils.h"
00025 
00026 #ifdef __cplusplus
00027 extern "C" {
00028 #endif
00029 
00030 
00031 /** Type to ensure correct arguments.
00032  */
00033 typedef enum { ZERO = 0, ONE = 1 } bit_t;
00034 
00035 
00036 /** High 16 bits of an int.
00037  * Useful in conjunction with hash values to store data.
00038  * @param x: the int to extract the high 16 bits.
00039  */
00040 static inline
00041 uint32_t base_high16(uint32_t x)
00042 {
00043     return x & 0xffff0000;
00044 }
00045     
00046 /** Low 16 bits of an int.
00047  * Useful in conjunction with hash values to store data.
00048  * @param x: the int extract the low 16 bits.
00049  */
00050 static inline
00051 uint32_t base_low16(uint32_t x)
00052 {
00053     return x & 0x0000ffff;
00054 }
00055 
00056 /** Bit counting function.
00057  * @return: the number of 1s in a given int
00058  * @param x: the int to examine.
00059  */
00060 static inline
00061 uint32_t base_countBits(uint32_t x)
00062 {
00063     /* algorithm: count bits in parallel (hack) */
00064     x -= (x & 0xaaaaaaaa) >> 1;
00065     x = ((x >> 2) & 0x33333333L) + (x & 0x33333333L);
00066     x = ((x >> 4) + x) & 0x0f0f0f0fL;
00067     x = ((x >> 8) + x);
00068     x = ((x >> 16) + x) & 0xff;
00069     return x;
00070 }
00071 
00072 /** Bit counting function.
00073  * @return: the number of 1s in a given string of bits
00074  * @param bitString: the string of bits to examine
00075  * @param n: number of ints to read.
00076  */
00077 static inline
00078 uint32_t base_countBitsN(const uint32_t *bitString, size_t n)
00079 {
00080     uint32_t cnt;
00081     assert(n == 0 || bitString);
00082     for(cnt = 0; n != 0; --n) cnt += base_countBits(*bitString++);
00083     return cnt;
00084 }
00085 
00086 
00087 /** Find most significant set bit (32-bit version).
00088  * Function that scans a 32-bit word for the most significant set bit.
00089  * For x86 this is implemented in assembler while for all other architectures
00090  * it is implemented by setting all bits below the max significant set bit to
00091  * 1 and counting the number of set bits.
00092  * 
00093  * @param w: the 32-bit word.
00094  * @return The index (0--31) of the most significant set bit.
00095  * 
00096  * @pre w != 0
00097  */
00098 static inline
00099 uint32_t base_fmsb32(uint32_t w)
00100 {
00101     assert(w != 0);
00102 #if defined(__GNUG__) && defined(i386)
00103     uint32_t r;
00104     asm("bsrl %1, %0" : "=r" (r) : "rm" (w) : "cc");
00105     return r;
00106 #else
00107     w |= (w >> 1);                
00108     w |= (w >> 2);                
00109     w |= (w >> 4);                
00110     w |= (w >> 8);                
00111     w |= (w >> 16);                
00112     return base_countBits(w) - 1;    
00113 #endif
00114 }
00115 
00116 /** Bitwise or ;
00117  * @param bits1: arg1 = destination
00118  * @param bits2: arg2 = source
00119  * @param n: number of ints to read
00120  * @return arg1 = arg1 | arg2
00121  */
00122 static inline
00123 void base_orBits(uint32_t *bits1, const uint32_t *bits2, size_t n)
00124 {
00125     assert(n == 0 || (bits1 && bits2));
00126     for(; n != 0; --n) *bits1++ |= *bits2++;
00127 }
00128 
00129 /** Bitwise and ;
00130  * @param bits1: arg1 = destination
00131  * @param bits2: arg2 = source
00132  * @param n: number of ints to read
00133  * @return arg1 = arg1 & arg2
00134  */
00135 static inline
00136 void base_andBits(uint32_t *bits1, const uint32_t *bits2, size_t n)
00137 {
00138     assert(n == 0 || (bits1 && bits2));
00139     for(; n != 0; --n) *bits1++ &= *bits2++;
00140 }
00141 
00142 /** Bitwise xor ;
00143  * @param bits1: arg1 = destination
00144  * @param bits2: arg2 = source
00145  * @param n: number of ints to read
00146  * @return arg1 = arg1 ^ arg2
00147  */
00148 static inline
00149 void base_xorBits(uint32_t *bits1, const uint32_t *bits2, size_t n)
00150 {
00151     assert(n == 0 || (bits1 && bits2));
00152     for(; n != 0; --n) *bits1++ ^= *bits2++;
00153 }
00154 
00155 /** Reset of bits (to 0).
00156  * memset could be used but for strings of
00157  * bits of length 3-4 ints max, it is overkill.
00158  * Conversely, for larger arrays, don't use this
00159  * function.
00160  * @param bits: the string to reset
00161  * @param n: number of ints to write.
00162  */
00163 static inline
00164 void base_resetBits(uint32_t *bits, size_t n)
00165 {
00166     assert(n == 0 || bits);
00167     for(; n != 0; --n) *bits++ = 0;
00168 }
00169 
00170 /** Set bits to 1.
00171  * memset could be used but for strings of
00172  * bits of length 3-4 ints max, it is overkill.
00173  * Conversely, for larger arrays, don't use this
00174  * function.
00175  * @param bits: the string to reset
00176  * @param n: number of ints to write.
00177  */
00178 static inline
00179 void base_setBits(uint32_t *bits, size_t n)
00180 {
00181     assert(n == 0 || bits);
00182     for(; n != 0; --n) *bits++ = ~0u;
00183 }
00184 
00185 /** Set bits to something.
00186  * memset could be used but for strings of
00187  * bits of length 3-4 ints max, it is overkill.
00188  * Conversely, for larger arrays, don't use this
00189  * function.
00190  * @param bits: the string to reset
00191  * @param n: number of ints to write.
00192  * @param value: value to set.
00193  */
00194 static inline
00195 void base_setBitsWith(uint32_t *bits, size_t n, uint32_t value)
00196 {
00197     assert(n == 0 || bits);
00198     for(; n != 0; --n) *bits++ = value;
00199 }
00200 
00201 /** Apply a xor mask to a bitstring.
00202  * @param bits: the string to xor
00203  * @param n: number of ints to change
00204  * @param mask: the mask for the xor
00205  */
00206 static inline
00207 void base_xorBitsWith(uint32_t *bits, size_t n, uint32_t mask)
00208 {
00209     assert(n == 0 || bits);
00210     for(; n != 0; --n) *bits++ ^= mask;
00211 }
00212 
00213 /** Negate a bitstring.
00214  * @param bits: bit string to negate
00215  * @param n: number of ints to change
00216  */
00217 static inline
00218 void base_negBits(uint32_t *bits, size_t n)
00219 {
00220     assert(n == 0 || bits);
00221     for(; n != 0; bits++, --n) *bits = ~*bits;
00222 }
00223 
00224 /** Reset of 2 strings of bits (to 0).
00225  * memset could be used but for strings of
00226  * bits of length 3-4 ints max, it is overkill.
00227  * Conversely, for larger arrays, don't use this
00228  * function.
00229  * @param bits1,bits2: the strings to reset
00230  * @param n: number of ints to write.
00231  */
00232 static inline
00233 void base_resetBits2(uint32_t *bits1, uint32_t *bits2, size_t n)
00234 {
00235     assert(n == 0 || (bits1 && bits2));
00236     for(; n != 0; --n)
00237     {
00238         *bits1++ = 0;
00239         *bits2++ = 0;
00240     }
00241 }
00242 
00243 /** Set 2 strings of bits (to 1).
00244  * memset could be used but for strings of
00245  * bits of length 3-4 ints max, it is overkill.
00246  * Conversely, for larger arrays, don't use this
00247  * function.
00248  * @param bits1,bits2: the strings to reset
00249  * @param n: number of ints to write.
00250  */
00251 static inline
00252 void base_setBits2(uint32_t *bits1, uint32_t *bits2, size_t n)
00253 {
00254     assert(n == 0 || (bits1 && bits2));
00255     for(; n != 0; --n)
00256     {
00257         *bits1++ = ~0u;
00258         *bits2++ = ~0u;
00259     }
00260 }
00261 
00262 /** Equality test to 0. Optimistic
00263  * implementation: works best when == 0.
00264  * @param bits: the string to test
00265  * @param n: n number of ints to test
00266  * @return true if all bits[0..n-1] == 0
00267  */
00268 static inline
00269 BOOL base_areBitsReset(const uint32_t *bits, size_t n)
00270 {
00271     uint32_t diff = 0; /* accumulate the difference to 0 */
00272     assert(n == 0 || bits);
00273     for(; n != 0; --n) diff |= *bits++;
00274     return (BOOL)(diff == 0);
00275 }
00276 
00277 /** Wrapper to base_areBitsResets
00278  */
00279 static inline
00280 BOOL base_areIBitsReset(const int32_t *bits, size_t n)
00281 {
00282     return base_areBitsReset((uint32_t*) bits, n);
00283 }
00284 
00285 
00286 /** Comparison of bits.
00287  * Same comment as for resetBits: better
00288  * to inline this simple code for small
00289  * arrays, ie, bit arrays. Optimistic implementation.
00290  * @param bits1,bits2: arrays to compare
00291  * @param n: number of ints to read
00292  * @return TRUE if array contents are the same
00293  */
00294 static inline
00295 BOOL base_areBitsEqual(const uint32_t *bits1,
00296                        const uint32_t *bits2, size_t n)
00297 {
00298     uint32_t diff = 0;
00299     assert(n == 0 || (bits1 && bits2));
00300     for(; n != 0; --n) diff |= *bits1++ ^ *bits2++;
00301     return (BOOL)(diff == 0);
00302 }
00303 
00304     
00305 /** Copy of bits.
00306  * memcpy could be used but for strings of
00307  * bits of length 3-4 ints max, it is overkill.
00308  * Conversely, for larger arrays, don't use this
00309  * function.
00310  * @param bits: the string to reset
00311  * @param n: number of ints to read.
00312  * @pre n > 0 && valid pointer
00313  */ 
00314 static inline
00315 void base_copyBits(uint32_t *bits1, const uint32_t *bits2, size_t n)
00316 {
00317     assert(n == 0 || (bits1 && bits2));
00318     for(; n != 0; --n) *bits1++ = *bits2++;
00319 }
00320 
00321 /** Set bit to 1 at position i in a table of bits.
00322  * @param bits: the table of *int*
00323  * @param i: the position of the bit
00324  * Bit position in a table of int =
00325  * int position at i/32 == i >> 5
00326  * bit position at i%32 == i & 31
00327  * NOTE: we don't use setBit and resetBit
00328  * as names because they are too close to
00329  * resetBits that is already used.
00330  * @pre valid pointer and no out of bounds.
00331  */
00332 static inline
00333 void base_setOneBit(uint32_t *bits, size_t i)
00334 {
00335     assert(bits);
00336     bits[i >> 5] |= 1 << (i & 31);
00337 }
00338 
00339 
00340 /** Add a bit at position i in a table of bits.
00341  * @param bits: the table of *int*
00342  * @param i: the position of the bit
00343  * @param bit: the bit to add (0 or 1)
00344  * @pre valid pointer and no out of bounds.
00345  */
00346 static inline
00347 void base_addOneBit(uint32_t *bits, size_t i, bit_t bit)
00348 {
00349     assert(bits && (bit == ONE || bit == ZERO));
00350     bits[i >> 5] |= bit << (i & 31);
00351 }
00352 
00353 
00354 /** Assign a bit at position i in a table of bits.
00355  * @param bits: the table of *int*
00356  * @param i: the position of the bit
00357  * @param bit: the bit to assign.
00358  * @pre valid pointer and no out of bounds.
00359  */
00360 static inline
00361 void base_assignOneBit(uint32_t *bits, size_t i, bit_t bit)
00362 {
00363     assert(bits && (bit == ONE || bit == ZERO));
00364 
00365     bits[i >> 5] = (bits[i >> 5] & ~(1 << (i & 31))) | (bit << (i & 31));
00366 }
00367 
00368 
00369 /** "and" operation with a bit at position i in a table of bits.
00370  * @param bits: the table of *int*
00371  * @param i: the position of the bit
00372  * Bit position in a table of int =
00373  * int position at i/32 == i >> 5
00374  * bit position at i%32 == i & 31
00375  * @pre valid pointer and no out of bounds.
00376  */
00377 static inline
00378 void base_andWithOneBit(uint32_t *bits, size_t i, bit_t bit)
00379 {
00380     assert(bits);
00381     /* check it is really a bit and nobody tried to cheat
00382      * with a bad cast.
00383      */
00384     assert(bit == ONE || bit == ZERO);
00385     bits[i >> 5] &= bit << (i & 31);
00386 }
00387 
00388 
00389 /** Reset bit to 0 at position i in a table of bits.
00390  * @param bits: the table of *int*
00391  * @param i: the position of the bit
00392  * Bit position in a table of int =
00393  * int position at i/32 == i >> 5
00394  * bit position at i%32 == i & 31
00395  * NOTE: don't use setBit and resetBit
00396  * as names because they are too close to
00397  * resetBits that is already used.
00398  * @pre valid pointer and not out of bounds.
00399  */
00400 static inline 
00401 void base_resetOneBit(uint32_t *bits, size_t i)
00402 {
00403     assert(bits);
00404     bits[i >> 5] &= ~(1 << (i & 31));
00405 }
00406 
00407 
00408 /** Substract a bit at position i in a table of bits.
00409  * @param bits: the table of *int*
00410  * @param i: the position of the bit
00411  * Bit position in a table of int =
00412  * int position at i/32 == i >> 5
00413  * bit position at i%32 == i & 31
00414  * NOTE: don't use setBit and resetBit
00415  * as names because they are too close to
00416  * resetBits that is already used.
00417  * @pre valid pointer and not out of bounds.
00418  */
00419 static inline 
00420 void base_subOneBit(uint32_t *bits, size_t i, bit_t bit)
00421 {
00422     assert(bits);
00423     /* check it is really a bit and nobody tried to cheat
00424      * with a bad cast.
00425      */
00426     assert(bit == ONE || bit == ZERO);
00427     bits[i >> 5] &= ~(bit << (i & 31));
00428 }
00429 
00430 
00431 /** Toggle bit at position i in a table of bits.
00432  * @param bits: the table of *int*
00433  * @param i: the position of the bit
00434  * Bit position in a table of int =
00435  * int position at i/32 == i >> 5
00436  * bit position at i%32 == i & 31
00437  * @pre valid pointer and not out of bounds.
00438  */
00439 static inline
00440 void base_toggleOneBit(uint32_t *bits, size_t i)
00441 {
00442     assert(bits);
00443     bits[i >> 5] ^= 1 << (i & 31);
00444 }
00445 
00446 
00447 /** Xor a bit at position i in a table of bits.
00448  * @param bits: the table of *int*
00449  * @param i: the position of the bit
00450  * Bit position in a table of int =
00451  * int position at i/32 == i >> 5
00452  * bit position at i%32 == i & 31
00453  * @pre valid pointer and not out of bounds.
00454  */
00455 static inline
00456 void base_xorOneBit(uint32_t *bits, size_t i, bit_t bit)
00457 {
00458     assert(bits);
00459     /* check it is really a bit and nobody tried to cheat
00460      * with a bad cast.
00461      */
00462     assert(bit == ONE || bit == ZERO);
00463     bits[i >> 5] ^= bit << (i & 31);
00464 }
00465 
00466 
00467 /** Test for a set bit in a bit-string.
00468  * Can be used in the following way. Instead of: 
00469  * \code 
00470  * if (base_getOneBit(a,n)) c++; 
00471  * \endcode
00472  * you can write:
00473  * \code 
00474  * c += base_getOneBit(a,n);
00475  * \endcode
00476  * @returns ONE if \a i'th bit is set, ZERO otherwise.
00477  * @pre valid pointer and not out of bounds.
00478  */
00479 static inline
00480 bit_t base_getOneBit(const uint32_t *bits, size_t i)
00481 {
00482     assert(bits);
00483     return (bit_t)((bits[i >> 5] >> (i & 31)) & 1);
00484 }
00485 
00486 /** Test for a set bit in a bit-string. This function is not the same
00487  * as \c base_getOneBit(). This function returns an integer with all
00488  * other bits except the \a i'th bit masked out. I.e. it returns 0 if
00489  * the bit is not set, and a power of 2 if it is set.
00490  * 
00491  * @returns the bit as it is in the int, ie, shifted.
00492  * @pre valid pointer and not out of bounds.
00493  */
00494 static inline
00495 uint32_t base_readOneBit(const uint32_t *bits, size_t i)
00496 {
00497     assert(bits);
00498     return bits[i >> 5] & (1 << (i & 31));
00499 }
00500 
00501 
00502 /** Unpack a bit table to an index table.
00503  * Useful when loading a DBM and computing initial
00504  * redirection table. May be used for other things
00505  * than DBMs, e.g., variables.
00506  * @param table: index redirection table
00507  * @param bits: bit array
00508  * @param n: size in int of the bit array
00509  * @return number of bits in bits
00510  * @pre
00511  * - table is large enough: at least
00512  *   uint32_t[size] where size = index of the highest bit
00513  *   in the bitstring bits.
00514  * - bits is at least a uint32_t[n]
00515  * @post
00516  * - returned value == number of bits in bits
00517  * - for all bits set in bits at position i,
00518  *   then table[i] is defined and gives the
00519  *   proper indirection ; for other bits, table[i]
00520  *   is untouched.
00521  */
00522 size_t base_bits2indexTable(const uint32_t *bits, size_t n, cindex_t *table);
00523 
00524 
00525 #ifdef __cplusplus
00526 }
00527 
00528 #include "debug/utils.h"
00529 
00530 namespace base
00531 {
00532     /** Bit reference wrapper -- it is better to use directly
00533      * the previous functions when it is possible but this
00534      * may be useful. Called Bit for ease of use, e.g.,
00535      * Bit(a, 2) |= Bit::One;
00536      */
00537     class Bit
00538     {
00539     public:
00540         
00541         /******* Constants to make use of Bit coherent ******/
00542 
00543         static const bit_t One = ONE;
00544         static const bit_t Zero = ZERO;
00545 
00546         /** Constructor.
00547          * @param p: address of a bit string
00548          * @param i: index of the bit in that bit string
00549          */
00550         Bit(uint32_t *p, uint32_t i)
00551             : iptr(p + (i >> 5)), offset(i & 31)
00552         {}
00553         
00554         /************* Standard operators **********/
00555         
00556         Bit& operator |= (bit_t bit)
00557         {
00558             *iptr |= bit << offset;
00559             return *this;
00560         }
00561         Bit& operator |= (const Bit& bit)
00562         {
00563             return *this |= bit();
00564         }
00565         Bit& operator &= (bit_t bit)
00566         {
00567             *iptr &= bit << offset;
00568             return *this;
00569         }
00570         Bit& operator &= (const Bit& bit)
00571         {
00572             return *this &= bit();
00573         }
00574         Bit& operator ^= (bit_t bit)
00575         {
00576             *iptr ^= bit << offset;
00577             return *this;
00578         }
00579         Bit& operator ^= (const Bit& bit)
00580         {
00581             return *this ^= bit();
00582         }
00583         Bit& operator = (bit_t bit)
00584         {
00585             *iptr = (*iptr & ~(1 << offset)) | (bit << offset);
00586             return *this;
00587         }
00588         Bit& operator = (const Bit& bit)
00589         {
00590             return *this = bit();
00591         }
00592         Bit& operator += (bit_t bit)
00593         {
00594             return *this |= bit;
00595         }
00596         Bit& operator += (const Bit& bit)
00597         {
00598             return *this += bit();
00599         }
00600         Bit& operator -= (bit_t bit)
00601         {
00602             *iptr &= ~(bit << offset);
00603             return *this;
00604         }
00605         Bit& operator -= (const Bit& bit)
00606         {
00607             return *this -= bit();
00608         }
00609         bit_t operator () () const
00610         {
00611             return (bit_t) ((*iptr >> offset) & 1);
00612         }
00613         Bit& reset()
00614         {
00615             *iptr &= ~(1 << offset);
00616             return *this;
00617         }
00618         Bit& set()
00619         {
00620             *iptr |= (1 << offset);
00621             return *this;
00622         }
00623         Bit& neg()
00624         {
00625             *iptr ^= (1 << offset);
00626             return *this;
00627         }
00628 
00629     private:
00630         uint32_t *iptr, offset; //< bit address and offset
00631     };
00632 
00633     /** Encapsulation of a bitstring
00634      */
00635     class BitString
00636     {
00637     public:
00638 
00639         /** Constructor:
00640          * @param len: size in BITS of the bitstring.
00641          */
00642         BitString(uint32_t len)
00643             : n(bits2intsize(len)),
00644               bitString(new uint32_t[n])
00645         {
00646             base_resetSmall(bitString, n);
00647         }
00648 
00649         /** Copy constructor.
00650          * @param arg: original bit string to copy.
00651          */
00652         BitString(const BitString& arg)
00653             : n(arg.n), bitString(new uint32_t[arg.n])
00654         {
00655             base_copySmall(bitString, arg.bitString, arg.n);
00656         }
00657 
00658         /** Destructor, deallocate memory.
00659          */
00660         ~BitString() { delete [] bitString; }
00661 
00662 
00663         /** @return the number of bits set
00664          */
00665         size_t count() const
00666         {
00667             return base_countBitsN(bitString, n);
00668         }
00669 
00670         /** @return the index table corresponding to this
00671          * bit string and the number of bits set.
00672          * @param table: where to write the table.
00673          */
00674         size_t indexTable(cindex_t *table) const
00675         {
00676             return base_bits2indexTable(bitString, n, table);
00677         }
00678 
00679         /** @return the size in int of the bitstring.
00680          */
00681         size_t intSize() const
00682         {
00683             return n;
00684         }
00685 
00686         /** @return the size in bits of the bitstring.
00687          */
00688         size_t size() const
00689         {
00690             return n << 5;
00691         }
00692 
00693         /********** Standard operators ********/
00694 
00695         BitString& operator |= (const BitString& arg)
00696         {
00697             assert(arg.n <= n);
00698             base_orBits(bitString, arg.bitString, arg.n);
00699             return *this;
00700         }
00701         ///< @pre arg is a uint32_t[n]
00702         BitString& operator |= (const uint32_t *arg)
00703         {
00704             assert(n == 0 || arg);
00705             base_orBits(bitString, arg, n);
00706             return *this;
00707         }
00708         BitString& operator &= (const BitString& arg)
00709         {
00710             assert(arg.n <= n);
00711             base_andBits(bitString, arg.bitString, arg.n);
00712             return *this;
00713         }
00714         ///< @pre arg is a uint32_t[n]
00715         BitString& operator &= (const uint32_t *arg)
00716         {
00717             assert(n == 0 || arg);
00718             base_andBits(bitString, arg, n);
00719             return *this;
00720         }
00721         BitString& operator ^= (const BitString& arg)
00722         {
00723             assert(arg.n <= n);
00724             base_xorBits(bitString, arg.bitString, arg.n);
00725             return *this;
00726         }
00727         ///< @pre arg is a uint32_t[n]
00728         BitString& operator ^= (const uint32_t *arg)
00729         {
00730             assert(n == 0 || arg);
00731             base_xorBits(bitString, arg, n);
00732             return *this;
00733         }
00734         BitString& operator = (const BitString& arg)
00735         {
00736             assert(arg.n <= n);
00737             base_copySmall(bitString, arg.bitString, arg.n);
00738             return *this;
00739         }
00740         ///< @pre arg is a uint32_t[n]
00741         BitString& operator = (const uint32_t *arg)
00742         {
00743             assert(n == 0 || arg);
00744             base_copySmall(bitString, arg, n);
00745             return *this;
00746         }
00747         bool operator == (const BitString& arg)
00748         {
00749             assert(arg.n <= n);
00750             return (bool) base_areEqual(bitString, arg.bitString, arg.n);
00751         }
00752         ///< @pre arg is a uint32_t[n]
00753         bool operator == (const uint32_t *arg)
00754         {
00755             assert(n == 0 || arg);
00756             return (bool) base_areEqual(bitString, arg, n);
00757         }
00758 
00759         /** @return true if there is no bit set, false otherwise.
00760          */
00761         bool isEmpty() const 
00762         {
00763             return base_areBitsReset(bitString, n);
00764         }
00765 
00766         /** Negate all bits.
00767          */
00768         BitString& neg()
00769         {
00770             base_negBits(bitString, n);
00771             return *this;
00772         }
00773 
00774         /** Set all the bits with bit.
00775          * @param bit: value of the bit to set (0 or 1).
00776          */
00777         BitString& operator = (bit_t bit)
00778         {
00779             base_fill(bitString, n, bit ? ~0 : 0);
00780             return *this;
00781         }
00782         BitString& operator = (Bit &b)
00783         {
00784             return *this = b();
00785         }
00786 
00787         /** Set a given bit (to 1).
00788          * @param index: index of the bit to set.
00789          * @pre index is in range of the bit string.
00790          */
00791         BitString& operator += (cindex_t index)
00792         {
00793             assert(index < size());
00794             base_setOneBit(bitString, index);
00795             return *this;
00796         }
00797 
00798         /** Reset a given bit (to 0).
00799          * @param index: index of the bit to reset.
00800          * @pre index is in range of the bit string.
00801          */
00802         BitString& operator -= (cindex_t index)
00803         {
00804             assert(index < size());
00805             base_resetOneBit(bitString, index);
00806             return *this;
00807         }
00808 
00809         /** Toggle a given bit.
00810          * @param index: index of the bit to toggle.
00811          * @pre index is in range of the bit string.
00812          */         
00813         BitString& operator ^= (cindex_t index)
00814         {
00815             assert(index < size());
00816             base_toggleOneBit(bitString, index);
00817             return *this;
00818         }
00819 
00820         /** Read a given bit.
00821          * @param index: index of the bit to read.
00822          * @pre index is in range of the bit string.
00823          */
00824         bit_t getBit(cindex_t index) const
00825         {
00826             assert(index < size());
00827             return base_getOneBit(bitString, index);
00828         }
00829 
00830         /** Assign one bit (=bit).
00831          * @param index: index of the bit to assign.
00832          * @param bit: the bit to assign.
00833          * @pre index is in range of the bit string.
00834          */
00835         BitString& assignBit(cindex_t index, bit_t bit)
00836         {
00837             assert(index < size());
00838             base_assignOneBit(bitString, index, bit);
00839             return *this;
00840         }
00841         BitString& assignBit(cindex_t index, Bit b)
00842         {
00843             return assignBit(index, b());
00844         }
00845 
00846         /** Add one bit (|=bit).
00847          * @param index: index of the bit to add.
00848          * @param bit: the bit to add.
00849          * @pre index is in range of the bit string.
00850          */
00851         BitString& addBit(cindex_t index, bit_t bit)
00852         {
00853             assert(index < size());
00854             base_addOneBit(bitString, index, bit);
00855             return *this;
00856         }
00857         BitString& addBit(cindex_t index, Bit b)
00858         {
00859             return addBit(index, b());
00860         }
00861 
00862         /** Subtract one bit (&=~bit).
00863          * @param index: index of the bit to add.
00864          * @param bit: the bit to subtract.
00865          * @pre index is in range of the bit string.
00866          */
00867         BitString& subBit(cindex_t index, bit_t bit)
00868         {
00869             assert(index < size());
00870             base_subOneBit(bitString, index, bit);
00871             return *this;
00872         }
00873         BitString& subBit(cindex_t index, Bit b)
00874         {
00875             return subBit(index, b());
00876         }
00877 
00878         /** Xor operation with one bit (^=bit).
00879          * @param index: index of the bit to "xor" with.
00880          * @param bit: argument bit for the xor.
00881          * @pre index is in range of the bit string.
00882          */
00883         BitString& xorBit(cindex_t index, bit_t bit)
00884         {
00885             assert(index < size());
00886             base_xorOneBit(bitString, index, bit);
00887             return *this;
00888         }
00889         BitString& xorBit(cindex_t index, Bit b)
00890         {
00891             return xorBit(index, b());
00892         }
00893 
00894         /** Easy access of bits:
00895          * if bs is a BitString, you can do: bs[3] |= Bit::One
00896          * @return a bit reference.
00897          * @param index: index of the bit to access.
00898          * @pre index is in range of the bit string.
00899          */
00900         Bit operator [] (cindex_t index)
00901         {
00902             assert(bitString && index < size());
00903             return Bit(bitString, index);
00904         }
00905 
00906         /** Pretty print.
00907          * @param os: where to print.
00908          */
00909         std::ostream& prettyPrint(std::ostream& os) const
00910         {
00911             return debug_cppPrintBitstring(os, bitString, n);
00912         }
00913 
00914         /** Access to the bit string.
00915          */
00916         uint32_t* operator () () { return bitString; }
00917         const uint32_t* operator () () const { return bitString; }
00918 
00919     private:
00920         size_t n;
00921         uint32_t *bitString;
00922     };
00923 
00924     //< Standard overload.
00925     static inline
00926     std::ostream& operator << (std::ostream& os, const BitString& bs)
00927     { return bs.prettyPrint(os); }
00928 
00929     //< Standard overload.
00930     static inline
00931     std::ostream& operator << (std::ostream& os, const Bit& b)
00932     { return os << b(); }
00933 }
00934 
00935 #endif /* __cplusplus */
00936 
00937 #endif /* INCLUDE_BASE_BITSTRING_H */

Generated on Fri Jun 30 00:02:30 2006 for Module base by  doxygen 1.4.2