BRL-CAD
Loading...
Searching...
No Matches
bitv.h
Go to the documentation of this file.
1/* B I T V . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2026 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20
21#ifndef BU_BITV_H
22#define BU_BITV_H
23
24#include "common.h"
25
26#include "bu/defines.h"
27#include "bu/magic.h"
28#include "bu/list.h"
29#include "bu/vls.h"
30
32
33/*----------------------------------------------------------------------*/
34/** @addtogroup bu_bitv
35 *
36 * @brief
37 * Routines for managing efficient high-performance bit vectors of
38 * arbitrary length.
39 *
40 * The basic type "bitv_t" is defined in include/bu.h; it is the
41 * widest integer datatype for which efficient hardware support
42 * exists. BU_BITV_SHIFT and BU_BITV_MASK are also defined in bu.h
43 *
44 * These bit vectors are "little endian", bit 0 is in the right hand
45 * side of the [0] word.
46 *
47 */
48/** @{*/
49/** @file bu/bitv.h */
50
51/**
52 * bitv_t should be a fast integer type for implementing bit vectors.
53 *
54 * On many machines, this is a 32-bit "long", but on some machines a
55 * compiler/vendor-specific type such as "long long" or even 'char'
56 * can give access to faster integers.
57 *
58 * THE SIZE OF bitv_t MUST MATCH BU_BITV_SHIFT.
59 */
60#include <stdint.h>
62
63/**
64 * Bit vector shift size
65 *
66 * Should equal to: log2(sizeof(bitv_t)*8.0). Using bu_bitv_shift()
67 * will return a run-time computed shift size if the size of a bitv_t
68 * changes. Performance impact is rather minimal for most models but
69 * disabled for a handful of primitives that heavily rely on bit
70 * vectors.
71 *
72 * (8-bit type: 3, 16-bit type: 4, 32-bit type: 5, 64-bit type: 6)
73 */
74#define BU_BITV_SHIFT 6
75
76/** Bit vector mask */
77#define BU_BITV_MASK ((1<<BU_BITV_SHIFT)-1)
78
79/**
80 * Bit vector data structure.
81 *
82 * bu_bitv uses a little-endian encoding, placing bit 0 on the right
83 * side of the 0th word.
84 *
85 * This is done only because left-shifting a 1 can be done in an
86 * efficient word-length-independent manner; going the other way would
87 * require a compile-time constant with only the sign bit set, and an
88 * unsigned right shift, which some machines don't have in hardware,
89 * or an extra subtraction.
90 *
91 * Application code should *never* peek at the bit-buffer; use the
92 * macros. The external hex form is most significant byte first (bit
93 * 0 is at the right). Note that MUVES does it differently.
94 */
95struct bu_bitv {
96 struct bu_list l; /**< linked list for caller's use */
97 size_t nbits; /**< actual size of bits[], in bits */
98 bitv_t bits[1]; /**< variable size array */
99};
100typedef struct bu_bitv bu_bitv_t;
101#define BU_BITV_NULL ((struct bu_bitv *)0)
102
103/**
104 * asserts the integrity of a non-head node bu_bitv struct.
105 */
106#define BU_CK_BITV(_bp) BU_CKMAG(_bp, BU_BITV_MAGIC, "bu_bitv")
107
108/**
109 * Initializes a bu_bitv struct without allocating any memory.
110 * This macro is not suitable for initializing a head list node.
111 *
112 * Because struct bu_bitv embeds one full @c bitv_t word (currently
113 * 64 bits) inline, a stack-allocated instance already provides 64
114 * usable bits without any heap allocation. Callers that need at most
115 * 64 bits can avoid bu_bitv_new() entirely:
116 *
117 * @code
118 * struct bu_bitv bv;
119 * BU_BITV_INIT(&bv);
120 * BU_BITSET(&bv, 3);
121 * if (BU_BITTEST(&bv, 3)) { ... }
122 * // no bu_bitv_free() needed -- stack memory
123 * @endcode
124 *
125 * nbits is set to sizeof(bitv_t)*8 (64) to reflect the capacity
126 * actually available in the embedded bits[1] field.
127 */
128#define BU_BITV_INIT(_bp) { \
129 BU_LIST_INIT_MAGIC(&(_bp)->l, BU_BITV_MAGIC); \
130 (_bp)->nbits = sizeof(bitv_t) * 8; \
131 (_bp)->bits[0] = 0; \
132 }
133
134/**
135 * Macro suitable for declaration-statement initialization of a bu_bitv
136 * struct on the stack or as a static/global. Does not allocate memory
137 * and is not suitable for a head node.
138 *
139 * The initialized vector has 64 bits of usable capacity matching the
140 * embedded bits[1] storage. Example:
141 *
142 * @code
143 * struct bu_bitv bv = BU_BITV_INIT_ZERO;
144 * BU_BITSET(&bv, 7);
145 * @endcode
146 */
147#define BU_BITV_INIT_ZERO { {BU_BITV_MAGIC, BU_LIST_NULL, BU_LIST_NULL}, sizeof(bitv_t)*8, {0} }
148
149/**
150 * returns truthfully whether a bu_bitv has been initialized
151 */
152#define BU_BITV_IS_INITIALIZED(_bp) (((struct bu_bitv *)(_bp) != BU_BITV_NULL) && LIKELY((_bp)->l.magic == BU_BITV_MAGIC))
153
154/**
155 * returns floor(log2(sizeof(bitv_t)*8.0)), i.e. the number of bits
156 * required with base-2 encoding to index any bit in an array of
157 * length sizeof(bitv_t)*8.0 bits long. users should not call this
158 * directly, instead calling the BU_BITV_SHIFT macro instead.
159 */
160BU_EXPORT extern size_t bu_bitv_shift(void);
161
162/**
163 * Convert a number of words into the corresponding (bitv_t type) size
164 * as a bit-vector size.
165 */
166#define BU_WORDS2BITS(_nw) ((size_t)(_nw>0?_nw:0)*sizeof(bitv_t)*8)
167
168/**
169 * Convert a bit-vector (stored in a bitv_t array) size into the
170 * corresponding word size.
171 */
172#define BU_BITS2WORDS(_nb) (((size_t)(_nb>0?_nb:0)+BU_BITV_MASK)>>BU_BITV_SHIFT)
173
174/**
175 * Convert a bit-vector (stored in a bitv_t array) size into the
176 * corresponding total memory size (in bytes) of the bitv_t array.
177 */
178#define BU_BITS2BYTES(_nb) (BU_BITS2WORDS(_nb)*sizeof(bitv_t))
179
180BU_EXPORT extern void bu_bitv_set(struct bu_bitv *bv, size_t bit);
181BU_EXPORT extern void bu_bitv_clear_bit(struct bu_bitv *bv, size_t bit);
182BU_EXPORT extern int bu_bitv_test(const struct bu_bitv *bv, size_t bit);
183BU_EXPORT extern size_t bu_bitv_length(const struct bu_bitv *bv);
184
185/* Set bit. bitv_t is an unsigned integer.
186 * NOTE: assumes user has performed bounds checking
187 */
188#define BU_BITSET(_bv, bit) \
189 ((_bv)->bits[(bit)>>BU_BITV_SHIFT] |= (((bitv_t)1)<<((bit)&BU_BITV_MASK)))
190
191#define BU_BITCLR(_bv, bit) \
192 ((_bv)->bits[(bit)>>BU_BITV_SHIFT] &= ~(((bitv_t)1)<<((bit)&BU_BITV_MASK)))
193
194/* True if bit is set.
195 * NOTE: assumes user has performed bounds checking
196 */
197#define BU_BITTEST(_bv, bit) \
198 (((_bv)->bits[(bit)>>BU_BITV_SHIFT] & (((bitv_t)1)<<((bit)&BU_BITV_MASK)))!=0)
199
200/**
201 * zeros all of the internal storage bytes in a bit vector array
202 */
203#define BU_BITV_ZEROALL(_bv) bu_bitv_clear(_bv)
204
205
206/* This is not done by default for performance reasons */
207#ifdef NO_BOMBING_MACROS
208# define BU_BITV_BITNUM_CHECK(_bv, _bit) (void)(_bv)
209#else
210# define BU_BITV_BITNUM_CHECK(_bv, _bit) /* Validate bit number */ \
211 if (UNLIKELY(((unsigned)(_bit)) >= (_bv)->nbits)) {\
212 bu_log("BU_BITV_BITNUM_CHECK bit number (%u) out of range (0..%u)\n", \
213 ((unsigned)(_bit)), (_bv)->nbits); \
214 bu_bomb("process self-terminating\n");\
215 }
216#endif
217
218#ifdef NO_BOMBING_MACROS
219# define BU_BITV_NBITS_CHECK(_bv, _nbits) (void)(_bv)
220#else
221# define BU_BITV_NBITS_CHECK(_bv, _nbits) /* Validate number of bits */ \
222 if (UNLIKELY(((unsigned)(_nbits)) > (_bv)->nbits)) {\
223 bu_log("BU_BITV_NBITS_CHECK number of bits (%u) out of range (> %u)", \
224 ((unsigned)(_nbits)), (_bv)->nbits); \
225 bu_bomb("process self-terminating"); \
226 }
227#endif
228
229
230/**
231 * DEPRECATED: Macros to efficiently find all the ONE bits in a bit
232 * vector. Counts words down, counts bits in words going up, for
233 * speed & portability. It does not matter if the shift causes the
234 * sign bit to smear to the right.
235 *
236 * Example:
237 * @code
238 *
239 * BU_BITV_LOOP_START(bv) {
240 * fiddle(BU_BITV_LOOP_INDEX);
241 * } BU_BITV_LOOP_END;
242 *
243 * @endcode
244 *
245 */
246#define BU_BITV_LOOP_START(_bv) \
247 { \
248 int _wd; /* Current word number */ \
249 BU_CK_BITV(_bv); \
250 for (_wd=BU_BITS2WORDS((_bv)->nbits)-1; _wd>=0; _wd--) { \
251 int _b; /* Current bit-in-word number */ \
252 bitv_t _val; /* Current word value */ \
253 if ((_val = (_bv)->bits[_wd])==0) continue; \
254 for (_b=0; _b < BU_BITV_MASK+1; _b++, _val >>= 1) { \
255 if (!(_val & 1)) continue;
256
257/**
258 * DEPRECATED: Paired with BU_BITV_LOOP_START()
259 */
260#define BU_BITV_LOOP_END } /* end for (_b) */ \
261 } /* end for (_wd) */ \
262 } /* end block */
263
264/**
265 * Count the number of set bits.
266 */
267BU_EXPORT extern size_t bu_bitv_count_set(const struct bu_bitv *bv);
268
269/**
270 * Iterate over all set bits in the bit vector efficiently.
271 *
272 * This function quickly skips over large blocks of zeroes using
273 * machine-word level operations, making it significantly faster than
274 * a bit-by-bit test loop when the bit vector is sparse. For each bit
275 * that is set to 1, the provided callback function is invoked with
276 * the index of the set bit and the user-provided data pointer.
277 *
278 * @param bv The bit vector to iterate over.
279 * @param callback The function to call for each set bit.
280 * @param data User-provided context passed directly to the callback.
281 */
282BU_EXPORT extern void bu_bitv_foreach(const struct bu_bitv *bv, void (*callback)(size_t bit, void *data), void *data);
283
284
285/**
286 * Allocate storage for a new bit vector of at least 'nbits' in
287 * length. The bit vector itself is guaranteed to be initialized to
288 * all zero.
289 *
290 * Because @c struct bu_bitv embeds one full machine word (@c bitv_t,
291 * currently 64 bits) inline, requests for fewer than 64 bits are
292 * silently rounded up to 64 and require no extra heap allocation
293 * beyond the struct itself. Requesting exactly 0 bits is valid and
294 * results in a usable 64-bit vector.
295 */
296BU_EXPORT extern struct bu_bitv *bu_bitv_new(size_t nbits);
297
298/**
299 * Release all internal storage for this bit vector.
300 *
301 * It is the caller's responsibility to not use the pointer 'bv' any
302 * longer. It is the caller's responsibility to dequeue from any
303 * linked list first.
304 */
305BU_EXPORT extern void bu_bitv_free(struct bu_bitv *bv);
306
307/**
308 * Set all the bits in the bit vector to zero.
309 *
310 * Also available as a BU_BITV_ZEROALL macro if you don't desire the
311 * pointer checking.
312 */
313BU_EXPORT extern void bu_bitv_clear(struct bu_bitv *bv);
314
315/**
316 * Performs an in-place bitwise OR operation on a bit vector.
317 *
318 * Result is stored in 'ov' (ov = ov | iv). If the vectors are of
319 * differing lengths, the operation will safely process up to the
320 * bounds of the overlapping arrays. Any excess bits in 'ov' that do
321 * not exist in 'iv' are preserved as-is.
322 *
323 * @param ov Destination and first operand bit vector.
324 * @param iv Source bit vector operand.
325 */
326BU_EXPORT extern void bu_bitv_or(struct bu_bitv *ov, const struct bu_bitv *iv);
327
328/**
329 * Performs an in-place bitwise AND operation on a bit vector.
330 *
331 * Result is stored in 'ov' (ov = ov & iv). If the vectors are of
332 * differing lengths, the operation will safely process up to the
333 * bounds of the overlapping arrays. For an AND operation, any excess
334 * bits in 'ov' that do not exist in 'iv' are cleared to 0.
335 *
336 * @param ov Destination and first operand bit vector.
337 * @param iv Source bit vector operand.
338 */
339BU_EXPORT extern void bu_bitv_and(struct bu_bitv *ov, const struct bu_bitv *iv);
340
341/**
342 * Performs an in-place bitwise NOT operation on a bit vector.
343 *
344 * Flips all bits in the vector (ov = ~ov). Safely preserves the
345 * unused trailing padding bits in the final machine word.
346 *
347 * @param ov The bit vector to invert.
348 */
349BU_EXPORT extern void bu_bitv_not(struct bu_bitv *ov);
350
351/**
352 * Performs an in-place bitwise XOR (exclusive OR) operation on a bit vector.
353 *
354 * Result is stored in 'ov' (ov = ov ^ iv). If the vectors are of
355 * differing lengths, the operation processes up to the bounds of the
356 * overlapping arrays. Excess bits in 'ov' remain unchanged.
357 *
358 * @param ov Destination and first operand bit vector.
359 * @param iv Source bit vector operand.
360 */
361BU_EXPORT extern void bu_bitv_xor(struct bu_bitv *ov, const struct bu_bitv *iv);
362
363/**
364 * Shifts entire bit vector left or right across word boundaries.
365 *
366 * A positive shift value shifts the bits left (towards higher
367 * indices), effectively moving bit N to N+shift. A negative shift
368 * value shifts the bits right (towards lower indices), moving bit N
369 * to N-|shift|. Bits shifted out of bounds are discarded. Vacated
370 * bits are zeroed.
371 *
372 * @param ov The bit vector to shift.
373 * @param shift The number of bits to shift.
374 */
376
377/**
378 * Print the bits set in a bit vector.
379 */
380BU_EXPORT extern void bu_bitv_vls(struct bu_vls *v, const struct bu_bitv *bv);
381
382/**
383 * Print the bits set in a bit vector. Use bu_vls stuff, to make only
384 * a single call to bu_log().
385 */
386BU_EXPORT extern void bu_pr_bitv(const char *str, const struct bu_bitv *bv);
387
388/**
389 * Convert a bit vector to an ascii string of hex digits. The string
390 * is from MSB to LSB (bytes and bits).
391 */
392BU_EXPORT extern void bu_bitv_to_hex(struct bu_vls *v, const struct bu_bitv *bv);
393
394/**
395 * Convert a string of HEX digits (as produced by bu_bitv_to_hex) into
396 * a bit vector.
397 */
398BU_EXPORT extern struct bu_bitv *bu_hex_to_bitv(const char *str);
399
400/**
401 * Convert a bit vector to an ascii string of binary digits in the GCC
402 * format ("0bn..."). The string is from MSB to LSB (bytes and bits).
403 */
404BU_EXPORT extern void bu_bitv_to_binary(struct bu_vls *v, const struct bu_bitv *bv);
405
406/**
407 * Convert a string of BINARY digits (as produced by
408 * bu_bitv_to_binary) into a bit vector.
409 */
410BU_EXPORT extern struct bu_bitv *bu_binary_to_bitv(const char *str);
411
412/**
413 * Convert a string of BINARY digits (as produced by
414 * bu_bitv_to_binary) into a bit vector. The "nbytes" argument may be
415 * zero if the user has no minimum length preference.
416 */
417BU_EXPORT extern struct bu_bitv *bu_binary_to_bitv2(const char *str, const int nbytes);
418
419/**
420 * Compare two bit vectors for equality. They are considered equal iff
421 * their lengths and each bit are equal. Returns 1 for true, zero for
422 * false.
423 */
424BU_EXPORT extern int bu_bitv_compare_equal(const struct bu_bitv *, const struct bu_bitv *);
425
426/**
427 * Compare two bit vectors for equality. They are considered equal iff
428 * their non-zero bits are equal (leading zero bits are ignored so
429 * lengths are not considered explicitly). Returns 1 for true, 0 for
430 * false.
431 */
432BU_EXPORT extern int bu_bitv_compare_equal2(const struct bu_bitv *, const struct bu_bitv *);
433
434/**
435 * Make a copy of a bit vector
436 */
437BU_EXPORT extern struct bu_bitv *bu_bitv_dup(const struct bu_bitv *bv);
438
439
440/**
441 * Convert a string of hex characters to an equivalent string of
442 * binary characters.
443 *
444 * The input hex string may have an optional prefix of '0x' or '0X' in
445 * which case the resulting binary string will be prefixed with '0b'.
446 *
447 * The input string is expected to represent an integral number of
448 * bytes but will have leading zeroes prepended as necessary to
449 * fulfill that requirement.
450 *
451 * Returns BRLCAD_OK for success, BRLCAD_ERROR for errors.
452 */
453BU_EXPORT extern int bu_hexstr_to_binstr(const char *hexstr, struct bu_vls *b);
454
455
456/**
457 * Convert a string of binary characters to an equivalent string of
458 * hex characters.
459 *
460 * The input binary string may have an optional prefix of '0b' or '0B'
461 * in which case the resulting hex string will be prefixed with '0x'.
462 *
463 * The input string is expected to represent an integral number of
464 * bytes but will have leading zeroes prepended as necessary to
465 * fulfill that requirement.
466 *
467 * Returns BRLCAD_OK for success, BRLCAD_ERROR for errors.
468 *
469 */
470BU_EXPORT extern int bu_binstr_to_hexstr(const char *binstr, struct bu_vls *h);
471
472
473/** @brief Bit field printing implementation. */
474
475
476/**
477 * Print a bit field according to a format specification via bu_log().
478 *
479 * Line printed is of the form "String Label: x1234 <FOO,BAR,RAB,OOF>"
480 * and is commonly used by debugging code to print which debug bits
481 * are enabled.
482 *
483 * @param label string label
484 * @param bits integer with the bits to print
485 * @param format format specification
486 *
487 * The 'format' begins with a desired printing base (8 or 16), i.e.,
488 * \\010 means print octal and \\020 for hex. Remaining string is the
489 * little endian bit position (i.e., 1 to 32 encoded in octal format)
490 * followed by a label for that bit (e.g., "\010\2Bit_one\1BIT_zero")
491 *
492 * Note octal counting is used for the bit position label:
493 * \01 -> ... \07 -> \10 -> \11 -> ... \17 -> \20 ... etc
494 */
495BU_EXPORT extern void bu_printb(const char *label,
496 unsigned long bits,
497 const char *format);
498
499/**
500 * Same as bu_printb() but with output going to a vls instead of stderr
501 */
502BU_EXPORT extern void bu_vls_printb(struct bu_vls *vls,
503 const char *label, unsigned long bits,
504 const char *format);
505
506/** @} */
507
509
510#endif /* BU_BITV_H */
511
512/*
513 * Local Variables:
514 * mode: C
515 * tab-width: 8
516 * indent-tabs-mode: t
517 * c-file-style: "stroustrup"
518 * End:
519 * ex: shiftwidth=4 tabstop=8
520 */
Definition dvec.h:74
Header file for the BRL-CAD common definitions.
struct bu_bitv * bu_hex_to_bitv(const char *str)
void bu_bitv_foreach(const struct bu_bitv *bv, void(*callback)(size_t bit, void *data), void *data)
struct bu_bitv * bu_bitv_new(size_t nbits)
void bu_bitv_not(struct bu_bitv *ov)
void bu_bitv_to_binary(struct bu_vls *v, const struct bu_bitv *bv)
struct bu_bitv * bu_binary_to_bitv2(const char *str, const int nbytes)
struct bu_bitv * bu_binary_to_bitv(const char *str)
void bu_bitv_free(struct bu_bitv *bv)
int bu_bitv_compare_equal2(const struct bu_bitv *, const struct bu_bitv *)
void bu_bitv_to_hex(struct bu_vls *v, const struct bu_bitv *bv)
void bu_bitv_and(struct bu_bitv *ov, const struct bu_bitv *iv)
void bu_bitv_vls(struct bu_vls *v, const struct bu_bitv *bv)
void bu_bitv_clear_bit(struct bu_bitv *bv, size_t bit)
void bu_bitv_xor(struct bu_bitv *ov, const struct bu_bitv *iv)
size_t bu_bitv_length(const struct bu_bitv *bv)
uint64_t bitv_t
Definition bitv.h:61
size_t bu_bitv_count_set(const struct bu_bitv *bv)
void bu_bitv_shift_vector(struct bu_bitv *ov, int shift)
void bu_bitv_clear(struct bu_bitv *bv)
int bu_bitv_test(const struct bu_bitv *bv, size_t bit)
int bu_binstr_to_hexstr(const char *binstr, struct bu_vls *h)
void bu_bitv_or(struct bu_bitv *ov, const struct bu_bitv *iv)
size_t bu_bitv_shift(void)
struct bu_bitv * bu_bitv_dup(const struct bu_bitv *bv)
int bu_bitv_compare_equal(const struct bu_bitv *, const struct bu_bitv *)
void bu_printb(const char *label, unsigned long bits, const char *format)
Bit field printing implementation.
int bu_hexstr_to_binstr(const char *hexstr, struct bu_vls *b)
void bu_bitv_set(struct bu_bitv *bv, size_t bit)
void bu_pr_bitv(const char *str, const struct bu_bitv *bv)
void bu_vls_printb(struct bu_vls *vls, const char *label, unsigned long bits, const char *format)
Global registry of recognized magic numbers.
Definition bitv.h:95
bitv_t bits[1]
Definition bitv.h:98
size_t nbits
Definition bitv.h:97
struct bu_list l
Definition bitv.h:96
Definition vls.h:53