/*
elmo - ELectronic Mail Operator
Copyright (C) 2003 rzyjontko
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
----------------------------------------------------------------------
This file contains an implementation of bitarrays - arrays of bits,
efficient representation of sets.
*/
/****************************************************************************
* IMPLEMENTATION HEADERS
****************************************************************************/
#include <stdio.h>
#include "bitarray.h"
#include "xmalloc.h"
/****************************************************************************
* IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE DATA
****************************************************************************/
/****************************************************************************
* INTERFACE DATA
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTIONS
****************************************************************************/
static void
print_int (int a)
{
printf (" %d", a);
}
/****************************************************************************
* INTERFACE FUNCTIONS
****************************************************************************/
bitarray_t *
bitarray_create (int bits)
{
bitarray_t *result;
if (bits == 0)
return NULL;
result = xmalloc (sizeof (bitarray_t));
result->bits = bits;
result->size = (bits - 1) / 32 + 1;
result->array = xmalloc (result->size * 4);
return result;
}
bitarray_t *
bitarray_reverse (bitarray_t *b)
{
int i;
bitarray_t *result;
result = bitarray_create (b->bits);
bitarray_ones (result);
for (i = 0; i < result->size; i++)
result->array[i] ^= b->array[i];
return result;
}
void
bitarray_resize (bitarray_t *a, int bits)
{
int size;
a->bits = bits;
size = (bits - 1) / 32 + 1;
if (size > a->size){
a->size = size;
a->array = xrealloc (a->array, size * 4);
}
}
void
bitarray_remove (bitarray_t *a, int index)
{
if (bitarray_is_set (a, a->bits - 1))
bitarray_set (a, index);
else
bitarray_unset (a, index);
a->bits--;
}
void
bitarray_destroy (bitarray_t *a)
{
if (a == NULL)
return;
if (a && a->array)
xfree (a->array);
if (a)
xfree (a);
}
void
bitarray_zeros (bitarray_t *a)
{
int i;
if (a == NULL)
return;
for (i = 0; i < a->size; i++)
a->array[i] = 0;
}
void
bitarray_ones (bitarray_t *a)
{
int i;
if (a == NULL)
return;
for (i = 0; i < a->size; i++)
a->array[i] = ~ 0;
}
void
bitarray_set (bitarray_t *a, int bit)
{
if (a == NULL)
return;
if (bit > a->bits)
return;
a->array[bit / 32] |= (1 << (bit % 32));
}
void
bitarray_unset (bitarray_t *a, int bit)
{
if (a == NULL)
return;
if (bit > a->bits)
return;
a->array[bit / 32] &= ~ (1 << (bit % 32));
}
void
bitarray_change_bit (bitarray_t *a, int bit)
{
if (a == NULL)
return;
if (bit > a->bits)
return;
a->array[bit / 32] ^= (1 << (bit % 32));
}
void
bitarray_neg (bitarray_t *a)
{
int i;
for (i = 0; i < a->size; i++)
a->array[i] ^= ~ 0;
}
void
bitarray_sum (bitarray_t *a, bitarray_t *b)
{
int i;
for (i = 0; i < a->size; i++)
a->array[i] |= b->array[i];
}
void
bitarray_intersect (bitarray_t *a, bitarray_t *b)
{
int i;
for (i = 0; i < a->size; i++)
a->array[i] &= b->array[i];
}
void
bitarray_subtract (bitarray_t *a, bitarray_t *b)
{
int i;
for (i = 0; i < a->size; i++)
a->array[i] &= ~ b->array[i];
}
int
bitarray_equal (bitarray_t *a, bitarray_t *b)
{
int i;
for (i = 0; i < a->size; i++)
if (a->array[i] != b->array[i])
return 0;
return 1;
}
void
bitarray_copy (bitarray_t *to, bitarray_t *from)
{
int i;
for (i = 0; i < to->size; i++)
to->array[i] = from->array[i];
}
int
bitarray_is_set (bitarray_t *a, int bit)
{
if (a && a->array){
return a->array[bit / 32] & (1 << (bit % 32));
}
else
return 0;
}
void
bitarray_for_ones (bitarray_t *a, void (*fun)(int))
{
int i, j;
if (a == NULL)
return;
for (i = 0; i < a->size; i++){
for (j = 0; j < 32 && 32 * i + j < a->bits; j++){
if ((a->array[i] & (1 << j)) != 0)
fun (32 * i + j);
}
}
}
void
bitarray_print (bitarray_t *a)
{
bitarray_for_ones (a, print_int);
printf ("\n");
}
int
bitarray_ones_count (bitarray_t *a)
{
unsigned x;
int i;
int result = 0;
for (i = 0; i < a->size; i++){
x = a->array[i];
while (x){
x &= x - 1;
result++;
}
}
return result;
}
int
bitarray_true_for_all (bitarray_t *a, int (*fun)(int))
{
int i;
int j;
for (i = 0; i < a->size; i++){
for (j = 0; j < 32 && 32 * i + j < a->bits; j++){
if ((a->array[i] & (1 << j)) != 0)
if (! fun (32 * i + j))
return 0;
}
}
return 1;
}
int
bitarray_first_set (bitarray_t *a)
{
int i;
int j;
for (i = 0; i < a->size; i++){
for (j = 0; j < 32 && 32 * i + j < a->bits; j++){
if ((a->array[i] & (1 << j)) != 0)
return 32 * i + j;
}
}
return -1;
}
int
bitarray_none_is_set (bitarray_t *a)
{
int i;
for (i = 0; i < a->size; i++){
if (a->array[i])
break;
}
return i == a->size;
}
/****************************************************************************
* INTERFACE CLASS BODIES
****************************************************************************/
/****************************************************************************
*
* END MODULE bitarray.c
*
****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1