75 lines (60 with data), 1.3 kB
/*
Similar to the old efuns
except uses an array of ints for the bits.
Automatically extended truncated etc.
*/
array empty = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
];
#define INT_LENGTH 30 /* 32 gives negative numbers :( */
int test_bit(array a, int bit) {
int x = bit / INT_LENGTH,
y = bit % INT_LENGTH;
if (sizeof(a) < x)
return 0;
else
return (a[x] & (1 << y))?1:0;
}
/* returns a NEW array */
array
set_bit((int|array) a, int bit, int value)
{
array res;
int x = bit / INT_LENGTH, y = bit % INT_LENGTH, r;
if (!a) res = [ ];
else res = a + [ ]; /* force a copy - blech */
if (sizeof(res) <= x) { /* extend */
r = x - sizeof(res);
res = res + empty[..r];
}
if (value) res[x] = res[x] | (1 << y);
else {
res[x] = res[x] & (~(1 << y));
/* truncate if necessary */
for (r = sizeof(res) - 1; r >= 0 && (!res[r]); r--) { }
res = res[..r];
}
return res;
}
query_size (array a) {
return sizeof (a) * INT_LENGTH;
}
#if 0
test()
{
array b;
b = set_bit(b, 16, 1);
b = set_bit(b, 32, 1);
return b;
}
btt()
{
return 1 << 31;
}
bt()
{
return 8 >> 2;
}
#endif