You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
493 lines
12 KiB
493 lines
12 KiB
ANTLR_BEGIN_NAMESPACE()
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE BitsetList<ImplTraits>::BitsetList()
|
|
{
|
|
m_bits = NULL;
|
|
m_length = 0;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE BitsetList<ImplTraits>::BitsetList( ANTLR_BITWORD* bits, ANTLR_UINT32 length )
|
|
{
|
|
m_bits = bits;
|
|
m_length = length;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE ANTLR_BITWORD* BitsetList<ImplTraits>::get_bits() const
|
|
{
|
|
return m_bits;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE ANTLR_UINT32 BitsetList<ImplTraits>::get_length() const
|
|
{
|
|
return m_length;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE void BitsetList<ImplTraits>::set_bits( ANTLR_BITWORD* bits )
|
|
{
|
|
m_bits = bits;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE void BitsetList<ImplTraits>::set_length( ANTLR_UINT32 length )
|
|
{
|
|
m_length = length;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
typename BitsetList<ImplTraits>::BitsetType* BitsetList<ImplTraits>::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 <class ImplTraits>
|
|
typename BitsetList<ImplTraits>::BitsetType* BitsetList<ImplTraits>::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<ImplTraits>(numElements);
|
|
memcpy(bitset->get_blist().get_bits(), m_bits, numElements * sizeof(ANTLR_BITWORD));
|
|
|
|
// All seems good
|
|
//
|
|
return bitset;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
Bitset<ImplTraits>::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 <class ImplTraits>
|
|
Bitset<ImplTraits>::Bitset( const Bitset& bitset )
|
|
:m_blist(bitset.m_blist)
|
|
{
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE Bitset<ImplTraits>* Bitset<ImplTraits>::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 <class ImplTraits>
|
|
Bitset<ImplTraits>* Bitset<ImplTraits>::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 <class ImplTraits>
|
|
void Bitset<ImplTraits>::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 <class ImplTraits>
|
|
ANTLR_UINT32 Bitset<ImplTraits>::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 <class ImplTraits>
|
|
ANTLR_INLINE void Bitset<ImplTraits>::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 <class ImplTraits>
|
|
void Bitset<ImplTraits>::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 <class ImplTraits>
|
|
bool Bitset<ImplTraits>::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 <class ImplTraits>
|
|
bool Bitset<ImplTraits>::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 <class ImplTraits>
|
|
ANTLR_INLINE ANTLR_UINT32 Bitset<ImplTraits>::numBits() const
|
|
{
|
|
return m_blist.get_length() << ANTLR_BITSET_LOG_BITS;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE typename ImplTraits::BitsetListType& Bitset<ImplTraits>::get_blist()
|
|
{
|
|
return m_blist;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE void Bitset<ImplTraits>::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 <class ImplTraits>
|
|
ANTLR_INLINE bool Bitset<ImplTraits>::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 <class ImplTraits>
|
|
ANTLR_INT32* Bitset<ImplTraits>::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; i<numBits; i++)
|
|
{
|
|
if (this->isMember(i) == true)
|
|
intList[index++] = i;
|
|
}
|
|
|
|
// Result set
|
|
//
|
|
return intList;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE Bitset<ImplTraits>::~Bitset()
|
|
{
|
|
if (m_blist.get_bits() != NULL)
|
|
AllocPolicyType::free(m_blist.get_bits());
|
|
return;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
void Bitset<ImplTraits>::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 <class ImplTraits>
|
|
ANTLR_INLINE ANTLR_UINT64 Bitset<ImplTraits>::BitMask(ANTLR_UINT32 bitNumber)
|
|
{
|
|
return ((ANTLR_UINT64)1) << (bitNumber & (ANTLR_BITSET_MOD_MASK));
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE ANTLR_UINT32 Bitset<ImplTraits>::NumWordsToHold(ANTLR_UINT32 bit)
|
|
{
|
|
return (bit >> ANTLR_BITSET_LOG_BITS) + 1;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
ANTLR_INLINE ANTLR_UINT32 Bitset<ImplTraits>::WordNumber(ANTLR_UINT32 bit)
|
|
{
|
|
return bit >> ANTLR_BITSET_LOG_BITS;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
void Bitset<ImplTraits>::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 <class ImplTraits>
|
|
Bitset<ImplTraits>* Bitset<ImplTraits>::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<ImplTraits>* bitset = new Bitset<ImplTraits>(0);
|
|
bitset->add(bit);
|
|
return bitset;
|
|
}
|
|
|
|
template <class ImplTraits>
|
|
Bitset<ImplTraits>* Bitset<ImplTraits>::BitsetOf(ANTLR_INT32 bit1, ANTLR_INT32 bit2)
|
|
{
|
|
Bitset<ImplTraits>* bitset = Bitset<ImplTraits>::BitsetOf(bit1);
|
|
bitset->add(bit2);
|
|
return bitset;
|
|
}
|
|
|
|
//static
|
|
template <class ImplTraits>
|
|
Bitset<ImplTraits>* Bitset<ImplTraits>::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<ImplTraits>* bitset = new Bitset<ImplTraits>(0);
|
|
for( int i = 0; i < list.size(); ++i )
|
|
bitset->add( list[i] );
|
|
|
|
return bitset;
|
|
}
|
|
|
|
ANTLR_END_NAMESPACE()
|