Graphviz 12.0.1~dev.20240716.0800
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 <cgraph/alloc.h>
27#include <inttypes.h>
28#include <stdbool.h>
29#include <stdint.h>
30#include <stdlib.h>
31#include <string.h>
32
38typedef struct {
39 union {
40 uint8_t block[sizeof(uint8_t *)];
41 uint8_t *base;
42 } u;
43 size_t size_bits;
45
47static inline bitarray_t bitarray_new(size_t size_bits) {
48
49 bitarray_t ba = {.size_bits = size_bits};
50
51 // if the array is small enough, we can use inline storage
52 if (size_bits <= sizeof(ba.u.block) * 8) {
53 // nothing to be done
54
55 // otherwise we need to heap-allocate
56 } else {
57 size_t capacity = size_bits / 8 + (size_bits % 8 == 0 ? 0 : 1);
58 ba.u.base = gv_calloc(capacity, sizeof(uint8_t));
59 }
60
61 return ba;
62}
63
65static inline bool bitarray_get(bitarray_t self, size_t index) {
66 assert(index < self.size_bits && "out of bounds access");
67
68 // determine if this array is stored inline or not
69 const uint8_t *base;
70 if (self.size_bits <= sizeof(self.u.block) * 8) {
71 base = self.u.block;
72 } else {
73 base = self.u.base;
74 }
75
76 return (base[index / 8] >> (index % 8)) & 1;
77}
78
80static inline void bitarray_set(bitarray_t *self, size_t index, bool value) {
81 assert(index < self->size_bits && "out of bounds access");
82
83 // determine if this array is stored inline or not
84 uint8_t *base;
85 if (self->size_bits <= sizeof(self->u.block) * 8) {
86 base = self->u.block;
87 } else {
88 base = self->u.base;
89 }
90
91 if (value) {
92 base[index / 8] |= (uint8_t)(UINT8_C(1) << (index % 8));
93 } else {
94 base[index / 8] &= (uint8_t) ~(UINT8_C(1) << (index % 8));
95 }
96}
97
99static inline void bitarray_reset(bitarray_t *self) {
100 assert(self != NULL);
101
102 // is this array stored out of line?
103 if (self->size_bits > sizeof(self->u.block) * 8)
104 free(self->u.base);
105
106 memset(self, 0, sizeof(*self));
107}
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:47
static bool bitarray_get(bitarray_t self, size_t index)
get the value of the given element
Definition bitarray.h:65
static void bitarray_set(bitarray_t *self, size_t index, bool value)
set or clear the value of the given element
Definition bitarray.h:80
static void bitarray_reset(bitarray_t *self)
free underlying resources and leave a bit array empty
Definition bitarray.h:99
void free(void *)
node NULL
Definition grammar.y:149
uint8_t block[sizeof(uint8_t *)]
inline storage for small arrays
Definition bitarray.h:40
union bitarray_t::@61 u
size_t size_bits
extent in bits
Definition bitarray.h:43
uint8_t * base
start of the underlying allocated buffer
Definition bitarray.h:41
Definition block.h:26