Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
bitarray.h
Go to the documentation of this file.
1
22
23#pragma once
24
25#include <assert.h>
26#include <inttypes.h>
27#include <stdbool.h>
28#include <stdint.h>
29#include <stdlib.h>
30#include <util/alloc.h>
31
37typedef struct {
38 union {
39 uint8_t block[sizeof(uint8_t *)];
40 uint8_t *base;
41 } u;
42 size_t size_bits;
44
46static inline bitarray_t bitarray_new(size_t size_bits) {
47
48 bitarray_t ba = {.size_bits = size_bits};
49
50 // if the array is small enough, we can use inline storage
51 if (size_bits <= sizeof(ba.u.block) * 8) {
52 // nothing to be done
53
54 // otherwise we need to heap-allocate
55 } else {
56 size_t capacity = size_bits / 8 + (size_bits % 8 == 0 ? 0 : 1);
57 ba.u.base = gv_calloc(capacity, sizeof(uint8_t));
58 }
59
60 return ba;
61}
62
64static inline bool bitarray_get(bitarray_t self, size_t index) {
65 assert(index < self.size_bits && "out of bounds access");
66
67 // determine if this array is stored inline or not
68 const uint8_t *base;
69 if (self.size_bits <= sizeof(self.u.block) * 8) {
70 base = self.u.block;
71 } else {
72 base = self.u.base;
73 }
74
75 return (base[index / 8] >> (index % 8)) & 1;
76}
77
79static inline void bitarray_set(bitarray_t *self, size_t index, bool value) {
80 assert(index < self->size_bits && "out of bounds access");
81
82 // determine if this array is stored inline or not
83 uint8_t *base;
84 if (self->size_bits <= sizeof(self->u.block) * 8) {
85 base = self->u.block;
86 } else {
87 base = self->u.base;
88 }
89
90 if (value) {
91 base[index / 8] |= (uint8_t)(UINT8_C(1) << (index % 8));
92 } else {
93 base[index / 8] &= (uint8_t)~(UINT8_C(1) << (index % 8));
94 }
95}
96
98static inline void bitarray_reset(bitarray_t *self) {
99 assert(self != NULL);
100
101 // is this array stored out of line?
102 if (self->size_bits > sizeof(self->u.block) * 8)
103 free(self->u.base);
104
105 *self = (bitarray_t){0};
106}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
static bitarray_t bitarray_new(size_t size_bits)
create an array of the given element length
Definition bitarray.h:46
static bool bitarray_get(bitarray_t self, size_t index)
get the value of the given element
Definition bitarray.h:64
static void bitarray_set(bitarray_t *self, size_t index, bool value)
set or clear the value of the given element
Definition bitarray.h:79
static void bitarray_reset(bitarray_t *self)
free underlying resources and leave a bit array empty
Definition bitarray.h:98
void free(void *)
node NULL
Definition grammar.y:163
uint8_t block[sizeof(uint8_t *)]
inline storage for small arrays
Definition bitarray.h:39
size_t size_bits
extent in bits
Definition bitarray.h:42
union bitarray_t::@123 u
uint8_t * base
start of the underlying allocated buffer
Definition bitarray.h:40
Definition block.h:26