casa
$Rev:20696$
|
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