/******************************************************************************** ** *A bitarray.h bit arrays J. D. Mitchell ** ** Copyright (C) 2019 - J. D. Mitchell ** ** This file is free software, see the digraphs/LICENSE. **
********************************************************************************/
// C headers #include <limits.h> // for CHAR_BIT #include <stdbool.h> // for bool #include <stddef.h> // for size_t #include <stdint.h> // for uint16_t #include <string.h> // for memset
// GAP headers #include"gap-includes.h"// for COUNT_TRUES_BLOCKS, Obj, . . .
// Digraphs headers #include"digraphs-debug.h"// for DIGRAPHS_ASSERT
struct bit_array_struct {
uint16_t nr_bits; // number of bits
uint16_t nr_blocks; // number of blocks
Block* blocks; // the blocks themselves
};
typedefstruct bit_array_struct BitArray;
//! New BitArray with space for \p nr_bits bits, and with every bit set to \c //! false.
BitArray* new_bit_array(uint16_t const nr_bits);
//! Free all the memory associated with a BitArray false. void free_bit_array(BitArray* const);
//! Set every value in the BitArray pointed to by \p bit_array to the value \p //! val. staticinlinevoid init_bit_array(BitArray* const bit_array, boolconst val,
uint16_t const nr_bits) {
DIGRAPHS_ASSERT(bit_array != NULL);
DIGRAPHS_ASSERT(nr_bits <= bit_array->nr_bits);
//! Set position \p pos in the BitArray pointed to by \p bit_array //! to the value \p val. staticinlinevoid
set_bit_array(BitArray* const bit_array, uint16_t const pos, boolconst val) {
DIGRAPHS_ASSERT(bit_array != NULL);
DIGRAPHS_ASSERT(pos < bit_array->nr_bits); if (val) {
bit_array->blocks[quotient_lookup(pos)] |=
mask_lookup(remainder_lookup(pos));
} else {
bit_array->blocks[quotient_lookup(pos)] &=
~mask_lookup(remainder_lookup(pos));
}
}
//! Get the value in position \p pos of the BitArray pointer //! \p bit_array. staticinlinebool get_bit_array(BitArray const* const bit_array,
uint16_t const pos) {
DIGRAPHS_ASSERT(bit_array != NULL);
DIGRAPHS_ASSERT(pos < bit_array->nr_bits); return bit_array->blocks[quotient_lookup(pos)]
& mask_lookup(remainder_lookup(pos));
}
//! Intersect the BitArray's pointed to by \p bit_array1 and \p bit_array2. The //! BitArray pointed to by \p bit_array1 is changed in place! staticinlinevoid intersect_bit_arrays(BitArray* const bit_array1,
BitArray const* const bit_array2,
uint16_t const nr_bits) {
DIGRAPHS_ASSERT(bit_array1 != NULL);
DIGRAPHS_ASSERT(bit_array2 != NULL);
DIGRAPHS_ASSERT(bit_array1->nr_bits == bit_array2->nr_bits);
DIGRAPHS_ASSERT(bit_array1->nr_blocks == bit_array2->nr_blocks);
DIGRAPHS_ASSERT(nr_bits <= bit_array1->nr_bits);
DIGRAPHS_ASSERT(nr_bits <= bit_array2->nr_bits);
uint16_t const nr_blocks = number_of_blocks(nr_bits); for (uint16_t i = 0; i < nr_blocks; i++) {
bit_array1->blocks[i] &= bit_array2->blocks[i];
}
}
//! Union the BitArray's pointed to by \p bit_array1 and \p bit_array2. The //! BitArray pointed to by \p bit_array1 is changed in place! staticinlinevoid union_bit_arrays(BitArray* const bit_array1,
BitArray const* const bit_array2,
uint16_t const nr_bits) {
DIGRAPHS_ASSERT(bit_array1 != NULL);
DIGRAPHS_ASSERT(bit_array2 != NULL);
DIGRAPHS_ASSERT(bit_array1->nr_bits == bit_array2->nr_bits);
DIGRAPHS_ASSERT(bit_array1->nr_blocks == bit_array2->nr_blocks);
DIGRAPHS_ASSERT(nr_bits <= bit_array1->nr_bits);
DIGRAPHS_ASSERT(nr_bits <= bit_array2->nr_bits);
uint16_t const nr_blocks = number_of_blocks(nr_bits); for (uint16_t i = 0; i < nr_blocks; i++) {
bit_array1->blocks[i] |= bit_array2->blocks[i];
}
}
//! Sets \p bit_array1 to be 0 in every position that \p bit_array2 is 1. staticinlinevoid complement_bit_arrays(BitArray* const bit_array1,
BitArray const* const bit_array2,
uint16_t const nr_bits) {
DIGRAPHS_ASSERT(bit_array1 != NULL);
DIGRAPHS_ASSERT(bit_array2 != NULL);
DIGRAPHS_ASSERT(bit_array1->nr_bits == bit_array2->nr_bits);
DIGRAPHS_ASSERT(bit_array1->nr_blocks == bit_array2->nr_blocks);
DIGRAPHS_ASSERT(nr_bits <= bit_array1->nr_bits);
DIGRAPHS_ASSERT(nr_bits <= bit_array2->nr_bits);
uint16_t const nr_blocks = number_of_blocks(nr_bits); for (uint16_t i = 0; i < nr_blocks; i++) {
bit_array1->blocks[i] &= ~bit_array2->blocks[i];
}
}
//! This function copies \p bit_array2 into \p bit_array1 staticinlinevoid copy_bit_array(BitArray* const bit_array1,
BitArray const* const bit_array2,
uint16_t const nr_bits) {
DIGRAPHS_ASSERT(bit_array1 != NULL);
DIGRAPHS_ASSERT(bit_array2 != NULL);
DIGRAPHS_ASSERT(bit_array1->nr_bits == bit_array2->nr_bits);
DIGRAPHS_ASSERT(bit_array1->nr_blocks == bit_array2->nr_blocks);
DIGRAPHS_ASSERT(nr_bits <= bit_array1->nr_bits);
DIGRAPHS_ASSERT(nr_bits <= bit_array2->nr_bits);
uint16_t const nr_blocks = number_of_blocks(nr_bits); for (uint16_t i = 0; i < nr_blocks; i++) {
bit_array1->blocks[i] = bit_array2->blocks[i];
}
}
//! Return the number of set bits among the first \p nr_bits of \p bit_array. staticinline uint16_t size_bit_array(BitArray const* const bit_array,
uint16_t const nr_bits) {
DIGRAPHS_ASSERT(bit_array != NULL);
DIGRAPHS_ASSERT(nr_bits <= bit_array->nr_bits);
Block const* blocks = bit_array->blocks;
uint16_t const nr_blocks = number_of_blocks(nr_bits); return COUNT_TRUES_BLOCKS(blocks, nr_blocks);
}
//! Set the bit array \p bit_array to be \c true in position INT_INTOBJ(o) - 1. void set_bit_array_from_gap_int(BitArray* const bit_array, Obj o);
//! Set the bit array \p bit_array to be \c true for every integer valyue in //! \p list_obj (which should be a list consisting of integers, not necessarily //! plain or dense). void set_bit_array_from_gap_list(BitArray* const bit_array, Obj list_obj);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.