casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
BitVector.h
Go to the documentation of this file.
00001 //# BitVector.h: Bit vectors of any size
00002 //# Copyright (C) 1993,1994,1995,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: BitVector.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef CASA_BITVECTOR_H
00029 #define CASA_BITVECTOR_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <casa/Containers/Block.h>
00034 #include <casa/Utilities/Assert.h>
00035 #include <casa/iosfwd.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# Forward Declarations
00040 class BitVectorHelper;
00041 
00042 // The size of a unsigned Integer ( assumes 8-bit char )
00043 const uInt WORDSIZE = sizeof(uInt)*8;
00044 
00045 // <summary>
00046 // Bit vectors of any size
00047 // </summary>
00048 
00049 // <use visibility=export>
00050 
00051 // <reviewed reviewer="Friso Olnon" date="1995/03/13" tests="tBitVector" demos="">
00052 
00053 // <etymology>
00054 // A variable utilized as a discrete collection of bits is referred
00055 // to as a bit vector.
00056 // </etymology>
00057 
00058 // <synopsis> 
00059 // Bit vectors are an efficent method of keeping <em>True/False</em>
00060 // information on a set of items or conditions. Class BitVector
00061 // provides functions to manipulate individual bits in the vector and
00062 // to perform logical operations on whole bit vectors.
00063 // </synopsis> 
00064 
00065 // <example>
00066 // <srcblock>
00067 // // Create a bit vector with 20 bits (and set them all to False). 
00068 // BitVector bv (20, False);
00069 //
00070 // // Change some individual bits:
00071 // // Turn On (make True) bit 19.
00072 // bv.setBit (19);
00073 // // Turn Off (make False) bit 12 (superfluous here).
00074 // bv.clearBit (12);
00075 // // Toggle bit 5 (here: change value from 0 (False) to 1 (True)).
00076 // bv.toggleBit (5)
00077 // // Another way of setting a bit using the index operator.
00078 // bv[0] = True;
00079 // // Assign the value of bit 0 to bit 1  (in three ways).
00080 // bv[1] = bv.getBit(0);
00081 // bv[1] = bv[0];
00082 // bv.putBit (1, bv.getBit(0));
00083 //
00084 // // Show the bit vector size and its value on standard output.
00085 // cout << "Size of bit vector:  "<< b.nbits() <<"\n";
00086 // cout << "Value of bit vector: "<< bv        <<"\n";
00087 //
00088 // // Perform logical operations on bit vectors.
00089 // // Create two more bit vectors.
00090 // BitVector bv2 (40, False);
00091 // BitVector bv3 (40, True);
00092 // // bitwise OR
00093 // bv = bv2 | bv3;
00094 // // bitwise AND
00095 // bv = bv2 & bv3;
00096 // // bitwise XOR
00097 // bv = bv2 ^ bv3;
00098 // // bitwise NOT
00099 // bv = ~bv2;
00100 //
00101 // // Reset all bits to False, and then to True
00102 // bv = False;
00103 // bv.set (True);
00104 // // Change the vector's size to 10 (and copy the old values).
00105 // bv.resize (10);
00106 // // Change back to original size and set all bits to True.
00107 // void bv.resize (size, True, False);
00108 // </srcblock>
00109 // </example> 
00110 
00111 
00112 class BitVector
00113 {
00114 public:
00115     // BitVectorHelper is a helper class.
00116     friend class BitVectorHelper;
00117 
00118     // Create a bit vector of length 0.
00119     BitVector ();
00120 
00121     // Create a bit vector with <src>length</src> bits
00122     // and set all bits to to the specified state.
00123     BitVector (uInt length, Bool state);
00124 
00125     // Copy constructor (copy semantics).
00126     BitVector (const BitVector& that);
00127 
00128     // Delete the bit vector.
00129    ~BitVector ();
00130 
00131     // Assignment (copy semantics).
00132     BitVector& operator= (const BitVector& that);
00133 
00134     // Set all bits to the given state.
00135     BitVector& operator= (Bool state);
00136 
00137     // Return the number of bits in the bitvector.
00138     uInt nbits() const;
00139 
00140     // Set a bit at the given position (0-relative).
00141     // In debug-mode an exception is thrown when the position is invalid.
00142     void setBit (uInt pos); 
00143 
00144     // Clear a bit at the given position (0-relative).
00145     // In debug-mode an exception is thrown when the position is invalid.
00146     void clearBit (uInt pos); 
00147 
00148     // Toggle a bit at the given position (0-relative).
00149     // It returns the original state.
00150     // In debug-mode an exception is thrown when the position is invalid.
00151     Bool toggleBit (uInt pos); 
00152 
00153     // Get a bit at the given position (0-relative).
00154     // In debug-mode an exception is thrown when the position is invalid.
00155     Bool getBit (uInt pos) const;
00156 
00157     // Set a bit at the given position (0-relative) to the given state.
00158     // In debug-mode an exception is thrown when the position is invalid.
00159     void putBit (uInt pos, Bool state);
00160 
00161     // Index operator to access the specified bit.
00162     // In debug-mode an exception is thrown when the position is invalid.
00163     // <group>
00164     Bool operator[] (uInt pos) const;
00165     BitVectorHelper operator[] (uInt pos);
00166     // </group>
00167 
00168     // Logical operations on whole bit vectors.
00169     // The binary operators <src>&</src> (bitwise
00170     // AND), <src>|</src> (bitwise OR) and <src>^</src> (bitwise XOR),
00171     // and the unary operator <src>~</src> (bitwise NOT) are provided.
00172     // An exception is thrown if the lengths of the vectors differ.
00173     // <group>
00174     BitVector operator& (const BitVector& that) const;
00175     BitVector operator| (const BitVector& that) const;
00176     BitVector operator^ (const BitVector& that) const;
00177     BitVector operator~ () const;
00178     // </group>
00179 
00180     // Logical in-place operations on whole bit vectors.
00181     // The binary operators <src>&</src> (bitwise
00182     // AND), <src>|</src> (bitwise OR) and <src>^</src> (bitwise XOR),
00183     // and the unary operator <src>reverse</src> (bitwise NOT) are provided.
00184     // An exception is thrown if the lengths of the vectors differ.
00185     // <group>
00186     void operator&= (const BitVector& that);
00187     void operator|= (const BitVector& that);
00188     void operator^= (const BitVector& that);
00189     void reverse ();
00190     // </group>
00191 
00192     // Returns True if all bits are equal.
00193     // An exception is thrown if the lengths of the vectors differ.
00194     Bool operator== (const BitVector& that) const;
00195 
00196     // Returns True if a bit differs.
00197     // An exception is thrown if the lengths of the vectors differ.
00198     Bool operator!= (const BitVector& that) const;
00199 
00200     // Resize the bit vector to the new length.
00201     // By default the original bits are copied.
00202     // The remaining bits (or all bits in case of no copy) are
00203     // set the the given state.
00204     void resize (uInt length, Bool state=False, Bool copy=True);
00205 
00206     // Set all bits of the bit vector to the specified state.
00207     void set (Bool state);
00208 
00209     // Set <src>length</src> bits starting at the start position
00210     // (0-relative) to the given state.
00211     // An exception is thrown if start+length exceeds the length
00212     // of the vector.
00213     void set (uInt start, uInt length, Bool state);
00214 
00215     // Copy <src>length</src> bits starting at thatStart in the
00216     // other BitVector to this BitVector starting at thisStart.
00217     void copy (uInt thisStart, uInt length, const BitVector& that,
00218                uInt thatStart);
00219 
00220     // Write a representation of the bit vector (a list of
00221     // <em>zeros</em> and <em>ones</em> enclosed in square
00222     // parentheses) to ostream.
00223     friend ostream& operator<< (ostream&, const BitVector& vector);
00224 
00225 private:
00226     // Number of bits in the BitVector object.
00227     uInt size_p;
00228 
00229     // Pointer to the actual bit vector, stored as a contiguous
00230     // sequence of one or more unsigned integers.
00231     Block<uInt> bits_p;
00232 };
00233 
00234 
00235 
00236 // <summary> Helper class for BitVector </summary>
00237 // <use visibility=local>
00238 // <reviewed reviewer="Friso Olnon" date="1995/03/13" tests="tBitVector" demos="">
00239 
00240 // <prerequisite>
00241 // <li> class <linkto class=BitVector>BitVector</linkto>
00242 // </prerequisite>
00243 
00244 // <synopsis> 
00245 // Helper class for class <linkto class=BitVector>BitVector</linkto>.
00246 // For all practical purposes a BitVectorHelper object is the individual bit in
00247 // a bit vector. It is the object returned by the index operator of
00248 // BitVector.
00249 // </synopsis> 
00250 
00251 class BitVectorHelper
00252 {
00253 friend class BitVector;
00254 
00255 public:
00256     // Copy constructor has to be public.
00257     BitVectorHelper (const BitVectorHelper& that);
00258 
00259     // Set the bit to the state of the bit in the other BitVector.
00260     // Thus assignment has not the usual copy semantics, but affects
00261     // the underlying BitVector bit.
00262     const BitVectorHelper& operator= (const BitVectorHelper& that) const;
00263 
00264     // Set to a state.
00265     const BitVectorHelper& operator= (Bool state) const;
00266 
00267     // Defines the conversion from <src>BitVectorHelper</src> to
00268     // <src>Bool</src>.
00269     operator Bool() const;
00270 
00271 private:
00272     uInt bitNumber_p;
00273 
00274     // Pointer back to the original vector.
00275     BitVector* vecPtr_p;
00276 
00277     // The constructor we actually use.
00278     BitVectorHelper (uInt bitNumber, BitVector* vector);
00279 };
00280 
00281 
00282 
00283 inline void BitVector::setBit (uInt pos)
00284 {
00285     DebugAssert (pos < size_p, AipsError);
00286     uInt index = pos/WORDSIZE;
00287     bits_p[index] |= (1 << (pos - index*WORDSIZE));
00288 }
00289 
00290 inline void BitVector::clearBit (uInt pos)
00291 {
00292     DebugAssert (pos < size_p, AipsError);
00293     uInt index = pos/WORDSIZE;
00294     bits_p[index] &= (~ (1 << (pos - index*WORDSIZE)));
00295 }
00296 
00297 inline Bool BitVector::operator[] (uInt pos) const
00298 {
00299     return getBit (pos);
00300 }
00301 
00302 inline uInt BitVector::nbits() const
00303 {
00304   return size_p;
00305 }
00306 
00307 
00308 inline BitVectorHelper::BitVectorHelper (uInt bitNumber, BitVector* vector)
00309 : bitNumber_p (bitNumber),
00310   vecPtr_p    (vector)
00311 {}
00312 
00313 inline BitVectorHelper BitVector::operator[] (uInt pos)
00314 {
00315     return BitVectorHelper (pos, this);
00316 }
00317 
00318 inline BitVectorHelper::BitVectorHelper (const BitVectorHelper& that)
00319 : bitNumber_p (that.bitNumber_p),
00320   vecPtr_p    (that.vecPtr_p)
00321 {}
00322 
00323 inline const BitVectorHelper& BitVectorHelper::operator= (Bool state) const
00324 {
00325     vecPtr_p->putBit (bitNumber_p, state);
00326     return *this;
00327 }
00328 
00329 inline BitVectorHelper::operator Bool() const
00330 {
00331     return vecPtr_p->getBit (bitNumber_p);
00332 }
00333 
00334 inline const BitVectorHelper& BitVectorHelper::operator=
00335                                     (const BitVectorHelper& that) const
00336 {
00337     vecPtr_p->putBit (bitNumber_p, that.vecPtr_p->getBit (that.bitNumber_p));
00338     return *this;
00339 }
00340 
00341 
00342 
00343 
00344 } //# NAMESPACE CASA - END
00345 
00346 #endif
00347