namespace antlr3 { template ANTLR_INLINE BitsetList::BitsetList() { m_bits = NULL; m_length = 0; } template ANTLR_INLINE BitsetList::BitsetList( ANTLR_BITWORD* bits, ANTLR_UINT32 length ) { m_bits = bits; m_length = length; } template ANTLR_INLINE ANTLR_BITWORD* BitsetList::get_bits() const { return m_bits; } template ANTLR_INLINE ANTLR_UINT32 BitsetList::get_length() const { return m_length; } template ANTLR_INLINE void BitsetList::set_bits( ANTLR_BITWORD* bits ) { m_bits = bits; } template ANTLR_INLINE void BitsetList::set_length( ANTLR_UINT32 length ) { m_length = length; } template typename BitsetList::BitsetType* BitsetList::bitsetLoad() { // Allocate memory for the bitset structure itself // the input parameter is the bit number (0 based) // to include in the bitset, so we need at at least // bit + 1 bits. If any arguments indicate a // a bit higher than the default number of bits (0 means default size) // then Add() will take care // of it. // BitsetType* bitset = new BitsetType(); if (this != NULL) { // Now we can add the element bits into the set // ANTLR_UINT32 count=0; while (count < m_length) { if( bitset->get_blist().get_length() <= count) bitset->grow(count+1); typename ImplTraits::BitsetListType& blist = bitset->get_blist(); blist.m_bits[count] = *(m_bits+count); count++; } } // return the new bitset // return bitset; } template typename BitsetList::BitsetType* BitsetList::bitsetCopy() { BitsetType* bitset; ANTLR_UINT32 numElements = m_length; // Avoid memory thrashing at the expense of a few more bytes // if (numElements < 8) numElements = 8; // Allocate memory for the bitset structure itself // bitset = new Bitset(numElements); memcpy(bitset->get_blist().get_bits(), m_bits, numElements * sizeof(ANTLR_BITWORD)); // All seems good // return bitset; } template Bitset::Bitset( ANTLR_UINT32 numBits ) { // Avoid memory thrashing at the up front expense of a few bytes if (numBits < (8 * ANTLR_BITSET_BITS)) numBits = 8 * ANTLR_BITSET_BITS; // No we need to allocate the memory for the number of bits asked for // in multiples of ANTLR3_UINT64. // ANTLR_UINT32 numelements = ((numBits -1) >> ANTLR_BITSET_LOG_BITS) + 1; m_blist.set_bits( (ANTLR_BITWORD*) AllocPolicyType::alloc0(numelements * sizeof(ANTLR_BITWORD))); m_blist.set_length( numelements ); } template Bitset::Bitset( const Bitset& bitset ) :m_blist(bitset.m_blist) { } template ANTLR_INLINE Bitset* Bitset::clone() const { Bitset* bitset; // Allocate memory for the bitset structure itself // bitset = new Bitset( ANTLR_BITSET_BITS * m_blist.get_length() ); // Install the actual bits in the source set // memcpy(bitset->m_blist.get_bits(), m_blist.get_bits(), m_blist.get_length() * sizeof(ANTLR_BITWORD) ); // All seems good // return bitset; } template Bitset* Bitset::bor(Bitset* bitset2) { Bitset* bitset; if (this == NULL) return bitset2->clone(); if (bitset2 == NULL) return this->clone(); // Allocate memory for the newly ordered bitset structure itself. // bitset = this->clone(); bitset->bitsetORInPlace(bitset2); return bitset; } template void Bitset::borInPlace(Bitset* bitset2) { ANTLR_UINT32 minimum; if (bitset2 == NULL) return; // First make sure that the target bitset is big enough // for the new bits to be ored in. // if ( m_blist.get_length() < bitset2->m_blist.get_length() ) this->growToInclude( bitset2->m_blist.get_length() * sizeof(ANTLR_BITWORD) ); // Or the miniimum number of bits after any resizing went on // if ( m_blist.get_length() < bitset2->m_blist.get_length() ) minimum = m_blist.get_length(); else minimum = bitset2->m_blist.get_length(); ANTLR_BITWORD* bits1 = m_blist.get_bits(); ANTLR_BITWORD* bits2 = bitset2->m_blist.get_bits(); for (ANTLR_UINT32 i = minimum; i > 0; i--) bits1[i-1] |= bits2[i-1]; } template ANTLR_UINT32 Bitset::size() const { ANTLR_UINT32 degree; ANTLR_INT32 i; ANTLR_INT8 bit; // TODO: Come back to this, it may be faster to & with 0x01 // then shift right a copy of the 4 bits, than shift left a constant of 1. // But then again, the optimizer might just work this out // anyway. // degree = 0; ANTLR_BITWORD* bits = m_blist.get_bits(); for (i = m_blist.get_length() - 1; i>= 0; i--) { if (bits[i] != 0) { for(bit = ANTLR_BITSET_BITS - 1; bit >= 0; bit--) { if((bits[i] & (((ANTLR_BITWORD)1) << bit)) != 0) { degree++; } } } } return degree; } template ANTLR_INLINE void Bitset::add(ANTLR_INT32 bit) { ANTLR_UINT32 word = Bitset::WordNumber(bit); if (word >= m_blist.get_length() ) this->growToInclude(bit); ANTLR_BITWORD* bits = m_blist.get_bits(); bits[word] |= Bitset::BitMask(bit); } template void Bitset::grow(ANTLR_INT32 newSize) { ANTLR_BITWORD* newBits; // Space for newly sized bitset - TODO: come back to this and use realloc?, it may // be more efficient... // newBits = (ANTLR_BITWORD*) AllocPolicyType::alloc0(newSize * sizeof(ANTLR_BITWORD) ); if ( m_blist.get_bits() != NULL) { // Copy existing bits // memcpy( newBits, m_blist.get_bits(), m_blist.get_length() * sizeof(ANTLR_BITWORD) ); // Out with the old bits... de de de derrr // AllocPolicyType::free( m_blist.get_bits() ); } // In with the new bits... keerrrang. // m_blist.set_bits(newBits); m_blist.set_length(newSize); } template bool Bitset::equals(Bitset* bitset2) const { ANTLR_UINT32 minimum; ANTLR_UINT32 i; if (this == NULL || bitset2 == NULL) return false; // Work out the minimum comparison set // if ( m_blist.get_length() < bitset2->m_blist.get_length() ) minimum = m_blist.get_length(); else minimum = bitset2->m_blist.get_length(); // Make sure explict in common bits are equal // for (i = minimum - 1; i < minimum ; i--) { ANTLR_BITWORD* bits1 = m_blist.get_bits(); ANTLR_BITWORD* bits2 = bitset2->m_blist.get_bits(); if ( bits1[i] != bits2[i]) return false; } // Now make sure the bits of the larger set are all turned // off. // if ( m_blist.get_length() > minimum) { for (i = minimum ; i < m_blist.get_length(); i++) { ANTLR_BITWORD* bits = m_blist.get_bits(); if(bits[i] != 0) return false; } } else if (bitset2->m_blist.get_length() > minimum) { ANTLR_BITWORD* bits = m_blist.get_bits(); for (i = minimum; i < bitset2->m_blist.get_length(); i++) { if ( bits[i] != 0 ) return false; } } return true; } template bool Bitset::isMember(ANTLR_UINT32 bit) const { ANTLR_UINT32 wordNo = Bitset::WordNumber(bit); if (wordNo >= m_blist.get_length()) return false; ANTLR_BITWORD* bits = m_blist.get_bits(); if ( (bits[wordNo] & Bitset::BitMask(bit)) == 0) return false; else return true; } template ANTLR_INLINE ANTLR_UINT32 Bitset::numBits() const { return m_blist.get_length() << ANTLR_BITSET_LOG_BITS; } template ANTLR_INLINE typename ImplTraits::BitsetListType& Bitset::get_blist() { return m_blist; } template ANTLR_INLINE void Bitset::remove(ANTLR_UINT32 bit) { ANTLR_UINT32 wordNo = Bitset::WordNumber(bit); if (wordNo < m_blist.get_length()) { ANTLR_BITWORD* bits = m_blist.get_bits(); bits[wordNo] &= ~(Bitset::BitMask(bit)); } } template ANTLR_INLINE bool Bitset::isNilNode() const { ANTLR_UINT32 i; ANTLR_BITWORD* bits = m_blist.get_bits(); for (i = m_blist.get_length() -1 ; i < m_blist.get_length(); i--) { if(bits[i] != 0) return false; } return true; } template ANTLR_INT32* Bitset::toIntList() const { ANTLR_UINT32 numInts; // How many integers we will need ANTLR_UINT32 numBits; // How many bits are in the set ANTLR_UINT32 i; ANTLR_UINT32 index; ANTLR_INT32* intList; numInts = this->size() + 1; numBits = this->numBits(); intList = (ANTLR_INT32*) AllocPolicyType::alloc(numInts * sizeof(ANTLR_INT32)); intList[0] = numInts; // Enumerate the bits that are turned on // for (i = 0, index = 1; iisMember(i) == true) intList[index++] = i; } // Result set // return intList; } template ANTLR_INLINE Bitset::~Bitset() { if (m_blist.get_bits() != NULL) AllocPolicyType::free(m_blist.get_bits()); return; } template void Bitset::growToInclude(ANTLR_INT32 bit) { ANTLR_UINT32 bl; ANTLR_UINT32 nw; bl = (m_blist.get_length() << 1); nw = Bitset::NumWordsToHold(bit); if (bl > nw) this->grow(bl); else this->grow(nw); } template ANTLR_INLINE ANTLR_UINT64 Bitset::BitMask(ANTLR_UINT32 bitNumber) { return ((ANTLR_UINT64)1) << (bitNumber & (ANTLR_BITSET_MOD_MASK)); } template ANTLR_INLINE ANTLR_UINT32 Bitset::NumWordsToHold(ANTLR_UINT32 bit) { return (bit >> ANTLR_BITSET_LOG_BITS) + 1; } template ANTLR_INLINE ANTLR_UINT32 Bitset::WordNumber(ANTLR_UINT32 bit) { return bit >> ANTLR_BITSET_LOG_BITS; } template void Bitset::bitsetORInPlace(Bitset* bitset2) { ANTLR_UINT32 minimum; ANTLR_UINT32 i; if (bitset2 == NULL) return; // First make sure that the target bitset is big enough // for the new bits to be ored in. // if ( m_blist.get_length() < bitset2->m_blist.get_length() ) this->growToInclude( bitset2->m_blist.get_length() * sizeof(ANTLR_BITWORD) ); // Or the miniimum number of bits after any resizing went on // if ( m_blist.get_length() < bitset2->m_blist.get_length() ) minimum = m_blist.get_length(); else minimum = bitset2->m_blist.get_length(); ANTLR_BITWORD* bits1 = m_blist.get_bits(); ANTLR_BITWORD* bits2 = bitset2->m_blist.get_bits(); for (i = minimum; i > 0; i--) bits1[i-1] |= bits2[i-1]; } template Bitset* Bitset::BitsetOf(ANTLR_INT32 bit) { // Allocate memory for the bitset structure itself // the input parameter is the bit number (0 based) // to include in the bitset, so we need at at least // bit + 1 bits. If any arguments indicate a // a bit higher than the default number of bits (0 menas default size) // then Add() will take care // of it. // Bitset* bitset = new Bitset(0); bitset->add(bit); return bitset; } template Bitset* Bitset::BitsetOf(ANTLR_INT32 bit1, ANTLR_INT32 bit2) { Bitset* bitset = Bitset::BitsetOf(bit1); bitset->add(bit2); return bitset; } //static template Bitset* Bitset::BitsetFromList(const IntListType& list) { // We have no idea what exactly is in the list // so create a default bitset and then just add stuff // as we enumerate. // Bitset* bitset = new Bitset(0); for( int i = 0; i < list.size(); ++i ) bitset->add( list[i] ); return bitset; } }