//============================================================================= // bitvect.hpp // Simple bit vector template classes. // // Usage // To define a bit vector 80 bits wide (i.e., a set of 80 boolean values): // // DrtBitVect<80> bits; // Set of 80 bits // // Bits are numbered starting at 0, so an 80-bit bit vector contains bits // numbered 0 through 79. All of the bits in the bit vector are // initialized to false (cleared). // // To set the 12th bit (bit number 11) in the bit vector 'bits': // // bits.set(11); // Method 1 // bits.set(11, true); // Method 2 // bits[11] = true; // Method 3 // // To clear the 37th bit (bit number 36): // // bits.clear(36); // Method 1 // bits.set(36, false); // Method 2 // bits[36] = false; // Method 3 // // To clear all of the bits in the bit vector: // // bits.reset(); // // To retrieve the current value of the 48th bit (bit number 47): // // bool v; // // v = bits.get(47); // Method 1 // v = bits[47]; // Method 2 // // To copy the bit vector to another bit vector (of the same size): // // DrtBitVect<80> b2; // Another 80-bit bit vector // // b2 = bits; // // Caveats // Be careful when using the '[]' operator on bit vector objects, since it // is not a bool value, but rather is an intermediate object (of type // DrtBitVectAsg). This will bite you in situations such as: // // printf("bits[i]=%d\n", bits[i]); // Incorrect, not bool // // This can be fixed: // // printf("bits[i]=%d\n", (bool) bits[i]); // // Correct, explicit typecast // History // 1.00, 1998-09-28, David R Tribble. // First cut. // // 1.01, 1998-10-03, David R Tribble. // Template class DrtBitVect privately inherits class DrtBitVectImpl, // whose member functions are protected instead of public. // Rearranged the class declarations so that forward declarations are no // longer necessary. // // Author // David R. Tribble // dtribble@technologist.com // http://www.flash.net/~dtribble // // Copyright ©1998 by David R. Tribble, all rights reserved. // Permission is hereby granted to use, distribute, and modify this source // code provided that the original copyright and authorship notices remain // intact. //----------------------------------------------------------------------------- #ifndef drt_bitvect_hpp #define drt_bitvect_hpp 1 // Identification #ifndef NO_H_IDENT static const char drt_bitvect_hpp_id[] = "@(#)bitvect.hpp 1.01 1998-10-03 dtribble"; #endif // System includes #ifndef NULL #include #endif #ifndef CHAR_BIT #include #endif // Win32 DLL gibberish #undef DRTDECL #ifdef _WIN32 #ifdef drt_bitvect_lib #define DRTDECL __declspec(dllexport) #else #define DRTDECL __declspec(dllimport) #endif #else #define DRTDECL #endif // Namespace #if !NO_NAMESPACES namespace Drt { #endif //----------------------------------------------------------------------------- // class DrtBitVectAsg // Helper class for class 'DrtBitVect'. // // Notes // This class is used to implement DrtBitVect::operator[](). //----------------------------------------------------------------------------- #define DrtBitVectAsg_VERS 100 // Class version class DRTDECL DrtBitVectAsg { public: // Shared constants static const int VERS; // Class version public: // Functions inline /*void*/ ~DrtBitVectAsg(); // Destructor inline /*DrtBitVectAsg*/ DrtBitVectAsg(const DrtBitVectAsg &r); // Copy constructor inline /*DrtBitVectAsg*/ DrtBitVectAsg(unsigned long *bits, unsigned long msk); // Constructor public: // Operators inline const bool operator =(bool v); // Assignment operator inline /*const bool*/ operator bool() const; // Get bit value private: // Variables unsigned long * m_bits; // Bit vector portion unsigned long m_mask; // Bit mask private: // Functions // Constructors and destructors not provided /*DrtBitVectAsg*/ DrtBitVectAsg(); // Default constructor }; //----------------------------------------------------------------------------- // class DrtBitVectImpl // Helper class for class DrtBitVect. // // Notes // This class does all of the actual work for the member functions of // class DrtBitVectImpl. Thus, all template class instantiations share // the same code, and use only a small amount of inline code per // instantiation. // // This class only contains shared (static) member functions and has no // data (variable) members. // // Class DrtBitVect inherits this class privately, so that clients of // class DrtBitVect cannot access any of the member functions of this // class. //----------------------------------------------------------------------------- #define DrtBitVectImpl_VERS 100 // Class version class DRTDECL DrtBitVectImpl { public: // Shared constants static const int VERS; // Class version protected: // Shared functions static bool get(const unsigned long *s, int sz, int b); // Get a bit static bool set(unsigned long *s, int sz, int b, bool v); // Set a bit static bool set(unsigned long *s, int sz, int b); // Set a bit static bool clear(unsigned long *s, int sz, int b); // Clear a bit static void reset(unsigned long *s, int sz); // Clear all bits static void copy(unsigned long *s, int sz, const unsigned long *r); // Copy all bits static DrtBitVectAsg assign(unsigned long *s, int sz, int b); // Get an assignable bit private: // Constants enum Constants // Manifest constants { BPW = CHAR_BIT * sizeof(unsigned long) // Bits in a word }; private: // Shared variables static unsigned long s_dummy; // Assignable dummy bits private: // Functions // Constructors and destructors not provided /*void*/ ~DrtBitVectImpl(); // Destructor /*DrtBitVectImpl*/ DrtBitVectImpl(); // Default constructor /*DrtBitVectImpl*/ DrtBitVectImpl(const DrtBitVectImpl &r); // Copy constructor const DrtBitVectImpl & operator =(const DrtBitVectImpl &r); // Assignment operator }; //----------------------------------------------------------------------------- // class DrtBitVect [template] // Simple bit vector functions. // // This template declares a bit vector containing 'NBITS' bits. // // Usage // See the description at the top of this header file. // // Caveats // See the description at the top of this header file. // // Notes // This class inherits class DrtBitVectImpl privately, so that clients of // class DrtBitVect cannot access any of the member functions of class // DrtBitVectImpl. //----------------------------------------------------------------------------- #define DrtBitVect_VERS 100 // Class version template class DRTDECL DrtBitVect: private DrtBitVectImpl { public: // Functions inline /*void*/ ~DrtBitVect(); // Destructor inline /*DrtBitVect*/ DrtBitVect(); // Default constructor inline /*DrtBitVect*/ DrtBitVect(const DrtBitVect &r); // Copy constructor inline bool get(int b) const; // Get a bit inline bool set(int b); // Set a bit inline bool set(int b, bool v); // Set a bit inline bool clear(int b); // Clear a bit inline void reset(); // Clear all bits public: // Operators inline const DrtBitVect & operator =(const DrtBitVect &r); // Assignment operator inline const bool operator [](int b) const; // Get a bit inline DrtBitVectAsg operator [](int b); // Get an assignable bit private: // Constants enum Constants // Manifest constants { BPW = CHAR_BIT * sizeof(unsigned long), // Bits in a word NWORDS = (NBITS + BPW-1) / BPW // Words in the vector }; private: // Variables unsigned long m_bits[NWORDS]; // Vector of bits }; //----------------------------------------------------------------------------- // Inline member functions //----------------------------------------------------------------------------- template inline /*void*/ DrtBitVect::~DrtBitVect() { // Destructor // Do nothing } template inline /*DrtBitVect*/ DrtBitVect::DrtBitVect() { // Default constructor DrtBitVectImpl::reset(m_bits, NWORDS); } template inline /*DrtBitVect*/ DrtBitVect::DrtBitVect(const DrtBitVect &r) { // Copy constructor DrtBitVectImpl::copy(m_bits, NWORDS, r.m_bits); } template inline const DrtBitVect & DrtBitVect::operator =(const DrtBitVect &r) { // Assignment operator DrtBitVectImpl::copy(m_bits, NWORDS, r.m_bits); return (*this); } template inline bool DrtBitVect::get(int b) const { // Get bit 'b' of bit vector return (DrtBitVectImpl::get(m_bits, NWORDS, b)); } template inline bool DrtBitVect::set(int b, bool v) { // Set bit 'b' of bit vector to 'v' return (DrtBitVectImpl::set(m_bits, NWORDS, b, v)); } template inline bool DrtBitVect::set(int b) { // Set bit 'b' of bit vector to true return (DrtBitVectImpl::set(m_bits, NWORDS, b)); } template inline bool DrtBitVect::clear(int b) { // Clear bit 'b' of bit vector to false return (DrtBitVectImpl::clear(m_bits, NWORDS, b)); } template inline void DrtBitVect::reset() { // Clear all bits of bit vector to false DrtBitVectImpl::reset(m_bits, NWORDS); } template inline const bool DrtBitVect::operator [](int b) const { // Get non-assignable bit 'b' of bit vector return (DrtBitVectImpl::get(m_bits, NWORDS, b)); } template inline DrtBitVectAsg DrtBitVect::operator [](int b) { // Get assignable bit 'b' of bit vector return (DrtBitVectImpl::assign(m_bits, NWORDS, b)); } //----------------------------------------------------------------------------- // Inline member functions //----------------------------------------------------------------------------- inline /*void*/ DrtBitVectAsg::~DrtBitVectAsg() { // Destructor m_bits = NULL; } inline /*DrtBitVectAsg*/ DrtBitVectAsg::DrtBitVectAsg(const DrtBitVectAsg &r): m_bits(r.m_bits), m_mask(r.m_mask) { // Copy constructor } inline /*DrtBitVectAsg*/ DrtBitVectAsg::DrtBitVectAsg(unsigned long *bits, unsigned long msk): m_bits(bits), m_mask(msk) { // Constructor } inline const bool DrtBitVectAsg::operator =(bool v) { // Assign value 'v' to this assignable bit of a bit vector if (v) *m_bits |= m_mask; else *m_bits &= ~m_mask; return (v); } inline /*const bool*/ DrtBitVectAsg::operator bool() const { // Get value of this assignable bit of a bit vector return ((*m_bits & m_mask) != 0); } // Namespace #if !NO_NAMESPACES } // namespace Drt #endif // Win32 DLL gibberish #ifdef _WIN32 #undef DRTDECL #define DRTDECL __declspec(dllimport) #endif #endif // drt_bitvect_hpp // Settings for Emacs: // Local Variables: // tab-width: 8 // End: // End bitvect.hpp