ref: ea47856f32ee8063d5fe7eb3b1fe5b6094320db2
dir: /bitvector.c/
/* bit vector primitives todo: * reverse * nreverse (- rotate left/right) * shl_to * not - shr_row, shl_row These routines are the back end supporting bit matrices. Many operations on bit matrices are slow (such as accessing or setting a single element!) but certain operations are privileged and lend themselves to extremely efficient implementation due to the bit-vector nature of machine integers. These are: done: & | $ ~ copy reverse fill sum prod todo: shift trans rowswap would be nice: channel interleave Important note: Out-of-place functions always assume dest and source have the same amount of space available. shr_to, shl_to, not_to, and reverse_to assume source and dest don't overlap and_to, or_to, and xor_to allow overlap. */ #include "llt.h" uint32_t * bitvector_resize(uint32_t *b, uint64_t oldsz, uint64_t newsz, int initzero) { uint32_t *p; size_t sz = ((newsz+31)>>5) * sizeof(uint32_t); p = LLT_REALLOC(b, sz); if(p == nil) return nil; if(initzero && newsz>oldsz){ size_t osz = ((oldsz+31)>>5) * sizeof(uint32_t); memset(&p[osz/sizeof(uint32_t)], 0, sz-osz); } return p; } uint32_t * bitvector_new(uint64_t n, int initzero) { return bitvector_resize(nil, 0, n, initzero); } size_t bitvector_nwords(uint64_t nbits) { return (nbits+31)>>5; } void bitvector_set(uint32_t *b, uint64_t n, uint32_t c) { if(c) b[n>>5] |= 1U<<(n&31); else b[n>>5] &= ~(1U<<(n&31)); } uint32_t bitvector_get(uint32_t *b, uint64_t n) { return b[n>>5] & (1U<<(n&31)); }