mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-27 06:10:34 +05:00
201 lines
4.0 KiB
C++
201 lines
4.0 KiB
C++
|
#ifndef NETGEN_CORE_BITARRAY
|
||
|
#define NETGEN_CORE_BITARRAY
|
||
|
|
||
|
/**************************************************************************/
|
||
|
/* File: bitarray.hpp */
|
||
|
/* Author: Joachim Schoeberl */
|
||
|
/* Date: 01. Jun. 95 */
|
||
|
/**************************************************************************/
|
||
|
|
||
|
#include <climits>
|
||
|
#include <cstring>
|
||
|
#include <ostream>
|
||
|
|
||
|
#include "archive.hpp"
|
||
|
#include "array.hpp"
|
||
|
#include "localheap.hpp"
|
||
|
#include "ngcore_api.hpp"
|
||
|
#include "utils.hpp"
|
||
|
|
||
|
namespace ngcore
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
A compressed array of bools.
|
||
|
|
||
|
Provides bit-operations and whole array operations.
|
||
|
*/
|
||
|
class BitArray
|
||
|
{
|
||
|
protected:
|
||
|
/// number of bits
|
||
|
size_t size;
|
||
|
|
||
|
/// the data
|
||
|
unsigned char * data;
|
||
|
///
|
||
|
bool owns_data = true;
|
||
|
public:
|
||
|
/// empty array
|
||
|
BitArray ()
|
||
|
: size(0), data(nullptr) { ; }
|
||
|
/// array of asize bits
|
||
|
NGCORE_API BitArray (size_t asize);
|
||
|
/// array of asize bits
|
||
|
NGCORE_API BitArray (size_t asize, LocalHeap & lh);
|
||
|
///
|
||
|
NGCORE_API BitArray (const BitArray & ba2);
|
||
|
BitArray (BitArray && ba2)
|
||
|
: size(ba2.size), data(ba2.data), owns_data(ba2.owns_data)
|
||
|
{
|
||
|
ba2.owns_data = false;
|
||
|
ba2.data = nullptr;
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
NETGEN_INLINE BitArray (std::initializer_list<T> list)
|
||
|
: BitArray (list.size())
|
||
|
{
|
||
|
Clear();
|
||
|
int cnt = 0;
|
||
|
for (auto i = list.begin(); i < list.end(); i++, cnt++)
|
||
|
if (*i) SetBit(cnt);
|
||
|
}
|
||
|
|
||
|
/// delete data
|
||
|
~BitArray ()
|
||
|
{
|
||
|
if (owns_data)
|
||
|
delete [] data;
|
||
|
}
|
||
|
|
||
|
/// Set size, loose values
|
||
|
NGCORE_API void SetSize (size_t asize);
|
||
|
|
||
|
/// the size
|
||
|
size_t Size () const { return size; }
|
||
|
|
||
|
/// set all bits
|
||
|
NGCORE_API BitArray & Set () throw();
|
||
|
|
||
|
/// clear all bits
|
||
|
NGCORE_API BitArray & Clear () throw();
|
||
|
|
||
|
/// set bit i
|
||
|
[[deprecated("Use either SetBit() or SetBitAtomic()")]]
|
||
|
void Set (size_t i) { SetBitAtomic(i); }
|
||
|
|
||
|
/// set bit i ( not thread safe )
|
||
|
void SetBit (size_t i)
|
||
|
{
|
||
|
NETGEN_CHECK_RANGE(i, 0, size);
|
||
|
data[Addr(i)] |= Mask(i);
|
||
|
}
|
||
|
|
||
|
/// set bit i ( thread safe )
|
||
|
void SetBitAtomic (size_t i)
|
||
|
{
|
||
|
NETGEN_CHECK_RANGE(i, 0, size);
|
||
|
unsigned char * p = data+Addr(i);
|
||
|
unsigned char mask = Mask(i);
|
||
|
|
||
|
AsAtomic(*p) |= mask;
|
||
|
}
|
||
|
|
||
|
/// clear bit i
|
||
|
void Clear (size_t i)
|
||
|
{
|
||
|
NETGEN_CHECK_RANGE(i, 0, size);
|
||
|
data[Addr(i)] &= ~Mask(i);
|
||
|
}
|
||
|
|
||
|
/// check bit i
|
||
|
bool Test (size_t i) const
|
||
|
{
|
||
|
NETGEN_CHECK_RANGE(i, 0, size);
|
||
|
return (data[Addr(i)] & Mask(i)) ? true : false;
|
||
|
}
|
||
|
|
||
|
/// set all bits to b
|
||
|
BitArray & operator= (bool b)
|
||
|
{
|
||
|
if (b) Set();
|
||
|
else Clear();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// check bit i
|
||
|
bool operator[] (size_t i) const
|
||
|
{
|
||
|
NETGEN_CHECK_RANGE(i, 0, size);
|
||
|
return Test(i);
|
||
|
}
|
||
|
|
||
|
|
||
|
/// invert all bits
|
||
|
NGCORE_API BitArray & Invert ();
|
||
|
|
||
|
/// logical AND with ba2
|
||
|
NGCORE_API BitArray & And (const BitArray & ba2);
|
||
|
|
||
|
/// logical OR with ba2
|
||
|
NGCORE_API BitArray & Or (const BitArray & ba2);
|
||
|
|
||
|
/// copy from ba2
|
||
|
NGCORE_API BitArray & operator= (const BitArray & ba2);
|
||
|
|
||
|
NGCORE_API size_t NumSet () const;
|
||
|
private:
|
||
|
///
|
||
|
unsigned char Mask (size_t i) const
|
||
|
{ return char(1) << (i % CHAR_BIT); }
|
||
|
|
||
|
///
|
||
|
size_t Addr (size_t i) const
|
||
|
{ return (i / CHAR_BIT); }
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
inline BitArray & operator|= (BitArray & me, const BitArray & you)
|
||
|
{
|
||
|
me.Or(you);
|
||
|
return me;
|
||
|
}
|
||
|
|
||
|
inline BitArray & operator&= (BitArray & me, const BitArray & you)
|
||
|
{
|
||
|
me.And(you);
|
||
|
return me;
|
||
|
}
|
||
|
|
||
|
inline BitArray operator| (const BitArray & a, const BitArray & b)
|
||
|
{
|
||
|
BitArray res = a;
|
||
|
res |= b;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
inline BitArray operator& (const BitArray & a, const BitArray & b)
|
||
|
{
|
||
|
BitArray res = a;
|
||
|
res &= b;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
inline BitArray operator~ (const BitArray & a)
|
||
|
{
|
||
|
BitArray res = a;
|
||
|
res.Invert();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
|
||
|
NGCORE_API std::ostream & operator<<(std::ostream & s, const BitArray & ba);
|
||
|
|
||
|
NGCORE_API Archive & operator & (Archive & archive, BitArray & ba);
|
||
|
|
||
|
} // namespace ngcore
|
||
|
|
||
|
#endif // NETGEN_CORE_BITARRAY
|