#ifndef _Bitfield_H
#define _Bitfield_H
#include <vector>
#include "Defs.h"
namespace OpenZWave
{
class OPENZWAVE_EXPORT Bitfield
{
friend class Iterator;
public:
Bitfield():m_numSetBits(0){}
~Bitfield(){}
void Set( uint32 _idx )
{
if( !IsSet(_idx) )
{
uint32 newSize = (_idx>>5)+1;
if( newSize > m_bits.size() )
{
m_bits.resize( newSize, 0 );
}
m_bits[_idx>>5] |= (1<<(_idx&0x1f));
++m_numSetBits;
}
}
void Clear( uint32 _idx )
{
if( IsSet(_idx) )
{
m_bits[_idx>>5] &= ~(1<<(_idx&0x1f));
--m_numSetBits;
}
}
bool IsSet( uint32 _idx )const
{
if( (_idx>>5) < m_bits.size() )
{
return( ( m_bits[_idx>>5] & (1<<(_idx&0x1f)) ) !=0 );
}
return false;
}
uint32 GetNumSetBits()const{ return m_numSetBits; }
class Iterator
{
friend class Bitfield;
public:
uint32 operator *() const
{
return m_idx;
}
Iterator& operator++()
{
NextSetBit();
return *this;
}
Iterator operator++(int)
{
Iterator tmp = *this;
++tmp;
return tmp;
}
bool operator ==(const Iterator &rhs)
{
return m_idx == rhs.m_idx;
}
bool operator !=(const Iterator &rhs)
{
return m_idx != rhs.m_idx;
}
private:
Iterator( Bitfield const* _bitfield, uint32 _idx ): m_idx( _idx ), m_bitfield( _bitfield )
{
if( ( _idx == 0 ) && ( !m_bitfield->IsSet(0) ) )
{
NextSetBit();
}
}
void NextSetBit()
{
while( ((++m_idx)>>5)<m_bitfield->m_bits.size() )
{
if( ( m_bitfield->m_bits[m_idx>>5] & ~((1<<(m_idx&0x1f))-1) ) == 0 )
{
m_idx = (m_idx&0xffffffe0)+31;
}
else
{
if( (m_bitfield->m_bits[m_idx>>5] & (1<<(m_idx&0x1f))) !=0 )
{
return;
}
}
}
}
uint32 m_idx;
Bitfield const* m_bitfield;
};
Iterator Begin()const{ return Iterator( this, 0 ); }
Iterator End()const{ return Iterator( this, (uint32) m_bits.size()<<5 ); }
private:
OPENZWAVE_EXPORT_WARNINGS_OFF
vector<uint32> m_bits;
OPENZWAVE_EXPORT_WARNINGS_ON
uint32 m_numSetBits;
};
}
#endif