/***************************************************************************** # Copyright (C) 1994-2008 by David Gordon. # All rights reserved. # # This software is part of a beta-test version of the Consed/Autofinish # package. It should not be redistributed or # used for any commercial purpose, including commercially funded # sequencing, without written permission from the author and the # University of Washington. # # This software is provided ``AS IS'' and any express or implied # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose, are disclaimed. # In no event shall the authors or the University of Washington be # liable for any direct, indirect, incidental, special, exemplary, or # consequential damages (including, but not limited to, procurement of # substitute goods or services; loss of use, data, or profits; or # business interruption) however caused and on any theory of liability, # whether in contract, strict liability, or tort (including negligence # or otherwise) arising in any way out of the use of this software, even # if advised of the possibility of such damage. # # Building Consed from source is error prone and not simple which is # why I provide executables. Due to time limitations I cannot # provide any assistance in building Consed. Even if you do not # modify the source, you may introduce errors due to using a # different version of the compiler, a different version of motif, # different versions of other libraries than I used, etc. For this # reason, if you discover Consed bugs, I can only offer help with # those bugs if you first reproduce those bugs with an executable # provided by me--not an executable you have built. # # Modifying Consed is also difficult. Although Consed is modular, # some modules are used by many other modules. Thus making a change # in one place can have unforeseen effects on many other features. # It may takes months for you to notice these other side-effects # which may not seen connected at all. It is not feasable for me to # provide help with modifying Consed sources because of the # potentially huge amount of time involved. # #*****************************************************************************/ #ifndef mbtValVectorOfBool_included #define mbtValVectorOfBool_included #include "mbtValVector.h" #include const int nNumberOfBitsInMbtValVectorOfBoolElement = 8; class mbtValVectorOfBool : public mbtValVector { public: // if nCapacity is 1 to 8, need 1 element. Hence the fancy // nCapacity + nNumberOfBitsInMbtValVectorOfBoolElement - 1 ) / // nNumberOfBitsInMbtValVectorOfBoolElement business // nBitOffset is just where the array should start: usually 1 // for sequences mbtValVectorOfBool( const size_t nCapacity, const int nBitOffset, const RWCString& soName ) : mbtValVector( ( nCapacity + nNumberOfBitsInMbtValVectorOfBoolElement - 1 ) / nNumberOfBitsInMbtValVectorOfBoolElement, 0, 0 ), nBitOffset_( nBitOffset ), nCurrentLength_( nCapacity ), soName_( soName ) { setMasks(); } mbtValVectorOfBool( const mbtValVectorOfBool& mbt ); void setOffset( const int nBitOffset ) { nBitOffset_ = nBitOffset; } int nGetStartIndex() { return nBitOffset_; } int nGetEndIndex() { return nCurrentLength_ + nBitOffset_ - 1; } // make this inoperative // inline bool& operator[]( size_t n ) { inline bool operator[]( size_t n ) const { if ( ( n - nBitOffset_ ) >= nCurrentLength_ ) { PANIC_OST( ost ) << "In mbtValVectorOfBool::operator[] ( " << n << " ) out of bounds with nCurrentLength_ = " << nCurrentLength_ << " name: " << soName_ << ends; throw RWInternalError( ost.str() ); } int nElementIndex = ( n - nBitOffset_ ) / nNumberOfBitsInMbtValVectorOfBoolElement; int nOffsetWithinElement = ( n - nBitOffset_ ) % nNumberOfBitsInMbtValVectorOfBoolElement; return( ( pArray_[ nElementIndex ] >> nOffsetWithinElement) & 1 ); } inline bool bGetValue( const size_t n ) { return( operator[]( n ) ); } size_t length() const { return( nCurrentLength_ ); } inline void setValue( const size_t n, const bool bValue ) { if ( ( n - nBitOffset_ ) >= nCurrentLength_ ) { PANIC_OST( ost ) << "In mbtValVectorOfBool::setValue( " << n << ", " << bValue << ") out of bounds with nCurrentLength_ = " << nCurrentLength_ << " name: " << soName_ << ends; throw RWInternalError( ost.str() ); } int nElementIndex = ( n - nBitOffset_ ) / nNumberOfBitsInMbtValVectorOfBoolElement; int nOffsetWithinElement = ( n - nBitOffset_ ) % nNumberOfBitsInMbtValVectorOfBoolElement; if ( bValue ) pArray_[ nElementIndex ] |= ucSetBitMasks_[ nOffsetWithinElement ]; else pArray_[ nElementIndex ] &= ucClearBitMasks_[ nOffsetWithinElement ]; } static void setMasks() { if ( bMasksSet_ ) return; // check that unsigned char can hold at least 8 bits assert( nNumberOfBitsInMbtValVectorOfBoolElement <= sizeof( unsigned char ) * 8 ); for( int n = 0; n < nNumberOfBitsInMbtValVectorOfBoolElement; ++n ) { ucSetBitMasks_[ n ] = ( ( (unsigned char) 1 ) << n ); ucClearBitMasks_[ n ] = ~ucSetBitMasks_[ n ]; } bMasksSet_ = true; }; void setName( const RWCString& soName ) { soName_ = soName; } public: int nCurrentLength_; int nBitOffset_; static bool bMasksSet_; static unsigned char ucSetBitMasks_[nNumberOfBitsInMbtValVectorOfBoolElement]; static unsigned char ucClearBitMasks_[nNumberOfBitsInMbtValVectorOfBoolElement]; RWCString soName_; }; #endif