mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
145 lines
2.3 KiB
C
145 lines
2.3 KiB
C
/**
|
|
* @require SIZE > 0
|
|
**/
|
|
module std::collections::bitset(<SIZE>);
|
|
|
|
def Type = uint;
|
|
|
|
const BITS = Type.sizeof * 8;
|
|
const SZ = (SIZE + BITS - 1) / BITS;
|
|
|
|
struct BitSet
|
|
{
|
|
Type[SZ] data;
|
|
}
|
|
|
|
fn usz BitSet.cardinality(&self)
|
|
{
|
|
usz n;
|
|
foreach (x : self.data)
|
|
{
|
|
n += x.popcount();
|
|
}
|
|
return n;
|
|
}
|
|
|
|
/**
|
|
* @require i < SIZE
|
|
**/
|
|
fn void BitSet.set(&self, usz i)
|
|
{
|
|
usz q = i / BITS;
|
|
usz r = i % BITS;
|
|
self.data[q] |= 1 << r;
|
|
}
|
|
|
|
/**
|
|
* @require i < SIZE
|
|
**/
|
|
fn void BitSet.unset(&self, usz i)
|
|
{
|
|
usz q = i / BITS;
|
|
usz r = i % BITS;
|
|
self.data[q] &= ~(1 << r);
|
|
}
|
|
|
|
/**
|
|
* @require i < SIZE
|
|
**/
|
|
fn bool BitSet.get(&self, usz i) @operator([]) @inline
|
|
{
|
|
usz q = i / BITS;
|
|
usz r = i % BITS;
|
|
return self.data[q] & (1 << r) != 0;
|
|
}
|
|
|
|
fn usz BitSet.len(&self) @operator(len) @inline
|
|
{
|
|
return SZ * BITS;
|
|
}
|
|
|
|
/**
|
|
* @require i < SIZE
|
|
**/
|
|
fn void BitSet.set_bool(&self, usz i, bool value) @operator([]=) @inline
|
|
{
|
|
if (value) return self.set(i);
|
|
self.unset(i);
|
|
}
|
|
|
|
/**
|
|
* @require Type.kindof == UNSIGNED_INT
|
|
**/
|
|
module std::collections::growablebitset(<Type>);
|
|
import std::collections::list;
|
|
|
|
const BITS = Type.sizeof * 8;
|
|
|
|
def GrowableBitSetList = List(<Type>);
|
|
|
|
struct GrowableBitSet
|
|
{
|
|
GrowableBitSetList data;
|
|
}
|
|
|
|
fn void GrowableBitSet.init(&self, usz initial_capacity = 1, Allocator* using = mem::heap())
|
|
{
|
|
self.data.init(initial_capacity, using);
|
|
}
|
|
|
|
fn void GrowableBitSet.tinit(&self)
|
|
{
|
|
self.init(.using = mem::temp());
|
|
}
|
|
|
|
fn usz GrowableBitSet.cardinality(&self)
|
|
{
|
|
usz n;
|
|
foreach (x : self.data)
|
|
{
|
|
n += x.popcount();
|
|
}
|
|
return n;
|
|
}
|
|
|
|
fn void GrowableBitSet.set(&self, usz i)
|
|
{
|
|
usz q = i / BITS;
|
|
usz r = i % BITS;
|
|
if (q >= self.data.len())
|
|
{
|
|
usz n = q + 1;
|
|
self.data.reserve(n);
|
|
self.data.size = n;
|
|
}
|
|
self.data.set(q, self.data[q] | (1 << r));
|
|
}
|
|
|
|
fn void GrowableBitSet.unset(&self, usz i)
|
|
{
|
|
usz q = i / BITS;
|
|
usz r = i % BITS;
|
|
if (q >= self.data.len()) return;
|
|
self.data.set(q, self.data[q] &~ (1 << r));
|
|
}
|
|
|
|
fn bool GrowableBitSet.get(&self, usz i) @operator([]) @inline
|
|
{
|
|
usz q = i / BITS;
|
|
usz r = i % BITS;
|
|
if (q >= self.data.len()) return false;
|
|
return self.data[q] & (1 << r) != 0;
|
|
}
|
|
|
|
fn usz GrowableBitSet.len(&self) @operator(len)
|
|
{
|
|
usz n = self.data.len() * BITS;
|
|
if (n > 0) n -= (usz)self.data[n - 1].ctz() - 1;
|
|
return n;
|
|
}
|
|
|
|
fn void GrowableBitSet.set_bool(&self, usz i, bool value) @operator([]=) @inline
|
|
{
|
|
if (value) return self.set(i);
|
|
self.unset(i);
|
|
} |