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()
