2019-08-28 17:10:09 +05:00
|
|
|
/**************************************************************************/
|
|
|
|
/* File: bitarray.cpp */
|
|
|
|
/* Autho: Joachim Schoeberl */
|
|
|
|
/* Date: 01. Jun. 95 */
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
data type BitArray
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "bitarray.hpp"
|
|
|
|
|
|
|
|
namespace ngcore
|
|
|
|
{
|
|
|
|
BitArray :: BitArray (size_t asize)
|
|
|
|
{
|
|
|
|
size = 0;
|
|
|
|
data = NULL;
|
|
|
|
SetSize (asize);
|
|
|
|
}
|
|
|
|
|
|
|
|
BitArray :: BitArray (size_t asize, LocalHeap & lh)
|
|
|
|
{
|
|
|
|
size = asize;
|
|
|
|
data = new (lh) unsigned char [Addr (size)+1];
|
|
|
|
owns_data = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
BitArray :: BitArray (const BitArray & ba2)
|
|
|
|
{
|
|
|
|
size = 0;
|
|
|
|
data = NULL;
|
|
|
|
(*this) = ba2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitArray :: SetSize (size_t asize)
|
|
|
|
{
|
|
|
|
if (size == asize) return;
|
|
|
|
if (owns_data) delete [] data;
|
|
|
|
|
|
|
|
size = asize;
|
|
|
|
data = new unsigned char [Addr (size)+1];
|
|
|
|
}
|
|
|
|
|
|
|
|
BitArray & BitArray :: Set () throw()
|
|
|
|
{
|
|
|
|
if (!size) return *this;
|
|
|
|
for (size_t i = 0; i <= Addr (size); i++)
|
|
|
|
data[i] = UCHAR_MAX;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
BitArray & BitArray :: Clear () throw()
|
|
|
|
{
|
|
|
|
if (!size) return *this;
|
|
|
|
for (size_t i = 0; i <= Addr (size); i++)
|
|
|
|
data[i] = 0;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
BitArray & BitArray :: Invert ()
|
|
|
|
{
|
|
|
|
if (!size) return *this;
|
|
|
|
for (size_t i = 0; i <= Addr (size); i++)
|
|
|
|
data[i] ^= 255;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
BitArray & BitArray :: And (const BitArray & ba2)
|
|
|
|
{
|
|
|
|
if (!size) return *this;
|
|
|
|
for (size_t i = 0; i <= Addr (size); i++)
|
|
|
|
data[i] &= ba2.data[i];
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BitArray & BitArray :: Or (const BitArray & ba2)
|
|
|
|
{
|
|
|
|
if (!size) return *this;
|
|
|
|
for (size_t i = 0; i <= Addr (size); i++)
|
|
|
|
data[i] |= ba2.data[i];
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2020-08-29 18:37:48 +05:00
|
|
|
bool BitArray :: operator==(const BitArray& other) const
|
|
|
|
{
|
|
|
|
if(size != other.Size())
|
|
|
|
return false;
|
|
|
|
for(auto i : Range(size/CHAR_BIT))
|
|
|
|
if(data[i] != other.data[i])
|
|
|
|
return false;
|
|
|
|
for(auto i : Range(size%CHAR_BIT))
|
2020-09-11 19:54:25 +05:00
|
|
|
if(Test(i + CHAR_BIT * (size/CHAR_BIT)) != other.Test(i + CHAR_BIT * (size/CHAR_BIT)))
|
2020-08-29 18:37:48 +05:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
2019-08-28 17:10:09 +05:00
|
|
|
|
|
|
|
BitArray & BitArray :: operator= (const BitArray & ba2)
|
|
|
|
{
|
|
|
|
SetSize (ba2.Size());
|
|
|
|
if (!size)
|
|
|
|
return *this;
|
|
|
|
for (size_t i = 0; i <= Addr (size); i++)
|
|
|
|
data[i] = ba2.data[i];
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostream & operator<<(std::ostream & s, const BitArray & ba)
|
|
|
|
{
|
|
|
|
size_t n = ba.Size();
|
|
|
|
for (size_t i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
if (i % 50 == 0) s << i << ": ";
|
|
|
|
s << int(ba[i]);
|
|
|
|
if (i % 50 == 49) s << "\n";
|
|
|
|
}
|
|
|
|
s << std::flush;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t BitArray :: NumSet () const
|
|
|
|
{
|
|
|
|
size_t cnt = 0;
|
|
|
|
for (size_t i = 0; i < Size(); i++)
|
|
|
|
if (Test(i)) cnt++;
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
2020-08-29 18:37:48 +05:00
|
|
|
void BitArray :: DoArchive(Archive& archive)
|
2019-08-28 17:10:09 +05:00
|
|
|
{
|
2020-08-29 18:37:48 +05:00
|
|
|
if(archive.GetVersion("netgen") >= "v6.2.2007-62")
|
2019-08-28 17:10:09 +05:00
|
|
|
{
|
2020-08-29 18:37:48 +05:00
|
|
|
archive.NeedsVersion("netgen", "v6.2.2007-62");
|
|
|
|
auto size = Size();
|
|
|
|
archive & size;
|
|
|
|
if(archive.Input())
|
|
|
|
SetSize(size);
|
|
|
|
archive.Do(data, size/CHAR_BIT+1);
|
2019-08-28 17:10:09 +05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-29 18:37:48 +05:00
|
|
|
if (archive.Output())
|
2019-08-28 17:10:09 +05:00
|
|
|
{
|
2020-08-29 18:37:48 +05:00
|
|
|
throw Exception("should not get here");
|
|
|
|
archive << Size();
|
|
|
|
for (size_t i = 0; i < Size(); i++)
|
|
|
|
archive << (*this)[i];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
archive & size;
|
|
|
|
SetSize (size);
|
|
|
|
Clear();
|
|
|
|
for (size_t i = 0; i < size; i++)
|
|
|
|
{
|
|
|
|
bool b;
|
|
|
|
archive & b;
|
|
|
|
if (b) SetBit(i);
|
|
|
|
}
|
2019-08-28 17:10:09 +05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-29 18:37:48 +05:00
|
|
|
} // namespace ngcore
|